Ansible is a tool that allows to automate and especially to centralize administrative tasks.

Presentation

It is an open source tool that will operate as an admin server and from which it will be possible to manage several servers or server clusters in a centralized way.

Without agent, it uses the SSH protocol to remotely manage the Linux servers. It is a highly efficient and complete tool that allows advanced uses, we will only see its basics of using in this tutorial.

Ansible also has a graphic interface, nonetheless subject to payment. Its use is generally recommended for very big infrastructures in order to follow up the tasks execution, to have different graphics, etc.

In this tutorial, we are going to learn how to use Ansible to manage a Linux environment
Here is the demo architecture that we are going to use :


Installation

We are beginning by installing our Ansible server.
Of course, its position within a company network must be well thought-out.
It must be able to join all the servers that are about to be managed with the SSH protocol.
Its security and access must be watched carefully because, inherently, it will allow to launch actions on other servers.
It is therefore recommended to establish hardening processes of the server, but also audit and monitoring processes of the logs and connections.
Each access to this machine needs to be carefully traced.

For an installation on Debian 8, enter the following commands as root in a terminal :

apt-get install python-pip
pip install ansible

Ansible is now installed, you will find its configuration in the directory /etc/ansible.
Here is the files detail by default :

It is the file that allows to specify the clients machines, those that will be subjected to the Ansible commands and to a management through Ansible. As well, this file affords to specify groups of machines, in order to accelerate the management of several servers that have the same configuration (for instance a web server cluster in mirror).

It is the main configuration of Ansible, commands, modules, plugins and SSH configuration are there.


First step

Now, the Ansible server is ready, we have to make our first contact between the managed machines (both our Debian web servers) and the Ansible server. As mentioned above, exchanges are made by using the SSH protocol.

As such, two authentication methods can be used:
The standard method is the most used during a manual SSH connection, we enter the login with which we want to connect, then the password.

A key exchange needs to be established. The server willing to connect must have its public key autorized in the server that it wants to connect.

With Ansible, we would rather work with the key exchange, otherwise it would be necessary to enter a password for each command execution operated on a remote server. It would be difficult for several tens of servers.

For that, it is essential to create a key pair on the Ansible server, by using the command ssh-keygen.

Now, we are going to sen the server public key on all the servers that I would have to manage with Ansible :

ssh-copy-id root@192.168.1.10
ssh-copy-id root@192.168.1.20

After each of these two commands, the password of the root user of each web server is to be entered. After this, the SSH authentication will be automatically taken into account.
Now, we need to add two servers in list of the hosts considered by Ansible, in the file /etc/ansible/ansible_host. We are going to create a group of machine, called “web”.

# Ex 2: A collection of hosts belonging to the 'webservers' group
[web]
192.168.1.10
192.168.1.20

By this way, you can launch actions on the [web] group, and all the machines composing this group will be targeted.
You need to know that Ansible allows to use modules, that facilitate the features use of the Linux OS.

For example :
allows to execute bash commands through Ansible :

# Example
ansible web -m shell -a "ls -l /home/"

allows to test the command sending via Ansible by operating a ping, for example : ansible web -m ping

allows the packages management just like the “apt-get”command, for example : ansible web -m apt -a name=tree

Here is the list of the existing modules on the official site of Ansible : Ansible Modules
The argument -m allows to specify the module to use, the argument -a allows to specify the module arguments and right after the command name (ansible), the target or target group name must be specified.

Here are several tests that you can realize. Once the network authentication and the SSH authentication by key will be insured, let’s use the ping command on our web server group :

#Example
root@jn-community:~# ansible web -m ping
192.168.1.10 | success >> {
    "changed": false,
    "ping": "pong"
}

192.168.1.20 | success >> {
    "changed": false,
    "ping": "pong"
}

We see here that the command return indicates a block per server, with the server IP address matching each block. In this way, we are able to see, for each server, if the command is a success or not, and several additional information.

Now, let’s try to execute a standard command, such as ls, on each of our servers. For this, we will use the “shell” module as follows :

root@jn-community:~# ansible web -m shell -a "ls -l/home/"
192.168.1.10 | success | rc=0 >>
total 4
drwxr-xr-x 2 testuser testuser 4096 Jun   12  20:14 testuser

192.168.1.20 | success | rc=0 >>
total 4
drwxr-xr-x 2 testuser testuser 4096 Jun   12  20:14 testuser

Once again, we have, for each server composing our “web”server group, the Ansible operation return, and the command return, it means the content /home/ of each server. We start to understand the Ansible interest for the management of a large server farm.

Try to imagine that you have 20 servers to manage in this way, rather than connecting/deconnecting each time, it is enough to connect to Ansible, to target the right group of machine and each server will execute the command passed in argument


Installation of a web environment

To have a slightly more realistic context, we are going to imagine the following scenario :

In a web infrastructure, two new servers were just brought into production and they wait for their services installation. We are going to manage the servers installation directly from Ansible on both our servers. We will install Apache2, then PHP, and finally we will create a first file at the web root of each server.

This time we are going to use the “apt” module that allows to manage the packages for the Debian/Ubuntu OS as indicated in the Ansible documentation : Ansible apt module

Each module owns its lot of features and parameters. For example, we can begin by updating our package list from depots

ansible web -m apt -a update-cache=yes

Now, we are going to install the php5 and apache2 packages :

ansible web -m apt -a name="apache2,php5"

Now that our web environment is onstalled, we place a file index.html to their root. We will use the copy module that allows to remotely copy files (from the Ansible machine towards managed servers)

We are going to create a simple HTML file and copy it towards both our servers with a single command :

<html>
<body>
<h1> Serveur web </h1>
</body>
</html>

This file is located in the directory /opt/ on the Ensile server and wi wish to copy it in the directory /var/www/html/ of each server by using the copy module this way :

root@jn-community:~# ansible web -m copy -a "src=/opt/index.html dest=/var/www/html/"
192.168.1.10 | success >> {
    "changerd": true,
    "dest": "/var/www/html/page.html",
    "gid": 0,
    "groupe": "root",
    "md5sum": "a123b456c789d987e654f321",
    "mode": "0644",
    "owner": "root",
    "size": 52,
    "src": "/root/.ansible/tmp/ansible-tmp/3546541321.02-59684651321/source",
    "state": "file",
    "uid": 0
}

192.168.1.20 | success >> {
    "changerd": true,
    "dest": "/var/www/html/page.html",
    "gid": 0,
    "groupe": "root",
    "md5sum": "a123b456c789d987e654f321",
    "mode": "0644",
    "owner": "root",
    "size": 52,
    "src": "/root/.ansible/tmp/ansible-tmp/3546541321.02-59684651321/source",
    "state": "file",
    "uid": 0
}

Note that it is completely possible to manage other elements thanks to “copy” module, for example, directly allocate the user and the group “www-data” as the file owner :

ansible web -m copy -a "src=/opt/index.html dest=/var/www/html/ owner=www-data group=www-data"

Now you can join the file “index.html” on each of your servers. The operation here operated is relatively simple, we can imagine operating the same thing as simply for several tens of servers, or instead only one, while specifying its IP as follows :

ansible 192.168.1.10 -m copy -a "src=/opt/index.html dest=/var/www/html/"

If you want to restart the apache2 service, you can use the module service that allows to execute this kind of operation :

root@jn-community:~# ansible web -m service -a "name=apache2 state=restarted"
192.168.1.10 | success >> {
    "changed": true,
    "name": "apache2",
    "state": "started"
}

192.168.1.20 | success >> {
    "changed": true,
    "name": "apache2",
    "state": "started"
}

Now, you can imagine creating a pool of database server and configuring these servers in the same way etc.