Skip to content

La terminologie

On va commencer à rentrer un peu dans le détail des termes utilisés autour d’Ansible.

Parce qu’il y en a quelques uns, et que ne pas savoir à quoi les raccrocher c’est souvent voué à aller droit dans le mur.

Quand on parle d’Ansible, on parle entre autre des « facts ».

Les facts sont des variables contextuelles utilisables avec Ansible. Elles sont auto définies et peuvent être collectées lorsque Ansible se connecte à un équipement.

Il est possible de les récupérer manuellement. Pour faire celà, il va simplement falloir lancer la commande :

Terminal window
ansible -m setup -i '<ip_du_host>,' all

Vous allez obtenir une sortie d’Ansible contenant un gros JSON avec l’ensemble des facts qui ont pu être collectées.

Parmis celles-ci, on peut retrouver pour une machine Linux :

  • ansible_distribution : Le nom de la distribution utilisé
  • ansible_distribution_version : La version de la distribution utilisé
  • ansible_fqdn : Le nom complet de la machine sur laquelle Ansible s’est connecté
  • ansible_memtotal_mb : La taille de la RAM en Mo
  • ansible_os_family : La famille de système d’opération
  • ansible_processor_count : Le nombre de CPU

On retrouve également beaucoup d’autres informations qui pourront être utilisée dans vos tâches Ansible.

Les inventaires sont comme leurs noms l’indiquent le recueil de l’ensemble des machines qui seront gérées par Ansible.

On retrouvera également dans ces derniers les variables de configuration nécessaires aux différentes exécutions que vous pourrez lancer.

Les inventaires introduisent également une notion de groupes, ou d’ensembles. L’idée derrière cette notion est de définir des ensembles fonctionnels, comme par exemple des serveurs web, sur lesquels seront appliqués les tâches que vous lancerez Ansible.

Pour expliciter un peu le propos…

Considérons trois machines ayant pour vocation d’être des serveurs Web :

  • web1
  • web2
  • web3

L’ensemble des tâches Ansible que vous devez appliquer sont identiques sur ces trois machines. Vous allez alors créer un groupe « webserver » contenant ces trois machines. Celà aura pour bénéfice de faciliter la déclaration des variables et l’invocation des tâches, la déclaration ne sera faite qu’un fois au lieu de trois.

Si ça reste encore abstrait (c’est normal on est à l’explicitation des termes), pas de soucis, la documentation sur les inventaires devrait largement vous éclairer.

Les tâches sont les actions effectuées par Ansible sur les équipements de l’inventaire.

Ce sont elles qui vont définir quelles actions seront effectuées.

Prenons un example simple où on veut copier un fichier sur une cible de l’inventaire, la tâche en question aura ce format :

Copie sur cible
...
- name: "Copy file to remote host"
ansible.builtin.copy:
src: src/file.txt
dest: /tmp/file.txt
...

Pour détailler ce que fait cette tâche :

  • - name: "Copy file to remote host" : C’est simplement le nom de la tâche que l’on verra apparaitre dans la sortie d’Ansible
  • ansible.builtin.copy : C’est le nom du module que l’on utilise pour effectuer l’action.
  • src: src/file.txt : Le chemin relatif du fichier à copier sur le contrôleur Ansible
  • dest: /tmp/file.txt : Le chemin absolu où sera déposé le fichier sur la machine cible.

Les plugins regroupent deux choses :

  • Les lookup
  • Les modules

Ils peuvent être fourni par Ansible, des collections, ou écrit manuellement.

Les lookups sont des plugins un peu particuliers, parce qu’ils n’effectuent pas d’actions de modifications. Ils sont utilisé pour récupérer ou générer de l’information.

Ce sont des scripts écrit en Python qui vont permettre de récupérer ou générer une information donnée.

Celui que l’on rencontre le plus communément est le lookup permettant de générer un mot de passe.

Ils s’utilisent via la directive lookup d’Ansible.

Par exemple pour générer un mot de passe aléatoire de 64 caractères composé de :

  • Lettres
  • Chiffres
  • Tiret (caractère)
  • Underscore (caractère)
  • Point (caractère)

L’instruction serait la suivante :

Generation de mot de passe
lookup('ansible.builtin.password', '/dev/null length=64 chars=ascii_letters,digits,-,_,.')

Les modules sont les actions définit dans les tâches que va effectuer Ansible sur les équipements de l’inventaire.

Ce sont des scripts écrit en Python, avec un format prédéfini, qui assurent les actions sur les machines cibles, et l’idempotence de ces actions.

Fonctionnellement, pour pouvoir exécuter la tâche, Ansible va copier le module contextualisé (avec les bons paramètres) sur la machine cible. Une fois copié, il va exécuter, toujours sur la machine cible, le script via Python. Lorsque la tâche est terminée, et quel que soit l’état de la tâche, il va supprimer le script sur la machine cible.

En résumé les étapes sont :

  • Copie du script
  • Exécution du script
  • Suppression du script

Les collections Ansible sont une notion utilisée de façon très courante, mais de façon assez « masquée ».

Elles contiennent les plugins nécessaires aux tâches Ansible, et peuvent dans certains cas contenir des rôles.

La collection qui est incluse nativement dans Ansible s’appelle ansible.builtin. C’est dans cette collection que l’on retrouve la majeure partie des modules et lookups communs d’Ansible tel que copy, file, package, …

Elles permettent d’étendre le fonctionnement d’Ansible à des cas d’usages qui ne sont pas nativement inclus dans l’outil.

Parmi les collections existantes, celles que vous serez certainement amené à manipuler assez fréquemment :

  • ansible.posix : Collection spécifique pour les systèmes POSIX
  • community.general : Inclus un grand nombre de modules ne requérant pas de collection spécifiques
  • community.mysql : Permet l’interaction et la manipulation d’objets MySQL et MariaDB
  • community.postgresql : Permet l’interaction et la manipulation d’objets PostgreSQL

Par exemple pour la collection community.general si on se réfère à la page Ansible Galaxy, on dénombre :

  • 591 modules
  • 34 lookups

Ce que l’on qualifie de FQCN est le nom explicite des plugins.

Pour rester sur l’exemple du module copy, il est membre de la collection ansible.builtin. Son FQDN sera par définition : ansible.builtin.copy

L’une des recommendations d’Ansible est d’utiliser le FQCN des modules que l’on utilise.

Il peut y avoir des cas de plugins (modules ou lookups) ayant le même nom dans plusieurs collections différentes. Le but de cette recommandation est d’éviter le chevauchement des plugins lors de l’exécution et ainsi d’éviter de potentiels effets de bord.

Il convient donc de toujours utiliser le FQDN d’un plugin lors de sa déclaration.

Les playbooks sont le liant entre les inventaires et les tâches.

Ce sont eux qui vont définir sur quelles cibles nous allons appliquer des configurations et surtout quelles configurations seront appliquées.

Ils sont le « point d’entrée » pour comprendre ce qu’Ansible va exécuter.

Pour comprendre comment s’articule un playbook, prennont l’exemple suivant :

Playbook
- name: "Playbook name"
# On définit ici le(s) équipement(s) cible(s) ou le(s) groupe(s) d’équipements
hosts:
- all
# On définira ici les tâches à appliquer à l’ensemble des équipements concerné plus haut
tasks:
- name: "Copy file to remote host"
ansible.builtin.copy:
src: src/file.txt
dest: /tmp/file.txt

Les rôles sont des ensembles de tâches est de variables visant à une finalité fonctionnelle.

Le but des rôles est de pouvoir être réutilisés dans différents contextes, et ainsi de réduire le besoin d’écrire des tâches similaires dans différents playbooks.

Si on considère l’exemple classique du déploiement d’un serveur LEMP (Linux Nginx MariaDB PHP), la procédure d’installation sera toujours la même quel que soit le nombre de machines sur lesquelles il faudra faire l’installation.

De façon macroscopique, on peut identifier les tâches suivantes :

  • Installation et configuration de Nginx
  • Installation et configuration de MariaDB
  • Installation et configuration de PHP

Ce qui potentiellement pourrait changer d’une machine à l’autre serait :

  • L’adresse et les ports d’écoute de Nginx
  • Le FQDN du vhost Nginx
  • L’adresse et le port d’écoute de MariaDB
  • Les comptes MariaDB nécessaires
  • La configuration de PHP

Ainsi, on peut voir une structure d’un rôle qui se dessine avec :

  • Les tâches nécessaires à l’installation et la configuration des différentes briques
  • Des variables de configuration pour tout ce qui peut être modifiable entre les différents environnements.

Le but final étant de pouvoir consommer ce rôle dans un playbook et de le contextualiser à l’environnement au travers des variables d’inventaire

Ainsi, l’utilisation de ce rôle dans un playbook donnera la syntaxe suivante pour le playbook :

LEMP playbook
- name: "LEMP deployment"
hosts:
# On définit que le playbook ne s’exécute que sur les machines du groupe webservers
- webservers
# On utilise la clef « roles » pour dire à Ansible que l’on veut utiliser un rôle et non plus des tâches
roles:
# On indique que le rôle que l’on veut utilisé à pour nom « lemp »
- role: lemp