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.
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.
Ansible Testing Environment
Throughout this article, as well as the next one, we will use the following test environment. All hosts are CentOS 7 boxes:
Controller machine (where Ansible is installed): 192.168.0.19 Node1: 192.168.0.29 Node2: 192.168.0.30
In addition, please note that both nodes have been added in the webservers section of the local /etc/ansible/hosts file:
That said, let’s get started with the topic at hand.
Introducing Ansible Playbooks
As described in the previous guide, you can use the ansible utility to run commands in remote nodes as follows:
# ansible -a "/bin/hostnamectl --static" webservers
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
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.
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”).
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.
An example from the official docs will help us to illustrate:
1. hosts: this is a list of machines (as per /etc/ansible/hosts) where the following tasks will be performed.
2. remote_user: remote account that will be used to perform the tasks.
3. vars: variables used to modify the behavior of the remote system(s).
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.
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).
In that case, start a new play by adding the hosts directive at the bottom and starting over:
--- - hosts: webservers remote_user: root vars: variable1: value1 variable2: value2 remote_user: root tasks: - name: description for task1 task1: parameter1=value_for_parameter1 parameter2=value_for_parameter2 - name: description for task1 task2: parameter1=value_for_parameter1 parameter2=value_for_parameter2 handlers: - name: description for handler 1 service: name=name_of_service state=service_status - hosts: dbservers remote_user: root vars: variable1: value1 variable2: value2 …
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.
# mkdir /etc/ansible/playbooks
And a file named apache.yml inside of there with the following contents:
--- - hosts: webservers vars: http_port: 80 max_clients: 200 remote_user: root tasks: - name: ensure apache is at the latest version yum: pkg=httpd state=latest - name: replace default index.html file copy: src=/static_files/index.html dest=/var/www/html/ mode=0644 notify: - restart apache - name: ensure apache is running (and enable it at boot) service: name=httpd state=started enabled=yes handlers: - name: restart apache service: name=httpd state=restarted
Second, create a directory /static_files:
# mkdir /static_files
where you will store the custom index.html file:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"/> </script> </head> <body> <h1>Apache was started in this host via Ansible</h1><br> <h2>Brought to you by Tecmint.com</h2> </body> </html>
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:
# ansible-playbook /etc/ansible/playbooks/apache.yml
Now let’s see what happens when we open a browser and point it to 192.168.0.29 and 192.168.0.30:
Let’s go one step further and manually stop and disable Apache on node1 and node2:
# systemctl stop httpd # systemctl disable httpd # systemctl is-active httpd # systemctl is-enabled httpd
Then run again,
# ansible-playbook /etc/ansible/playbooks/apache.yml
This time, the task reports that the Apache web server was started and enabled on each host:
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.
Summary
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.
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.
Hello TecMint Team,
Need your small help, I want to collect multi-data from at least 50 servers like their RAM, os-version, Disk space,kernel-version, and so on things, I have created one script there I am able to get data as required at the remote host, but I want that all 50 remote host data which available at there /tmp/report-1. I want to fetch and override all 50 server data into one file at a local ansible machine.
Thanks in advance for your help.
Best Regards,
Wajid Shaikh
Hi All
Can anyone tell me how to set hostname using ansible. Please find the given below requirement.
I have 100 servers and I want set hostname like web01 for first server and second server web02 and so on. Please help me out for the same.
I have also use ansible module hostname but it works only when I am set same hostname in 100 servers.
Hi, When I run multiple server automation on ansible, it generates reports individually for each servers. that is making me tough when testing multiple servers at a time and wanted to how many failed and how many passed. is there any way that i can get a single report (resulting all servers) in ansible automation?
when i am running the playbook i am getting below output , Can you please explain what does it mean?
[root@localhost ~]# vim ./Path/To/ansible/playbooks/apache.yml
[root@localhost ~]# ansible-playbook ./Path/To/ansible/playbooks/apache.yml
PLAY RECAP *********************************************************************
Can you add more details? “PLAY RECAP ****************” is not enough for us to help you troubleshoot this.
you need to change your hosts= in the hosts group you added in you anisble host.
example here in tecmint its -“hosts: webservers” replace webservers with entry you did in /etc/anisble/hosts
[group]
ip address
I get this error:
TASK [replace default index.html file] *****************************************
fatal: [192.168.0.104]: FAILED! => {“changed”: false, “checksum”: “105317b5614e0de4463045e059a76aab62210ffd”, “failed”: true, “msg”: “Destination /var/www/html not writable”}
NO MORE HOSTS LEFT *************************************************************
[WARNING]: Could not create retry file ‘/etc/ansible/playbooks/apache.retry’. [Errno 13] Permission denied:
‘/etc/ansible/playbooks/apache.retry’
please help
On executing the command – ansible-playbook /etc/ansible/playbooks/apache.yml
I get below error:
TASK [replace default index.html file] *****************************************
fatal: [192.168.0.104]: FAILED! => {“changed”: true, “failed”: true, “msg”: “Destination /var/www/html not writable”}
NO MORE HOSTS LEFT *************************************************************
[WARNING]: Could not create retry file ‘/etc/ansible/playbooks/apache.retry’. [Errno 13] Permission denied:
‘/etc/ansible/playbooks/apache.retry’
please suggest
Hi friends,
Try adding this below lines & it works.
—
– hosts: webservers
vars:
http_port: 80
max_clients: 200
remote_user: root
tasks:
– name: ensure apache is at the latest version
yum: name=httpd state=latest
– name: write the apache config file
template: src=/static_files/index.html dest=/var/www/html mode=0644
notify:
– restart apache
– name: ensure apache is running (and enable it at boot)
service: name=httpd state=started enabled=yes
handlers:
– name: restart apache
service: name=httpd state=restarted
Sorry. use this link to get the code with indentation- http://docs.ansible.com/ansible/playbooks_intro.html
I too received this error when configured.. so, it clearly an indentation problem. So, i copied the code from http://docs.ansible.com/ansible/playbooks_intro.html and it worked.
@Sadashiv,
As other users have pointed out, copying and pasting directly from this article into a terminal results in indentation errors.
@Ravi,
Please place a notice in this article saying so.
Hi everyone,
Regarding the “ERROR: Syntax Error while loading YAML” message, it is hard to assess based on the code formatting as viewed in the comment area. Please take a look here (https://github.com/ansible/ansible/issues/8243) and make sure you don’t have indentation errors or typos throughout the configuration files. If this does not resolve your issues, please upload the playbook files to an online storage service (such as Pastebin) and share the details of your system (distribution + version and Ansible version) so that I can reproduce.
Gabriel,
I have encounter an issue
ERROR! Syntax Error while loading YAML.
The error appears to have been in ‘/etc/ansible/playbooks/apache.yml’: line 2, column 8, but may
be elsewhere in the file depending on the exact syntax problem.
The offending line appears to be:
—
– hosts: web-servers
^ here
My playbook as follows
—
– hosts: web-servers
vars:
http_port: 80
max_clients: 200
remote_user: root
tasks:
– name: ensure apache is at the latest version
yum: pkg=httpd state=latest
– name: replace default index.html file
copy: src=/static_files/index.html dest=/var/www/html/ mode=0644
notify:
– restart apache
– name: ensure apache is running (and enable it at boot)
service: name=httpd state=started enabled=yes
handlers:
– name: restart apache
service: name=httpd state=restarted
I am getting error after loading the ansible-playbook
ERROR: Syntax Error while loading YAML script, /etc/ansible/playbooks/apache.yml
Note: The error may actually appear before this position: line 7, column 4
remote_user: root
tasks:
Can you post the entire apache.yml file?
I got the fix.
its all about proper indentation of the file.
Thanks for this useful article, actually I was working on it this night to make something like a monitor for Apache, MySQL, Exim, FTP, Load Average and Disk Usage, which will execute a command and send an email in case of failed, I gone through hard time to be honest but finally made it.
What are the difficulties you encountered while setting up and using Ansible? Feel free to share with the rest of the community – that way we will all benefit from each other’s experience.