Configuration management systems are designed to make controlling large numbers of servers accessible for administrators and operations teams. They allow you to control many different systems in an automated way from one central location. While there are many popular configuration management systems available for Linux systems, such as Chef and Puppet, these are often more complex than many people want or need. Ansible is a great alternative to these options because it has a much smaller overhead to get started.
Ansible works by configuring client machines from a computer with Ansible components installed and configured. It communicates over normal SSH channels to retrieve information from remote machines, issue commands, and copy files. Because of this, an Ansible system does not require any additional software to be installed on the client computers. This is one way that Ansible facilitates the administration of servers. Any server that has an SSH port exposed can be brought under Ansible’s configuration umbrella, regardless of what stage it is at in its life cycle.
Ansible takes on a modular approach, making it possible to use the functionalities of the main system to deal with specific scenarios. Modules can be written in any language and communicated in standard JSON. Configuration files are mainly written in the YAML data serialization format due to its expressive nature and its similarity to popular markup languages. Ansible can interact with clients through either command line tools or through its configuration scripts called Playbooks.
In this guide, you will install Ansible on a Rocky Linux 9 server and learn some basics of how to use the software.
To follow this tutorial, you will need:
One Ansible Control Node: The Ansible control node is the machine you’ll use to connect to and control the Ansible hosts over SSH. Your Ansible control node can either be your local machine or a server dedicated to running Ansible, though this guide assumes your control node is a Rocky Linux 9 system. Make sure the control node has:
sudo
privileges. To set this up, you can follow Steps 2 and 3 of our Initial Server Setup with Rocky Linux 9 guide. However, please note that if you’re using a remote server as your Ansible Control node, you should follow every step of this guide.One or more Ansible Hosts: An Ansible host is any machine that your Ansible control node is configured to automate. This guide assumes your Ansible hosts are remote Rocky Linux 9 servers. Make sure each Ansible host has:
authorized_keys
of a system user. This user can be either root or a regular user with sudo
privileges. To set this up, you can follow Step 2 of How to Set Up SSH Keys on Rocky Linux 9.Once you’re done setting everything up, you’re ready to begin the first step.
To begin exploring Ansible as a means of managing your various servers, you first need to install the Ansible software on at least one machine.
To get Ansible for Rocky Linux 9, first ensure that the Rocky Linux 9 EPEL repository is installed using dnf
:
- sudo dnf install epel-release
Once the repository is installed, install Ansible:
- sudo dnf install ansible
Now you have all of the software required to administer your servers through Ansible.
Ansible keeps track of all of the servers that it knows about through a hosts
file. You need to set up this file first before you can communicate with your other machines.
Open the file with root privileges as in the following. Keep in mind that the default text editor for Rocky Linux 9 is vi
:
- sudo vi /etc/ansible/hosts
You will notice this file has a lot of example configurations commented out. Keep these examples in the file to help you learn Ansible’s configuration if you want to implement more complex scenarios in the future.
The hosts file is fairly flexible and can be configured in a few different ways. The syntax you are going to use is structured like the following:
[group_name]
alias ansible_ssh_host=your_server_ip
The group_name
is an organizational tag that lets you refer to any servers listed under it with one word. The alias is a name to refer to that server.
For example, imagine you have three servers you want to control with Ansible. Ansible communicates with client computers through SSH, so each server you want to manage will be accessible from the Ansible server. If you followed the One or more Ansible Hosts option in the prerequisites, your hosts will have the SSH keys set up and accessible by running the following:
- ssh root@your_server_ip
You will not be prompted for a password. While Ansible certainly has the ability to handle password-based SSH authentication, SSH keys help keep things more streamlined.
With your file already open, you will use the following servers’ IP addresses as an example: 203.0.113.111
, 203.0.113.112
, and 203.0.113.113
. Make sure to replace the IP addresses with your own. Next, set this up so that you can refer to each server individually as host1
, host2
, and host3
, or as a group as servers
. To configure this, you need to add the following block to your hosts file. You can do so by pressing i
to insert the text, and once you’re done press ESC
:
[servers]
host1 ansible_ssh_host=203.0.113.111
host2 ansible_ssh_host=203.0.113.112
host3 ansible_ssh_host=203.0.113.113
Once you’re done adding the block, save and exit the file. You can do this by writing :wq
and then ENTER
.
Hosts can be in multiple groups and groups can configure parameters for all of their members. You can try this by running the following command:
- ansible -m ping host1
Ansible connection errorhost1 | UNREACHABLE! => {
"changed": false,
"msg": "Failed to connect to the host via ssh: sammy@203.0.113.111: Permission denied (publickey).",
"unreachable": true
}
Ansible will, by default, try to connect to remote hosts using your current username. This error shows that if the user doesn’t exist on the remote system, the connection will fail.
Therefore, let’s specifically tell Ansible to connect to servers in the servers
group with the sammy user. Begin by creating a directory in the Ansible configuration structure called group_vars
:
- sudo mkdir /etc/ansible/group_vars
Within this folder, you can create YAML-formatted files for each group you want to configure. Previously, you edited the file using the vi
text editor. Alternatively, you can edit the file using nano
, but need to install it with the following command:
- sudo dnf -y install nano
If you prefer to use nano
, after you install it you will open the /etc/ansible/group_vars/servers
file to edit the configuration:
- sudo nano /etc/ansible/group_vars/servers
Add the following code to the file. YAML files start with ---
, so don’t forget that part:
---
ansible_ssh_user: sammy
Once you’re finished, save and exit the file. In nano
, you can do this by pressing CTRL + X
and then Y
and ENTER
.
Now Ansible will always use the sammy
user for the servers
group, regardless of the current user.
If you want to specify configuration details for every server, regardless of group association, you can put those details in a file at /etc/ansible/group_vars/all
. Individual hosts can be configured by creating files under a directory at /etc/ansible/host_vars
.
Now that you have your hosts set up and enough configuration details to allow you to successfully connect to your hosts, you can try out several commands.
First, ping all of the servers you configured. The -m ping
portion of the command is an instruction to Ansible to use the ping
module. These are general commands that you can run on your remote hosts. The ping
module operates in many ways like the normal ping
utility in Linux, but instead, it checks for Ansible connectivity:
- ansible -m ping all
Ansible will return output like the following:
Outputhost3 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": false,
"ping": "pong"
}
host1 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": false,
"ping": "pong"
}
host2 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": false,
"ping": "pong"
}
This output is a basic test to confirm that Ansible has a connection to all of its hosts.
Other than the all
command, there are other commands to target different sets of servers. You can also specify a group:
- ansible -m ping servers
You can also specify an individual host:
- ansible -m ping host1
Additionally, you can specify multiple hosts by separating them with colons:
- ansible -m ping host1:host2
The shell
module allows you to send a terminal command to the remote host and retrieve the results. For instance, to find out the memory usage on your host1
machine, you could use the following:
- ansible -m shell -a 'free -m' host1
As you may notice, you pass arguments into a script by using the -a
switch. Here’s what the output might return:
Outputhost1 | CHANGED | rc=0 >>
total used free shared buff/cache available
Mem: 7951 234 6768 0 948 7461
Swap: 0 0 0
You’ve now successfully run several of the basic Ansible commands among your various hosts.
Your Ansible server is now configured to communicate with the servers that you would like to control. You can verify that Ansible can communicate with each host by using the ansible
command to execute basic tasks remotely.
You have configured a great foundation for working with your servers through Ansible, so your next step is to learn how to use Playbooks to do the heavy lifting for you. You can learn more in our guide on Configuration Management 101: Writing Ansible Playbooks.
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!