Ansible est un outil qui permet d’automatiser et surtout de centraliser des tâches d’administration.

Présentation Ansible

Il s’agit d’un outil open-source qui agira comme un serveur d’administration et à partir duquel il sera possible de gérer plusieurs serveurs ou groupes de serveurs de façon centralisée.

Sans agent, il passe par le protocole SSH pour gérer les serveurs Linux à distance. Il s’agit d’un outil très efficace et complet qui permet des utilisations avancées, nous ne verrons que les bases de son utilisation dans ce tutoriel.

Ansible dispose également d’une interface graphique, elle est néanmoins payante. Son utilisation est généralement recommandée pour de très grosses infrastructures afin d’effectuer un suivi dans l’exécution des tâches, d’avoir différents graphiques, etc.

Dans ce tutoriel, nous allons apprendre à utiliser Ansible pour gérer un environnement Linux
Voici l’architecture de démo que nous allons utiliser :


Installation Ansible

Nous allons commencer par installer notre serveur Ansible.
Naturellement, sa position au sein d’un réseau d’entreprise doit être bien pensée.
Il doit être capable de joindre tous les serveurs qu’il va devoir gérer avec le protocole SSH.
Sa sécurité et son accès sont à surveiller de prêt car, par définition, il permettra de lancer des actions sur d’autres serveurs.
Il est donc recommandé de mettre en place des procédés d’hardening du serveur, mais également d’audit et de surveillance des logs et des connexions.
Chaque accès à cette machine doit être tracé avec attention.

Pour une installation sous Debian 8, saisir les commandes suivantes en tant que root dans un terminal :

apt-get install python-pip
pip install ansible

Ansible est donc installé, vous pourrez trouver sa configuration dans le répertoire /etc/ansible.
Voici le détail des fichiers présents par défaut :

Il s’agit du fichier qui permet de spécifier les machines clientes, celles qui pourront être assujetties aux commandes Ansible et à une gestion au travers d’Ansible. Également, ce fichier permet de spécifier des groupes de machines, afin d’accélérer la gestion de plusieurs serveurs disposant d’une même configuration (par exemple un cluster de serveurs web en miroir).

Il s’agit de la configuration principale d’Ansible, commandes, modules, plugins et configuration SSH s’y trouvent.


Premier pas sous Ansible

A présent, le serveur Ansible est prêt, nous devons établir notre premier contact entre les machines gérées (nos deux serveurs Debian web) et le serveur Ansible. Comme indiqué plus haut, les échanges seront effectués en utilisant le protocole SSH.

A ce titre, deux méthodes d’authentifications sont utilisables :
Méthode standard et la plus utilisée lors d’une connexion SSH manuelle, on saisie le login avec lequel on souhaite se connecter, puis le mot de passe.

Un échange de clé est à établir. Le serveur souhaitant se connecter doit avoir sa clé publique comme autorisée du côté du serveur sur lequel il souhaite se connecter.

Avec Ansible, nous préférons travailler avec l’échange de clé, il serait sinon nécessaire de saisir un mot de passe à chaque fois qu’une exécution de commande est effectuée sur un serveur distant. Cela est difficilement envisageable pour plusieurs dizaines de serveurs.

Pour cela, il est nécessaire de créer une paire de clé sur le serveur Ansible, en utilisant pour cela la commande ssh-keygen.

A présent, nous allons envoyer la clé publique du serveur sur tous les serveurs que j’aurai à gérer avec Ansible :

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

Après chacune de ces deux commandes, le mot de passe de l’utilisateur root du de chaque serveur web sera à saisir. Après cela, l’authentification SSH sera automatiquement prise en compte.
À présent, il faut ajouter les deux serveurs dans la liste des hôtes pris en comptes par Ansible, dans le fichier /etc/ansible/ansible_host. Nous allons créer un groupe de machine, dénommé « web ».

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

Ainsi, vous pourrez lancer des actions sur le groupe [web], et toutes les machines composant ce groupe seront ciblées.
Il faut savoir qu’Ansible permet d’utiliser des modules, qui facilitent l’utilisation des fonctionnalités des OS Linux.

Par exemple :
permet de passer des commandes bash au travers Ansible :

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

permet de tester l’envoi de commande via Ansible en effectuer un ping, par exemple : ansible web -m ping

permet la gestion des paquet comme la commande « apt-get », par exemple : ansible web -m apt -a name=tree

Voici la liste des modules existants sur le site officiel d’Ansible : Modules Ansible
L’argument -m permet de spécifier le module à utiliser, l’argument -a permet spécifier les arguments du module et juste après le nom de la commande (ansible), le nom de la cible ou du groupe cible doit être spécifié.

Voici quelques tests que vous pourrez réaliser. Une fois que la connectivité réseau et l’authentification SSH par clé sera assurée, utilisons la commande ping sur notre groupe de serveur web :

#Exemple
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"
}

Nous voyons ici que le retour de la commande indique un bloc par serveur, avec l’IP du serveur correspondant à chaque bloc. De cette façon, nous somme capable de voir, pour chaque serveur, si la commande est un succès ou non, et quelques informations supplémentaires.

À présent, essayons d’exécuter un commande standard, tel que ls, sur chacun de nos serveurs. Nous utiliserons pour cela le module « shell » comme suivant :

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

Une fois encore, nous avons, pour chaque serveur composant notre groupe de serveur « web », le retour de l’opération Ansible, et le retour de la commande, c’est à dire le contenu du /home/ de chaque serveur. On commence ici à voir l’intérêt d’Ansible pour la gestion d’un large parc de serveur.

Imaginez que vous ayez à gérer 20 serveurs de cette manière, plutôt que de se connecter/déconnecter à chaque fois, il suffit de se connecter à Ansible, de cibler le bon groupe de machine et chaque serveur exécutera la commande passée en argument


Installation d’un environnement web Ansible

Afin d’avoir un contexte un peu plus réaliste, nous allons imaginer le scénario suivant :

Dans une infrastructure web, deux nouveau serveurs viennent d’être mis en production et ils attendent l’installation de leurs services. Nous allons gérer l’installation des serveurs directement depuis Ansible sur nos deux serveurs. Nous installerons Apache2, puis PHP, et enfin nous créerons un premier fichier à la racine web de chaque serveur.

Nous allons utiliser cette fois ci le module « apt » qui permet de gérer les packages pour les OS Debian/Ubuntu comme l’indique la documentation Ansible : module Ansible apt

Chaque module possède son lot de fonctionnalités et de paramètres. Nous pouvons par exemple commencer par mettre à jour notre liste de paquet à partir des dépôts

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

A présent, nous allons installer les package php5 et apache2 :

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

Maintenant que notre environnement web est installé, nous allons placer un fichier index.html à la racine de ceux-ci. Nous utiliserons pour cela le module copy qui permet de copier des fichiers à distance (de la machine Ansible vers les serveurs gérés donc)

Nous allons créer un fichier HTML simple et le copier vers nos deux serveurs en une seule commande :

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

Ce fichier est positionné dans le répertoire /opt/ sur le serveur Ansible et nous souhaitons le copier dans le répertoire /var/www/html/ de chacun des deux serveurs, en utilisant le module copy de cette façon :

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
}

A noter qu’il est tout a fait possible de gérer d’autres éléments grâce au module « copy », par exemple, affecter directement l’utilisateur et le groupe « www-data » en tant que propriétaire du fichier :

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

Vous pourrez maintenant joindre le fichier « index.html » sur chacun de vos serveurs. L’opération ici effectuée est relativement simple, on peut imaginer effectuer la même chose aussi simplement pour plusieurs dizaines de serveur, ou au contraire sur un seul, en spécifiant son IP comme suivant :

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

Si vous souhaitez redémarrer le service apache2, vous pouvez utiliser le module service qui permet d’effectuer ce genre d’opération :

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"
}

A présent, vous pouvez imaginer de créer un pool de serveur database et de configurer ces serveurs de la même manière etc.