Aller au contenu
Infrastructure as Code medium

group_vars et host_vars : structurer les variables d'inventaire Ansible

10 min de lecture

Logo Ansible

group_vars/ et host_vars/ sont les emplacements standardAnsible cherche automatiquement les variables liées à votre inventaire. Pas besoin de vars_files:, pas besoin de --extra-vars — il suffit que les fichiers soient bien placés et nommés selon une convention stricte. C’est cette convention qui rend votre inventaire maintenable au fil du temps.

Cette page couvre l’organisation de ces dossiers, la précédence quand une même variable est définie à plusieurs niveaux, et le pattern dossier (un dossier par groupe au lieu d’un fichier) pour des projets qui grandissent.

  • Placer correctement group_vars/ et host_vars/ à côté de l’inventaire.
  • Définir une variable au niveau groupe ou au niveau host.
  • Comprendre la précédence : host_vars > group_vars/<groupe> > group_vars/all.
  • Splitter en plusieurs fichiers via le pattern dossier (group_vars/<groupe>/main.yml + vault.yml).
  • Vérifier la résolution avec ansible-inventory --host.

Ansible cherche ces dossiers à côté du fichier d’inventaire, pas à côté du playbook :

ma_formation/
├── ansible.cfg
├── playbooks/
│ └── deploy.yml
└── inventory/
├── hosts.yml ← l'inventaire
├── group_vars/ ← variables par groupe
│ ├── all.yml ← tous les hôtes
│ ├── webservers.yml
│ └── dbservers.yml
└── host_vars/ ← variables par host
├── web1.lab.yml
└── db1.lab.yml

Règle stricte : group_vars/ et host_vars/ doivent être soit dans le même dossier que l’inventaire, soit dans le dossier du playbook. Si vous les mettez ailleurs, Ansible ne les trouve pas — sans erreur explicite, juste des variables manquantes.

group_vars/all.yml est appliqué à tous les hôtes de l’inventaire — c’est le fallback quand aucune variable plus spécifique n’est définie.

inventory/group_vars/all.yml
---
admin_email: ops@example.com
ntp_server: ntp.lab
backup_retention_days: 30

Toutes vos machines (webservers, dbservers, control…) reçoivent ces 3 variables. Idéal pour des paramètres organisationnels qui ne dépendent pas du rôle de la machine.

Pour des paramètres spécifiques à un rôle (web vs db vs LB), créer un fichier par groupe :

inventory/group_vars/webservers.yml
---
http_port: 8080
worker_processes: 4
nginx_max_body_size: 10m

Toutes les machines du groupe webservers (web1, web2…) reçoivent ces 3 variables. Les machines hors du groupe (db1) ne les voient pas.

Pour une exception ponctuelle sur un seul host :

inventory/host_vars/web1.lab.yml
---
http_port: 9090 # web1 écoute sur 9090, pas 8080
ssl_cert: /etc/pki/web1.lab.crt

web1.lab reçoit http_port: 9090 (override de webservers.yml) et ssl_cert: .... web2.lab reste sur http_port: 8080.

Précédence — la règle “le plus local gagne”

Section intitulée « Précédence — la règle “le plus local gagne” »

Quand la même variable est définie à plusieurs niveaux, Ansible applique cette hiérarchie (de la plus faible à la plus forte) :

PrioritéSourceExemple
1 (faible)group_vars/all.ymlapp_port: 80
2group_vars/<groupe parent>.ymlapp_port: 8080 (webservers)
3group_vars/<groupe enfant>.ymlapp_port: 8443 (sous-groupe)
4 (forte)host_vars/<host>.ymlapp_port: 9090 (web1)

Démonstration dans le lab inventaires/group-vars-host-vars : la même variable app_port définie à 3 niveaux donne 3 valeurs différentes selon le host :

Fenêtre de terminal
$ ansible-inventory --host web1.lab | grep app_port
"app_port": 9090 # host_vars/web1.lab.yml gagne
$ ansible-inventory --host web2.lab | grep app_port
"app_port": 8080 # group_vars/webservers.yml gagne (pas de host_vars)
$ ansible-inventory --host db1.lab | grep app_port
"app_port": 80 # group_vars/all.yml (fallback)

Pattern dossier — splitter en plusieurs fichiers

Section intitulée « Pattern dossier — splitter en plusieurs fichiers »

Quand group_vars/webservers.yml dépasse 50 lignes, le pattern dossier rend la lecture plus propre :

inventory/
├── hosts.yml
└── group_vars/
└── webservers/
├── main.yml ← variables principales
├── network.yml ← config réseau
└── vault.yml ← secrets chiffrés Ansible Vault

Ansible fusionne automatiquement tous les .yml du dossier webservers/. Aucun ordre garanti — donc pas de variable redéfinie entre fichiers (sinon comportement aléatoire). Convention : un fichier par thème (réseau, sécurité, app, secrets).

group_vars/webservers/main.yml
http_port: 8080
worker_processes: 4
group_vars/webservers/network.yml
internal_subnet: 10.10.20.0/24
external_dns: 8.8.8.8
# group_vars/webservers/vault.yml (chiffré par ansible-vault)
$ANSIBLE_VAULT;1.1;AES256
3133...

Mandatory pour les secrets : isoler dans vault.yml chiffré séparément du reste — vous pouvez ainsi lire le main.yml sans déchiffrer.

ansible-inventory --host <host> est l’outil pour voir toutes les variables résolues :

Fenêtre de terminal
ansible-inventory --host web1.lab

Sortie tronquée :

{
"ansible_host": "10.10.20.21",
"ansible_user": "ansible",
"app_port": 9090,
"http_port": 9090,
"ssl_cert": "/etc/pki/web1.lab.crt",
"worker_processes": 4
}

Vous voyez toutes les variables résolues, peu importe leur source. Indispensable pour debugger un override inattendu.

--graph montre la structure des groupes :

Fenêtre de terminal
ansible-inventory --graph
@all:
|--@webservers:
| |--web1.lab
| |--web2.lab
|--@dbservers:
| |--db1.lab

Cette page a un lab d’accompagnement : labs/inventaires/group-vars-host-vars/ dans stephrobert/ansible-training. Il définit app_port aux 3 niveaux (all, webservers, host_vars/web1.lab) et démontre la résolution via un playbook qui pose un fichier marqueur sur chaque host.

Fenêtre de terminal
cd ~/Projets/ansible-training/labs/inventaires/group-vars-host-vars/
cat README.md
ansible-inventory -i inventory/hosts.yml --host web1.lab | grep app_port
ansible-inventory -i inventory/hosts.yml --host db1.lab | grep app_port
pytest -v challenge/tests/
SymptômeCauseFix
Variable absente alors qu’elle est dans group_vars/X.ymlLe dossier group_vars/ est à côté du playbook au lieu de l’inventaireDéplacer à côté de inventory/hosts.yml
Variable dans host_vars/web1.yml ignoréeLe hostname ne correspond pas au fichierDoit être host_vars/web1.lab.yml si l’inventaire référence web1.lab
Override inattenduNe pas confondre niveaux : group_vars/<sous-groupe> > group_vars/<parent>Tester avec ansible-inventory --host
Secret en clair lu par accidentPas séparé dans vault.ymlConvention : main.yml + vault.yml (chiffré)
Comportement aléatoire entre 2 fichiers du dossierVariable redéfinie dans 2 fichiers du même groupeUne variable, un seul fichier — sinon ordre non garanti
  • group_vars/ et host_vars/ sont placés à côté de l’inventaire (pas du playbook).
  • group_vars/all.yml s’applique à tous les hôtes — fallback par défaut.
  • group_vars/<groupe>.yml s’applique aux hôtes du groupe ; host_vars/<host>.yml ne s’applique qu’à un host.
  • Précédence : host_vars > group_vars/<groupe> > group_vars/all. Le plus local gagne.
  • Pattern dossier : group_vars/<groupe>/main.yml + vault.yml pour des configs volumineuses.
  • ansible-inventory --host <host> est l’outil pour vérifier la résolution.

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens +700 guides gratuits, sans pub ni tracing. Aujourd'hui, ce site ne couvre même pas mes frais d'hébergement, d'électricité, de matériel, de logiciels, mais surtout de cafés.

Un soutien régulier, même symbolique, m'aide à garder ces ressources gratuites et à continuer de produire des guides de qualité. Merci pour votre appui.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn