What is Ansible?

Long story short, Ansible is a tool which helps server administrators automate and execute tasks on multiple servers at the same time. Imagine having 20 Linux servers, each needing an installtion

of a web server. In the good old days, you would have to login to each server individually and perform the task, now though you can do it with a single command.

Why is Ansible preferred – other automation tools require you to install additional software on your remote servers, while Ansible does the job through SSH, which means no additional software on your target servers, less resources/low overhead, less things to troubleshoot then things go wrong.

Install Ansible

We will refer to the machine we install Ansible on as the command server. This could be your own laptop, stand alone server, or a small VPS. I personally run it on a small vps with 1GB ram and 50GB space from servercheap.net running CentOS 6

1 ) Let’s update our system with the latest packages

[root@ansible ~]# yum -y update

2) Enable EPEL repo

[root@ansible ~]# wget http://download.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
[root@ansible ~]# rpm -ivh epel-release-6-8.noarch.rpm

3) Install Ansible via YUM

[root@ansible ~]# yum install ansible

4) Verify Ansible is installed

[root@ansible ~]# ansible --version
 config file = /etc/ansible/ansible.cfg
 configured module search path = Default w/o overrides
 python version = 2.6.6 (r266:84292, Aug 18 2016, 15:13:37) [GCC 4.4.7 20120313 (Red Hat 4.4.7-17)]

Setup SSH Keys/Password-less login

This step is necessary so Ansible is able to login to our remote server without you having to enter your root password every time and for each server.

1) Generate a public key on our control server

[root@ansible ~]# ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
53:48:d1:09:35:c6:3f:09:4f:33:36:c8:44:1a:8c:12 root@ansible
The key's randomart image is:
+--[ RSA 2048]----+
| E. o=X*o |
| . ...=B.* |
| . o .* = |
| . = |
| S . |
| . |
| |
| |
| |

2) Copy the key we just generated from /root/.ssh/id_rsa.pub

[root@ansible ~]# cat /root/.ssh/id_rsa.pub
 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA0xRif65UF6W0vdmG7FPcQJLsZZBREam2lxOFZudZUHMgYR+R3CaLedHrO5+66Mo0C4kzFgrC1NySqBe9LMG1T8Mj/bxA81RwSLOSXf+nyz8oRHr1xb73pS7W0VlYqSFTK+RG9JZNad1Pc6PVb60jHWhtRxWwDF/2Cj4aVhpOmQnfiMZrTAvhy4VK6fU63JKKrOYzw71MYrkOclSYiAaeUd9+gBniAKYmJx7geC3Z+/JWs9EghQPE2yTKeY12jd/xHfNlrq+/V+V8TNd6aa5SMTZdGTlBnwArmZGCOd2Czv1PogDpS48W1mGIBei+LaD2YxIcqOz7zNUc/eCFEavs5w== root@ansible

3) Place the above public key in /root/.ssh/authorized_keys on all your Linux servers and save the file

nano /root/.ssh/authorized_keys 

ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA0xRif65UF6W0vdmG7FPcQJLsZZBREam2lxOFZudZUHMgYR+R3CaLedHrO5+66Mo0C4kzFgrC1NySqBe9LMG1T8Mj/bxA81RwSLOSXf+nyz8oRHr1xb73pS7W0VlYqSFTK+RG9JZNad1Pc6PVb60jHWhtRxWwDF/2Cj4aVhpOmQnfiMZrTAvhy4VK6fU63JKKrOYzw71MYrkOclSYiAaeUd9+gBniAKYmJx7geC3Z+/JWs9EghQPE2yTKeY12jd/xHfNlrq+/V+V8TNd6aa5SMTZdGTlBnwArmZGCOd2Czv1PogDpS48W1mGIBei+LaD2YxIcqOz7zNUc/eCFEavs5w== root@ansible

4) Let’s test it, if we have done everything properly, when we try to ssh to our linux server from our ansible control server, we should not be asked for password.

From our ansible control server we run:

[root@ansible ~]# ssh

The authenticity of host '[] ([])' can't be established.
RSA key fingerprint is 86:88:3f:9d:35:41:e4:a8:0e:6b:15:26:3d:77:01:4b.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '[]' (RSA) to the list of known hosts.
Last login: Thu Jul 13 17:58:07 2017 from .
[[email protected] ~]#

Configure Ansible Hosts

We need to tell Ansible the IPs of the servers we want to administer. This is done by adding your server ips in /etc/ansible/hosts

The default file looks like this:

[root@ansible ~]# cat /etc/ansible/hosts
# This is the default ansible 'hosts' file.
# It should live in /etc/ansible/hosts
# - Comments begin with the '#' character
# - Blank lines are ignored
# - Groups of hosts are delimited by [header] elements
# - You can enter hostnames or ip addresses
# - A hostname/ip can be a member of multiple groups

# Ex 1: Ungrouped hosts, specify before any group headers.

## green.example.com
## blue.example.com

# Ex 2: A collection of hosts belonging to the 'webservers' group

## [webservers]
## alpha.example.org
## beta.example.org

# If you have multiple hosts following a pattern you can specify
# them like this:

## www[001:006].example.com

# Ex 3: A collection of database servers in the 'dbservers' group

## [dbservers]
## db01.intranet.mydomain.net
## db02.intranet.mydomain.net

# Here's another example of host ranges, this time there are no
# leading 0s:

## db-[99:101]-node.example.com

Now let’s add our first host. At the bottom of the file we can do:

LinuxServer1:7777 ansible_ssh_host=

In the above example [test] is the name of the group which will contain our Linux servers. You can have as many groups as you wish.

LinuxServer1 is the friendly name of our first server.

:7777 tells Ansible that the SSH port of our server is 7777. If your server runs SSH on the standard port 22, you can leave that part out.

ansible_ssh_host= tells Ansible the IP of our server

So far so good. By now we have Ansible installed and our first server is configured.

Let’s run some sample commands:

[root@ansible ~]# ansible LinuxServer1 -m shell -a 'ps ax'

LinuxServer1 | SUCCESS | rc=0 >>
 1 ? Ss 0:49 init -z
 2 ? S 0:00 [kthreadd/342]
 3 ? S 0:00 [khelper/342]
 60 ? Ss 0:02 /usr/lib/systemd/systemd-journald
 67 ? Ss 0:00 /usr/lib/systemd/systemd-udevd
 106 ? Ss 0:15 /usr/lib/systemd/systemd-logind
 107 ? Ss 0:32 /bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation
 108 ? Ss 0:00 /usr/sbin/xinetd -stayalive -pidfile /var/run/xinetd.pid
 112 ? Ssl 0:00 /usr/sbin/rsyslogd -n
 138 ? Ss 0:00 /usr/sbin/saslauthd -m /run/saslauthd -a pam -n 2
 139 ? S 0:00 /usr/sbin/saslauthd -m /run/saslauthd -a pam -n 2
 153 ? Ss 0:00 /usr/sbin/sshd
 165 ? Ss 0:00 /bin/sh /usr/bin/mysqld_safe --basedir=/usr
 197 ? Ss 0:01 /usr/sbin/crond -n
 202 tty2 Ss+ 0:00 /sbin/agetty --noclear tty2 linux
 204 tty1 Ss+ 0:00 /sbin/agetty --noclear --keep-baud console 115200 38400 9600 vt220
 386 ? Sl 17:06 /usr/sbin/mysqld --basedir=/usr --datadir=/var/lib/mysql --plugin-dir=/usr/lib64/mysql/plugin --log-error=/var/log/mysqld.log --pid-file=/var/run/mysqld/mysqld.pid --socket=/var/lib/mysql/mysql.sock
 406 ? Ss 0:28 sendmail: accepting connections
 436 ? Ss 0:00 sendmail: Queue runner@01:00:00 for /var/spool/clientmqueue
 5723 ? Ss 0:01 /sbin/rpcbind -w
11951 ? Ss 0:25 /usr/sbin/httpd -DFOREGROUND
20486 ? S 0:02 /usr/sbin/httpd -DFOREGROUND
20487 ? S 0:04 /usr/sbin/httpd -DFOREGROUND
20488 ? S 0:03 /usr/sbin/httpd -DFOREGROUND
23767 ? Ss 0:00 sshd: root@pts/0
23797 pts/0 Ss+ 0:00 /bin/sh -c /usr/bin/python /root/.ansible/tmp/ansible-tmp-1499985693.17-135220611748439/command.py; rm -rf "/root/.ansible/tmp/ansible-tmp-1499985693.17-135220611748439/" > /dev/null 2>&1 && sleep 0
23808 pts/0 S+ 0:00 /usr/bin/python /root/.ansible/tmp/ansible-tmp-1499985693.17-135220611748439/command.py
23809 pts/0 S+ 0:00 /usr/bin/python /tmp/ansible_nWpKck/ansible_module_command.py
23810 pts/0 R+ 0:00 ps ax

Cool, we now see all the running processes on our remote server. Alternatively we can run:

[root@ansible ~]# ansible test -m shell -a 'ps ax'

Remember we created a group called test in our /etc/ansible/hosts file? The above command will then execute the command ‘ps ax’ on all servers under the group test. Since currently we only have one server, the output will be the same as above.

Ansible Playbooks

With the above example you can automate a lot of things, however Ansible is all about playbooks. What is a playbook? – it is just a text file in YAML format, where you list a bunch of commands for Ansible to execute. Let’s get right into some examples.

Scenario: Let’s image we are administering 20 linux servers. On each of them we have a custom shell script running. We have now made changes to our script and we would like to update it on all 20 servers. In the good old days you would have had to login to each server individually and update the file, let’s see how we can perform this task with the help of Ansible in just a few seconds.

Lets create a file called test.yaml in /etc/ansible (the location of the files do not matter and you are free to place them where ever you wish)

[root@localhost ansible]# cd /etc/ansible/
[root@localhost ansible]# nano test.yaml

And we insert the following yaml code:

- hosts: LinuxServer1
   - name: Copy scripts over
     synchronize: src=/etc/ansible/test.yaml dest=/root
   - name: Set execute persmission on ave
     file: path=/root/test.yaml owner=root group=wheel mode=0775 state=file

Lets break the above code down:

– hosts: LinuxServer1 – the destination server, alternatively you could put the group name, in our case ‘test’, which would then cause ansible to copy our file to all servers in the group.

– name: Copy scripts over – a general description of our task.

synchronize: src=/etc/ansible/test.yaml dest=/root – this line tells ansible to copy the file test.yaml which is located in /etc/ansible on our local control server and place it in /root on the destination server.

file: path=/root/test.yaml owner=root group=wheel mode=0775 state=file – this line tells ansible to change the permissions of the test.yaml once it is copied to the destination server.

And we execute it:

[root@ansible ~]# ansible-playbook test.yaml

If we now check our destination server, we will see test.yaml in /root with 755 permission

Pretty cool eh ? Now you have a basic knowledge and understanding of what Ansible is and how it works. But don’t just stop here. Ansible is a massively powerful tool which can allow you to automated almost anything you can think of.

Keep reading and studying the ansible playbooks here


Was this answer helpful? 2 Users Found This Useful (34 Votes)