Inventaires
Les inventaires Ansible permettent non seulement de définir les machines qui seront managés par Ansible, mais aussi des groupes fonctionnels ou des variables contextuelles.
Les formats
Section titled “Les formats”Il est possible de configurer les inventaires via deux formats :
- INI
- YAML
Personnellement, je préfère les inventaires au format YAML. Je trouve ça bien plus lisible dans le cas où l’inventaire devient volumineux.
Je vous mets un example avec le même inventaire écrit en INI et en YAML :
[all]machine1machine2
[web]machine1
[mysql]machine2all: hosts: machine1: machine2: children: web: hosts: machine1: mysql: hosts: machine2:Inventaire de référence
Section titled “Inventaire de référence”Personnellement, je n’utilise que le format Ansible car je trouve ce dernier plus simple d’usage dans le cas d’inventaires qui commencent à être assez conséquents.
Les hôtes
Section titled “Les hôtes”La toute première notion à comprendre est la notion d’hôtes. Ce sont au sens propre les cibles qui seront managées par Ansible.
Pour donner un exemple de la méthode de déclaration des hôtes, on va créer un inventaire basique avec 4 hôtes :
- w1.example.org
- w2.example.org
- d1.example.org
- d2.example.org
Le fichier YAML se présentera ainsi comme ça :
---# Clef générique pour l’ensemble de l’inventaireall: # Clef permettant de définir l’ensemble des hôtes hosts: # Liste des hôtes par leurs FQDN w1.example.org: w2.example.org: d1.example.org: d2.example.org:Vous pouvez créer un fichier inventories/inventory.yaml avec le contenu semblable à celui ci-dessus pour tester.
De cette façon, il est possible d’utiliser Ansible soit unitairement sur un hôte ou pour l’ensemble des hôtes via
all.
Pour exécuter le module ping sur un hôte spécifique la commande sera la suivante :
ansible -m ping -i inventories/inventory.yaml w1.example.orgPour le même module pour l’ensemble des hôtes :
ansible -m ping -i inventories/inventory.yaml allIci pas de complexité donc. Le seul besoin tant que les machines soit enregistrée dans le DNS avec le nom que vous avez fourni dans l’inventaire.
Les groupes
Section titled “Les groupes”Il est possible dans un inventaire Ansible de structurer des groupes. Cette fonctionnalité est assez libre, car on peut structure des groupes d’hôtes ou des groupes de groupes.
Groupe d’hôtes
Section titled “Groupe d’hôtes”Pour créer des groupes d’hôtes, nous allons repartir de l’inventaire présent dans la Les hôtes avec les mêmes machines.
Imaginons que les machines w1 et w2 sont des machines vouées à être des serveurs web et les machines d1 et d2 sont vouées à être des bases de données.
On peut définir deux groupes webservers et databases tel que suivant :
all: hosts: w1.example.org: w2.example.org: d1.example.org: d2.example.org: # La clef children définit que ce qui sera positionné en dessous seront des groupes children: # On définit le groupe webservers webservers: # La liste des hôtes qui seront inclus dans ce groupe. hosts: w1.example.org: w2.example.org: # On définit le groupe databases databases: # La liste des hôtes qui seront inclus dans ce groupe. hosts: d1.example.org: d2.example.org:À cette étape, vous avez deux groupes indépendants dans votre inventaire.
Ces groupes sont utilisables pour l’exécution des modules. À l’instar des commandes précédentes, vous pouvez le vérifier avec la commande :
ansible -m ping -i inventories/inventory.yaml webserversDans ce cas précis, seul les équipements du groupe webservers doivent vous répondre.
Les variables
Section titled “Les variables”Il est possible d’inclure des variables dans les inventaires. Ces variables viendront définir certaines configurations qui seront appliquées dans vos tâches et/ou rôles, mais également des informations contextuelles pour vos différents équipements.
Si par exemple vous n’avez pas d’enregistrements DNS défini pour certains de vos équipements, il est tout à fait possible de spécifier l’adresse IP d’un ou plusieurs équipements afin qu’Ansible s’appuie dessus plutôt que sur le DNS pour contacter l’équipement en question.
Cette variable contextuelle est ce que l’on appelle un fact dans la terminologie Ansible. Ce sont des variables qui
sont automatiquement définie en fonction du contexte (de l’équipement ou de l’environnement).
Le fact permettant de spécifier l’adresse IP d’un équipement qui sera managé par Ansible est ansible_host.
Si on amende l’inventaire pour spécifier ce fact pour l’ensemble des équipements celà donne le fichier suivant :
all: hosts: w1.example.org: ansible_host: '10.0.0.10' w2.example.org: ansible_host: '10.0.0.11' d1.example.org: ansible_host: '10.0.1.10' d2.example.org: ansible_host: '10.0.1.10' children: webservers: hosts: w1.example.org: w2.example.org: databases: hosts: d1.example.org: d2.example.org:Le fait de spécifier le fact ansible_host dans un inventaire induit qu’Ansible ne tentera plus de résolution DNS pour
l’hôte en question et se basera sur la valeur spécifiée.
Que sont les group_vars et hosts_vars ?
Section titled “Que sont les group_vars et hosts_vars ?”Dans le cas où vous vous retrouvez à avoir des inventaires complexes avec beaucoup de variables et/ou de facts défini à l’intérieur, il devient préférable d’utiliser la méthode recommandée par Ansible pour gérer les variables.
Cette méthode consiste en l’utilisation de deux dossiers ayant des noms particuliers :
- group_vars : Dossier qui contiendra les variables pour les différents groupes de l’inventaire
- hosts_vars : Dossier qui contiendra les variables pour l’ensemble des hôtes de l’inventaire.
De mon point de vue ainsi que de par mon usage, le fichier de référence d’inventaire (inventories/inventory.yaml)
doit être laissé le plus pur possible.
J’entends par là qu’il ne doit contenir que les hôtes (et éventuellement leurs facts ansible_host si besoin) et les
groupes. Je trouve que lors de l’utilisation de gros inventaires d’infrastructure celà rends la maintenance et la gestion
plus facile d’avoir les variables rangées dans des fichiers en propre.
Prenons l’exemple suivant (c’est un example qui est volontairement abstrait, c’est pour que vous compreniez le
fonctionnement des group_vars et des hosts_vars) :
- Pour les machines qui seront des serveurs web, on veut spécifier que le dossier qui contiendra le site Web sera
dans le dossier
/srv/web/site - Pour les machines de base de données, on veut spécifier que le dossier qui contiendra les données sera dans
/opt/db - Pour la machine
d1.example.orgon veut que le moteur de base de donnée soit en version10.0.1 - Pour la machine
d2.example.orgon veut que le moteur de base de donnée soit en version11.0.0
Si on stocke toute ces informations dans l’inventaire, on va se retrouver avec l’inventaire suivant :
all: hosts: w1.example.org: ansible_host: '10.0.0.10' w2.example.org: ansible_host: '10.0.0.11' d1.example.org: ansible_host: '10.0.1.10' db_version: '10.0.1' d2.example.org: ansible_host: '10.0.1.10' db version: '11.0.0' children: webservers: hosts: w1.example.org: w2.example.org: vars: web_storage: '/srv/web/site' databases: hosts: d1.example.org: d2.example.org: vars: db_storage: '/opt/db'Je vous laisse imaginer ce que ça peut donner sur un inventaire qui contient plusieurs dixaines de machines avec des applicatifs divers et variés.
L’utilisation des group_vars et des hosts_vars permet de splitter celà facilement.
En terme d’arborescence, celà va donner celà :
Directoryinventories/
Directorygroup_vars/
Directorywebservers/
- storage.yaml
Directorydatabases/
- storage.yaml
Directoryhosts_vars/
Directoryd1.example.org/
- db_version.yaml
Directoryd2.example.org/
- db_version.yaml
Le contenu des fichiers serait le suivant :
---web_storage: '/srv/web/site'---db_storage: '/opt/db'---db_version: '10.0.1'---db_version: '11.0.0'L’utilisation de ces dossiers permet beaucoup plus de flexibilité que d’utiliser le fichier principal d’inventaire.
Vous pouvez créer autant de fichiers que vous le souhaitez dans chaque dossier, la seule structure imposée se situe
directement sous les dossiers group_vars ou hosts_vars car les dossiers ou fichiers qui sont contenus au premier
niveau doivent correspondre aux noms des hôtes ou des groupes de votre inventaire.
Le fait que j’utilise des dossiers pour les groupes et les hôtes me permet de splitter mes variables au besoin dans chaque dossier.
Typiquement, dans mon cas d’usage, je vais avoir de façon très régulière avoir pour chaque hôte :
- Un fichier
firewall.yamlqui va définir uniquement les règles de firewall pour la machine - Un fichier
ntp.yamlqui va définir uniquement les paramètres de configuration du client NTP - …
Une commande très pratique pour voir comment est constitué un inventaire afin d’identifier quelles variables touche quel hôte ou quel groupe et pour savoir quel hôte est membre de quel groupe :
ansible-inventory -i inventories/inventory.yaml --graph --vars