[‘
In the previous article of this Ansible series, we explained that Ansible is an agent-less tool that allows you to quickly and efficiently manage multiple machines (also known as nodes – and perform deployments to them as well) from a single system.
n

n
After installing the software in the controller machine, creating the keys for passwordless login and copying them to the nodes, it’s time to learn how to optimize the process of managing such remote systems using Ansible.
n
Ansible Testing Environmentn
Throughout this article, as well as the next one, we will use the following test environment. All hosts are CentOS 7 boxes:
n
Controller machine (where Ansible is installed): 192.168.0.19rnNode1: 192.168.0.29rnNode2: 192.168.0.30rn
n
In addition, please note that both nodes have been added in the webservers section of the local /etc/ansible/hosts file:
n

n
That said, let’s get started with the topic at hand.
n
Introducing Ansible Playbooks
n
As described in the previous guide, you can use the ansible utility to run commands in remote nodes as follows:
n
# ansible -a "/bin/hostnamectl --static" webserversrn
n

n
In the example above, we ran hostnamectl --static
on node1 and node2. It doesn’t take long for one to realize that this method of running tasks on remote computers works fine for short commands but can quickly become burdensome or messy for more complex tasks that require further well-structured configuration parameters or interactions with other services
n
For example, setting up and configuring WordPress on multiple hosts – which we will cover in the next article of this series). This is where Playbooks come into scene.
n
Simply put, Playbooks are plain text files written in the YAML format, and contain a list with items with one or more key/value pairs (also known as a “hash” or a “dictionary”).
n
Inside each Playbook you will find one or more group of hosts (each one of these groups is also called a play) where the desired tasks are to be performed.
n
An example from the official docs will help us to illustrate:
n
1. hosts: this is a list of machines (as per /etc/ansible/hosts) where the following tasks will be performed.
n
2. remote_user: remote account that will be used to perform the tasks.
n
3. vars: variables used to modify the behavior of the remote system(s).
n
4. tasks are executed in order, one at a time, against all machines that match hosts. Within a play, all hosts are going to get the same task directives.
n
If you need to execute a different set of associated tasks for a specific host, create another play in the current Playbook (in other words, the purpose of a play is to map a specific selection of hosts to well-defined tasks).
n
In that case, start a new play by adding the hosts directive at the bottom and starting over:
n
---rn- hosts: webserversrn remote_user: rootrn vars:rn variable1: value1rn variable2: value2rn remote_user: rootrn tasks:rn - name: description for task1rn task1: parameter1=value_for_parameter1 parameter2=value_for_parameter2rn - name: description for task1rn task2: parameter1=value_for_parameter1 parameter2=value_for_parameter2rn handlers:rn - name: description for handler 1rn service: name=name_of_service state=service_statusrn- hosts: dbserversrn remote_user: rootrn vars:rn variable1: value1rn variable2: value2rn…rn
n
5. handlers are actions that are triggered at the end of the tasks section in each play, and are mostly used to restart services or trigger reboots in the remote systems.
n
# mkdir /etc/ansible/playbooksrn
n
And a file named apache.yml inside of there with the following contents:
n
---rn- hosts: webserversrn vars:rn http_port: 80rn max_clients: 200rn remote_user: rootrn tasks:rn - name: ensure apache is at the latest versionrn yum: pkg=httpd state=latestrn - name: replace default index.html filern copy: src=/static_files/index.html dest=/var/www/html/ mode=0644rn notify:rn - restart apachern - name: ensure apache is running (and enable it at boot)rn service: name=httpd state=started enabled=yesrn handlers:rn - name: restart apachern service: name=httpd state=restartedrn
n
Second, create a directory /static_files:
n
# mkdir /static_filesrn
n
where you will store the custom index.html file:
n
<!DOCTYPE html>rn <html lang="en">rn <head>rn <meta charset="utf-8"/>rn </script>rn </head>rn <body>rn <h1>Apache was started in this host via Ansible</h1><br>rn<h2>Brought to you by Tecmint.com</h2>rn </body>rn </html>rn
n
That said, now it’s time to use this playbook to perform the tasks mentioned earlier. You will note that Ansible will go through each task by host, one at a time, and will report on the status of such tasks:
n
# ansible-playbook /etc/ansible/playbooks/apache.ymlrn
n

n
Now let’s see what happens when we open a browser and point it to 192.168.0.29 and 192.168.0.30:
n

n
Let’s go one step further and manually stop and disable Apache on node1 and node2:
n
# systemctl stop httpdrn# systemctl disable httpdrn# systemctl is-active httpdrn# systemctl is-enabled httpdrn
n

n
Then run again,
n
# ansible-playbook /etc/ansible/playbooks/apache.ymlrn
n
This time, the task reports that the Apache web server was started and enabled on each host:
n

n
Please consider the above example as a glimpse of the power of Ansible. While these are relatively easy tasks when performed on a small number of servers, it can become very tedious and time-consuming if you need to do the same in several (perhaps hundreds) of machines.
n
Summary
n
In this article we have described how to run commands and execute complex tasks on several remote hosts simultaneously using Ansible. The official documentation and the GitHub repository provide a lot of examples and guides on how to use Ansible to achieve almost any imaginable task.
n
As you start learning how to automate tasks on remote Linux hosts using Ansible, we would like to hear your thoughts. Questions, comments, and suggestions are also always welcome, so feel free to contact us using the form below any time.
n
‘]