Chapitre 317 minIntermédiaire
L'inventaire Ansible : hôtes, groupes et variables
Par Josselyn C., prof de BTS SIO. Mis à jour le .
À la fin de ce chapitre, tu sauras
- décrire un parc dans un inventaire INI ou YAML ;
- organiser les hôtes en groupes et en groupes enfants ;
- ranger les variables dans
group_varsethost_vars; - cibler des hôtes avec un motif ;
- vérifier un inventaire avec
ansible-inventory.
3 exercices corrigés
L'inventaire Ansible est le fichier qui liste les machines à gérer, les range en groupes et leur associe des variables : adresse, compte de connexion, protocole, réglages propres à chaque serveur. Ce chapitre écrit l'inventaire de Sorbier en INI puis en YAML, range les variables dans group_vars et host_vars, explique les motifs qui ciblent un sous-ensemble du parc, et présente l'inventaire dynamique.
Hôtes et groupes
Un hôte est une machine gérée, désignée par un nom. Ce nom n'a pas besoin d'être résolu par le DNS : la variable ansible_host donne l'adresse à joindre. Un groupe rassemble des hôtes qu'on traite de la même façon. Un hôte peut appartenir à plusieurs groupes, et un groupe peut contenir d'autres groupes, appelés groupes enfants.
Deux groupes existent toujours, sans qu'on les déclare :
allcontient tous les hôtes de l'inventaire ;ungroupedcontient les hôtes qui ne sont dans aucun autre groupe queall.
On peut grouper selon plusieurs axes, et les combiner : la fonction (serveurs web, contrôleurs de domaine), le système (Linux, Windows), le lieu (siège de Lyon, agence de Marseille), l'environnement (production, recette). Chez Sorbier, le premier découpage suit le système, parce que la façon de se connecter en dépend ; le second suit la fonction.
Le format INI
Le format INI est le plus ancien et le plus court. Chaque groupe est un titre entre crochets ; les variables d'un hôte suivent son nom sur la même ligne.
# Inventaire de Sorbier au format INI
[supervision]
srv-journaux ansible_host=192.168.10.180
[serveurs_web]
srv-web ansible_host=192.168.10.225
[controleurs]
srv-ad ansible_host=192.168.10.177
srv-ad2 ansible_host=192.168.10.181
[fichiers]
srv-fichiers ansible_host=192.168.10.178
[switchs]
sw-etage1 ansible_host=192.168.10.211
sw-etage2 ansible_host=192.168.10.212
[linux:children]
supervision
serveurs_web
[windows:children]
controleurs
fichiers
[linux:vars]
ansible_user=ansible
[linux:children]déclare quesupervisionetserveurs_websont des groupes enfants delinux: leurs hôtes sont aussi danslinux.[linux:vars]donne une variable à tous les hôtes du groupelinux.- Une plage s'écrit entre crochets :
sw-etage[1:2]déclaresw-etage1etsw-etage2,srv-web[01:10]dix hôtes desrv-web01àsrv-web10.
Le format YAML
Le format YAML est plus long, mais il suit la même structure que le reste du projet et accepte des variables de tout type (listes, dictionnaires). C'est celui que Sorbier utilise, dans inventaire/hosts.yml :
---
all:
children:
linux:
children:
supervision:
hosts:
srv-journaux:
ansible_host: 192.168.10.180
serveurs_web:
hosts:
srv-web:
ansible_host: 192.168.10.225
windows:
children:
controleurs:
hosts:
srv-ad:
ansible_host: 192.168.10.177
srv-ad2:
ansible_host: 192.168.10.181
fichiers:
hosts:
srv-fichiers:
ansible_host: 192.168.10.178
switchs:
hosts:
sw-etage1:
ansible_host: 192.168.10.211
sw-etage2:
ansible_host: 192.168.10.212
Les trois mots-clés à retenir : hosts liste les hôtes d'un groupe, children ses groupes enfants, vars ses variables. L'indentation se fait avec des espaces, jamais des tabulations, et chaque niveau doit être aligné exactement.
| INI | YAML | |
|---|---|---|
| Lisibilité d'un petit inventaire | Très bonne | Bonne |
| Variables de type liste ou dictionnaire | Mal adapté | Naturel |
| Cohérence avec les playbooks | Autre syntaxe | Même syntaxe |
| Piège classique | Les valeurs sont des chaînes : true n'est pas toujours un booléen | L'indentation |
Les variables de connexion
Certaines variables, dont le nom commence par ansible_, règlent la façon dont Ansible se connecte à l'hôte. Ce sont les plus importantes d'un inventaire.
| Variable | Rôle | Valeur chez Sorbier |
|---|---|---|
ansible_host | Adresse ou nom DNS à joindre | 192.168.10.225 |
ansible_port | Port de connexion | 22 (SSH), 5986 (WinRM HTTPS) |
ansible_user | Compte de connexion | ansible, svc-ansible@AD.SORBIER.EXAMPLE |
ansible_connection | Plugin de connexion | ssh (par défaut), winrm, ansible.netcommon.network_cli, local |
ansible_become | Élever les privilèges pour toutes les tâches | true |
ansible_become_method | Méthode d'élévation | sudo (Linux), runas (Windows), enable (Cisco) |
ansible_python_interpreter | Python à utiliser sur l'hôte | Découvert automatiquement ; à forcer si besoin |
ansible_shell_type | Shell distant pour Windows en SSH | powershell |
ansible_network_os | Système d'un équipement réseau | cisco.ios.ios |
ansible_password | Mot de passe de connexion | Jamais en clair : une référence à Ansible Vault (chapitre 9) |
group_vars et host_vars
Mettre toutes les variables dans hosts.yml le rend vite illisible. Ansible lit automatiquement deux dossiers placés à côté de l'inventaire (ou à côté du playbook) :
group_vars/<groupe>.yml, ou un dossiergroup_vars/<groupe>/contenant plusieurs fichiers, pour les variables d'un groupe ;host_vars/<hôte>.yml, ou un dossierhost_vars/<hôte>/, pour les variables d'un hôte.
L'arborescence de Sorbier :
inventaire/
├── hosts.yml
├── group_vars/
│ ├── all.yml variables communes à tout le parc
│ ├── linux.yml compte de connexion des serveurs Linux
│ ├── windows/
│ │ ├── vars.yml connexion WinRM des serveurs Windows
│ │ └── vault.yml mots de passe, chiffrés par Ansible Vault
│ └── switchs.yml connexion des switchs Cisco
└── host_vars/
└── srv-web.yml réglages propres au serveur web
Le fichier group_vars/all.yml porte ce qui vaut pour toute l'infrastructure :
---
domaine_ad: ad.sorbier.example
serveurs_dns:
- 192.168.10.177
- 192.168.10.181
serveurs_ntp:
- 192.168.10.177
- 192.168.10.181
group_vars/linux.yml donne le compte de connexion, et host_vars/srv-web.yml les réglages du site :
---
ansible_user: ansible
---
web_nom_site: suivi.sorbier.example
web_racine: /var/www/suivi
Les fichiers de variables Windows et des switchs sont détaillés aux chapitres 10 et 12.
Quand une même variable est définie à plusieurs niveaux, la plus précise gagne : une variable d'hôte l'emporte sur une variable de groupe, un groupe enfant l'emporte sur son groupe parent, et un groupe l'emporte sur all. Si serveurs_ntp est redéfinie dans host_vars/srv-web.yml, c'est cette valeur que reçoit srv-web, et all.yml vaut pour les autres. L'ordre complet, qui inclut les variables des playbooks et des rôles, est au chapitre 6.
Cibler des hôtes : les motifs
Chaque commande et chaque play visent des hôtes par un motif (pattern). Les motifs se combinent :
| Motif | Hôtes visés | Résultat chez Sorbier |
|---|---|---|
all ou * | Tout l'inventaire | Les 7 hôtes |
linux | Un groupe | srv-journaux, srv-web |
srv-web | Un hôte | srv-web |
linux:windows | Union : dans l'un ou l'autre groupe | Les 5 serveurs |
windows:!controleurs | Exclusion : dans le premier, pas dans le second | srv-fichiers |
linux:&serveurs_web | Intersection : dans les deux | srv-web |
srv-* | Caractère générique sur les noms | Les 5 serveurs |
~srv-ad2?$ | Expression régulière (le ~ l'annonce) | srv-ad, srv-ad2 |
Pour voir ce qu'un motif vise sans rien exécuter, ajoute --list-hosts :
ansible 'windows:!controleurs' --list-hosts
hosts (1):
srv-fichiers
Mets les motifs qui contiennent !, & ou * entre apostrophes : sinon le shell les interprète avant Ansible.
L'option --limit (-l) restreint un playbook à une partie de ses hôtes, sans modifier le fichier : ansible-playbook site.yml --limit srv-web n'applique le playbook qu'au serveur web, même si ses plays visent linux. C'est l'option à connaître pour tester un changement sur un seul serveur avant de l'étendre.
Vérifier un inventaire
La commande ansible-inventory affiche l'inventaire tel qu'Ansible le comprend, variables résolues :
ansible-inventory --graph
@all:
|--@ungrouped:
|--@linux:
| |--@supervision:
| | |--srv-journaux
| |--@serveurs_web:
| | |--srv-web
|--@windows:
| |--@controleurs:
| | |--srv-ad
| | |--srv-ad2
| |--@fichiers:
| | |--srv-fichiers
|--@switchs:
| |--sw-etage1
| |--sw-etage2
# Toutes les variables d'un hôte, après fusion des group_vars et host_vars
ansible-inventory --host srv-web
# L'arbre avec les variables de chaque groupe et hôte
ansible-inventory --graph --vars
--host srv-web renvoie un JSON qui contient ansible_host, ansible_user (venu de linux.yml), domaine_ad, serveurs_dns, serveurs_ntp (venus de all.yml) et web_nom_site, web_racine (venus de host_vars). C'est le premier réflexe quand une variable n'a pas la valeur attendue.
L'inventaire dynamique
Un inventaire écrit à la main convient à un parc stable. Quand les machines apparaissent et disparaissent souvent (VM créées à la demande, cloud), on utilise un inventaire dynamique : un plugin interroge une source (un hyperviseur, un fournisseur de cloud, GLPI, l'annuaire) et construit la liste des hôtes à chaque exécution.
Un inventaire dynamique est un fichier YAML qui commence par plugin:. Par exemple, le plugin community.proxmox.proxmox liste les VM du cluster Proxmox VE et les range en groupes selon leur nœud, leur état ou leurs étiquettes (chapitre 13). La commande ansible-doc -t inventory -l liste les plugins d'inventaire installés.
On peut combiner plusieurs sources en passant un dossier comme inventaire : Ansible lit tous les fichiers qu'il contient, statiques et dynamiques, et fusionne le résultat.
Exercices
Exercice 1 sur 3 Convertir en YAML Réussi À revoir
Voici un inventaire INI de l'agence de Marseille. Écris-le en YAML.
[web]
mrs-web1 ansible_host=10.30.1.161
mrs-web2 ansible_host=10.30.1.162
[bdd]
mrs-bdd ansible_host=10.30.1.163
[marseille:children]
web
bdd
[marseille:vars]
ansible_user=ansible
Voir la réponseMasquer la réponse de l'exercice 1
---
all:
children:
marseille:
vars:
ansible_user: ansible
children:
web:
hosts:
mrs-web1:
ansible_host: 10.30.1.161
mrs-web2:
ansible_host: 10.30.1.162
bdd:
hosts:
mrs-bdd:
ansible_host: 10.30.1.163
Les adresses sont bien dans le réseau des serveurs de Marseille, 10.30.1.160/28 (hôtes de .161 à .174). La variable aurait aussi pu aller dans un fichier group_vars/marseille.yml.
Tu avais trouvé ?
Exercice 2 sur 3 Quels hôtes ? Réussi À revoir
Avec l'inventaire YAML de Sorbier de ce chapitre, donne les hôtes visés par chaque motif.
all:!windowscontroleurs:fichierssrv-ad*windows:&linuxansible-playbook site.yml --limit 'linux:!srv-web', quandsite.ymlcontient un playhosts: linux
Voir la réponseMasquer la réponse de l'exercice 2
srv-journaux,srv-web,sw-etage1,sw-etage2: tout sauf les trois serveurs Windows.srv-ad,srv-ad2,srv-fichiers: l'union des deux groupes.srv-ad,srv-ad2.- Aucun hôte : aucun serveur n'est à la fois dans
windowset danslinux. Ansible répond « No hosts matched » et ne fait rien. srv-journauxseulement : le play viselinux, et la limite retiresrv-web.
Tu avais trouvé ?
Exercice 3 sur 3 Quelle valeur ? Réussi À revoir
group_vars/all.yml contient paquets_supplementaires: [htop], group_vars/linux.yml contient paquets_supplementaires: [htop, tcpdump] et host_vars/srv-web.yml contient paquets_supplementaires: [htop, apachetop].
- Quelle valeur reçoivent
srv-web,srv-journauxetsrv-ad? - Chloé voulait que
srv-webreçoivehtop,tcpdumpetapachetop. Pourquoi n'est-ce pas le cas ? - Quelle commande lui aurait montré la valeur réelle avant de lancer le playbook ?
Voir la réponseMasquer la réponse de l'exercice 3
srv-web:[htop, apachetop](la variable d'hôte gagne).srv-journaux:[htop, tcpdump](le groupelinuxgagne surall).srv-ad:[htop](seulallla définit pour lui).- Ansible remplace une variable par la plus prioritaire ; il ne fusionne pas les listes. Pour cumuler, il faut des variables distinctes (par exemple
paquets_communs,paquets_linux,paquets_hote) et les assembler dans la tâche :"{{ paquets_communs + paquets_linux + paquets_hote | default([]) }}". ansible-inventory --host srv-web.
Tu avais trouvé ?