Ansible est un outil d'automatisation pour la maintenance de systèmes et le
déploiement d'applications.
Ansible permet de définir une liste de machines en les associant à des groupes. L'ensemble de ces groupes est appelé un inventaire
(inventory). Il est ensuite possible de réaliser des tâches sur un ou plusieurs groupes (et donc une ou plusieurs
machines) en faisant appel à des modules. Pour chaque module, Ansible établit une connexion SSH machine par machine
et vérifie si des commandes doivent être exécutées selon l'état de la machine et, le cas échéant, les exécute.
Il est possible de regrouper un ensemble de tâches dans un playbook qui va définir l'état d'un groupe
de machines. Lorsqu'on exécute un playbook, Ansible ne va effectuer que les actions nécessaires pour rendre la machine
conforme au playbook.
Installation
Ansible est écrit en Python et est disponible dans les dépôt Linux. Pour un système type Debian, vous pouvez utiliser apt :
sudo apt install ansible
Si vous avez l'habitude d'utiliser l'écosystème Python alors vous pouvez utiliser un environnement virtualisé Python 3 et
ensuite installer Ansible à partir du gestionnaire python pip :
Pour plus d'informations sur l'installation, vous pouvez vous reporter à la documentation.
Création d'un inventaire
Un inventaire (inventory) est un catalogue
des noms ou adresses de machines (aussi appelées nœuds ou hosts) décrivant une infrastructure.
Par défaut, l'inventaire se trouve dans le fichier /etc/ansible/hosts. Il est également possible de préciser
à Ansible d'utiliser un inventaire particulier, ce qui évite de modifier le fichier système, notamment pour les phases de test.
Le fichier d'inventaire suit le format de fichier INI :
Il est possible de définir un groupe comme étant un ensemble d'autres groupes grâce à la syntaxe [NOM_GROUPE:children].
Ce groupe ne contient alors que des noms d'autres groupes de l'inventaire.
Si les machines sont numérotées, vous pouvez utiliser une syntaxe abrégée de la forme racine<01>:<09>
pour eviter de lister une machine par ligne.
Il existe un groupe implicite : all. Ce groupe désigne l'ensemble des machines décrites dans l'inventaire.
Les machines présentes dans l'inventaire doivent être administrables par Ansible. Pour cela, il faut que chaque machine
soit accessible via SSH et qu'une version de Python >=2.7 y soit installée. De plus, pour administrer correctement
la machine, il est probablement nécessaire que le compte utilisateur pour la connexion SSH puisse obtenir des privilèges
d'exécution (par exemple avec la commande sudo).
Exécution de Ansible
Vous pouvez exécuter ansible avec les paramètres suivants :
-i <fichier inventaire>
spécifie le fichier d'inventaire à utiliser.
-C, --check
ne fait aucun changement. Ansible va se contenter de deviner les modifications qui devraient être realisées sur les machines.
-m <nom du module>
spécifie le module que l'on souhaite invoquer.
-a <arguments>
spécifie les arguments à passer au module au moment de l'exécution.
-k
demande le mot de passe pour la connexion SSH
-u <utilisateur>
spécifie le login utilisateur pour la connexion SSH
-b, --become
exécute les commandes distantes en tant que superutilisateur
-K
demande le mot de passe pour les opérations demandant des privilèges (principalement lors de l'exécution d'une commande sudo sur la machine distante)
Vous pouvez par exemple tester votre inventaire en utilisant le module ping pour vous assurer que vous pouvez
joindre toutes les machines de votre inventaire :
Disposer d'un conteneur LXC de référence administrable avec Ansible
Reprenez votre script de création de machine écrit lors du chapitre sur LXC et
ajoutez les instructions nécessaires pour avoir une machine administrable avec Ansible.
Exercice : première utilisation d'Ansible
Objectif
comprendre le fonctionnement d'Ansible
Créez deux conteneurs à partir de celui créé à l'exercice précédent. Créez un inventaire Ansible
en mettant chaque machine dans un groupe différent (par exemple groupe1 et groupe2).
Essayez ensuite d'utiliser le module raw qui permet d'exécuter n'importe quelle commande sur les machines distantes :
Utilisez le module raw pour exécuter des commandes nécessitant des privilèges comme apt update.
Écriture de playbooks
Un playbook est à la fois un format de fichier et une arborescence de fichiers
permettant de définir l'état d'une infrastructure de machines. Avec les playbooks, nous avons à notre disposition un outil qui nous permet de gérer
notre infrastructure comme du code : c'est-à-dire que la gestion des machines se fait à partir de fichiers semblables à du code source applicatif. Il devient
donc possible d'utiliser des gestionnaires de source comme Git pour conserver, partager et versionner notre infrastructure mais également d'imaginer
des procédures automatisées de test et de déploiement non seulement des applicatifs mais également des machines.
Dans son sens le plus strict, un playbook est un fichier au format YAML.
Un fichier playbook peut possèder les sections suivantes :
hosts
Le nom de groupe de l'inventaire pour lequel s'applique le playbook
vars
Une liste de variables qui peuvent être utilisées dans le corps du playbook en utilisant la notation Jinja2 {{ nom_variable }}
remote_user
Le login de l'utilisateur distant utilisé pour réaliser les tâches
tasks
La liste des tâches à réaliser si nécessaire
handlers
La liste des actions qui pourront être exécutées lors d'une notification
Dans les sections tasks et handlers, on trouve la déclaration des modules avec leurs arguments.
Pour chacun, on utilisera soit la notation :
- name: <description de la tâche>
<module>: <arg1>=<valeur1> <arg2>=<valeur2>...
... soit la notation plus longue :
- name: <description de la tâche>
<module>:
<arg1>: <valeur1>
<arg2>: <valeur2>
...
Les handlers permettent de définir des modules qui ne seront appelés que si certaines tâches sont exécutées.
On ajoute l'attibut notify à une tâche pour indiquer que si la tâche est exécutée alors le handler doit aussi l'être
L'exemple ci-dessus vérifie que le serveur Web Apache est installé et que le module ssl est activé pour ce serveur.
Si ce n'est pas le cas, alors ansible installera la module puis notifiera le handler "reload apache2 service".
Ce dernier effectuera une reload de la configuration du serveur. Les handlers sont donc une façon
simple de définir des tâches conditionnelles.
Exécution d'un playbook
Vous pouvez exécuter ansible-playbook avec les paramètres suivants :
-i <fichier inventaire>
spécifie le fichier d'inventaire à utiliser.
-C, --check
ne fait aucun changement. Ansible va se contenter de deviner les modifications qui devraient être realisées sur les machines.
-k
demande le mot de passe pour la connexion SSH
-u <utilisateur>
spécifie le login utilisateur pour la connexion SSH
-b, --become
exécute les commandes distantes en tant que superutilisateur
-K
demande le mot de passe pour les opérations demandant des privilèges (principalement lors de l'exécution d'une commande sudo sur la machine distante)
Exercice : premier playbook
Objectif
utiliser ansible-playbook
Exécuter le playbook suivant sur un conteneur LXC :
---- hosts: web
handlers: - name : reload apache2 service
service: name=apache2 state=reloaded enabled=yes tasks: - name: checks apache2 is present
package: name=apache2 state=present
- name: checks apache2 modules enabled
apache2_module: name=ssl state=present
notify: - reload apache2 service
Vérifier que le serveur HTTP est bien disponible.
Relancez le même playbook pour voir ce qu'il se passe...
Exercice : hébergement du cours
Objectif
Utiliser ansible-playbook pour monter un serveur Web qui héberge ce cours.
Une archive du site est téléchargeable à cette adresse.
Mais ce site est également un dépôt GitHub sur la branche gh-pages.