
Quand la même variable est définie à plusieurs endroits, Ansible applique une règle de précédence stricte sur 22 niveaux. Connaître cet ordre vous évite des heures de debug : non, votre group_vars/all.yml ne peut pas écraser un --extra-vars. Oui, vars/main.yml d’un rôle gagne sur vars: du play. Cette page liste les 22 niveaux officiels, du plus faible (role defaults) au plus fort (--extra-vars), avec des règles pratiques pour ne pas se tromper. Objectif explicite RHCE EX294.
C’est une page de référence — on n’apprend pas à coder en la lisant, on revient la consulter quand un comportement vous surprend.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- L’ordre exact des 22 niveaux de précédence Ansible (du plus faible au plus fort)
- Le regroupement par catégorie : defaults / group_vars / host_vars / play / role / task / extra
- Les 3 règles simples qui couvrent 95 % des cas pratiques
--extra-varsest toujours prioritaire sur tout- Comment diagnostiquer quel niveau a gagné quand une variable a une valeur inattendue
Prérequis
Section intitulée « Prérequis »- Avoir lu Variables — déclaration et Facts et magic vars ;
- Avoir manipulé
group_vars/,host_vars/,vars:,vars_files:,--extra-vars.
Les 22 niveaux officiels
Section intitulée « Les 22 niveaux officiels »Du plus faible (1) au plus fort (22) :
| Niveau | Source | Notes |
|---|---|---|
| 1 | Command-line values (-u, -c…) | Pas vraiment des variables |
| 2 | roles/<role>/defaults/main.yml | Defaults d’un rôle (override naturel) |
| 3 | inventory file group vars | Section [group:vars] d’un inventaire INI |
| 4 | inventory group_vars/all | À côté de l’inventaire |
| 5 | playbook group_vars/all | À côté du playbook |
| 6 | inventory group_vars/<group> | À côté de l’inventaire, par groupe |
| 7 | playbook group_vars/<group> | À côté du playbook, par groupe |
| 8 | inventory file host vars | Section [host:vars] d’un inventaire INI |
| 9 | inventory host_vars/<host> | À côté de l’inventaire |
| 10 | playbook host_vars/<host> | À côté du playbook |
| 11 | host facts / cached set_facts | Facts gathered + set_fact avec cacheable: true |
| 12 | play vars: | Bloc vars: au niveau du play |
| 13 | play vars_prompt: | Variables saisies interactivement |
| 14 | play vars_files: | Fichiers YAML chargés par le play |
| 15 | roles/<role>/vars/main.yml | Vars du rôle (gagne sur le play !) |
| 16 | block vars | Vars sur un block: (limité aux tâches du block) |
| 17 | task vars | Vars sur une tâche (limitées à cette tâche) |
| 18 | include_vars | Module qui charge un fichier au runtime |
| 19 | set_fact / register | Variables créées en cours d’exécution |
| 20 | role (and include_role) params | Params passés à un rôle via roles: - { role: x, var: y } |
| 21 | include params | Params passés via include_tasks/include_role |
| 22 | --extra-vars | Le plus fort — gagne sur tout |
Les 3 règles pratiques (95 % des cas)
Section intitulée « Les 3 règles pratiques (95 % des cas) »Règle 1 — --extra-vars gagne sur tout
Section intitulée « Règle 1 — --extra-vars gagne sur tout »ansible-playbook site.yml --extra-vars "service_name=production-api"Aucun vars:, vars_files:, group_vars/, host_vars/, set_fact: ou vars/main.yml ne peut écraser ça. C’est le niveau 22.
Implication : --extra-vars est l’outil de prédilection en CI/CD pour pousser un tag de release ou un environnement au runtime, sans modifier le code.
Règle 2 — Plus c’est local, plus c’est prioritaire
Section intitulée « Règle 2 — Plus c’est local, plus c’est prioritaire »L’intuition naturelle marche : une variable définie à proximité de la tâche gagne sur une variable définie plus loin :
host_vars/<host> > group_vars/<group> > group_vars/all > defaults↑ très spécifique ↑ très génériquetask vars > block vars > play vars > vars_files > group_vars↑ ultra-local ↑ partagéRègle 3 — vars/main.yml d’un rôle gagne sur vars: du play
Section intitulée « Règle 3 — vars/main.yml d’un rôle gagne sur vars: du play »Piège classique : un rôle pose vars/main.yml (niveau 15) qui écrase vos vars: du play (niveau 12). Conséquence : si vous voulez paramétrer un rôle depuis l’extérieur, utilisez :
defaults/main.ymldu rôle (niveau 2) — peut être overridé naturellement par le caller- role params (niveau 20) :
roles: - { role: nginx, nginx_port: 8080 } --extra-vars(niveau 22)
# Pas ça : impossible à overrider naturellement depuis le play# roles/nginx/vars/main.yml :nginx_port: 80 # ← niveau 15, écrase vars: du play
# Préférer : defaults pour permettre l'override# roles/nginx/defaults/main.yml :nginx_port: 80 # ← niveau 2, le caller peut écraser facilementCas pratique — 3 niveaux qui se court-circuitent
Section intitulée « Cas pratique — 3 niveaux qui se court-circuitent »Reprenons l’exemple validé sur le lab 15-ecrire-code-precedence-variables :
# group_vars/dbservers.yml ← niveau 6 ou 7priority_test: "from_group_vars_dbservers"
# group_vars/all.yml ← niveau 4 ou 5priority_test: "from_group_vars_all"
# playbook.yml- name: Test precedence hosts: db1.lab vars: priority_test: "from_play_vars" # ← niveau 12 tasks: - debug: msg: "priority_test = {{ priority_test }}"Sans --extra-vars :
"msg": "priority_test = from_play_vars"→ vars: du play (12) gagne sur group_vars/dbservers (6/7) qui gagne sur group_vars/all (4/5).
Avec --extra-vars "priority_test=from_extra_vars" (niveau 22) :
"msg": "priority_test = from_extra_vars"→ --extra-vars écrase tout.
Diagnostiquer quel niveau a gagné
Section intitulée « Diagnostiquer quel niveau a gagné »Quand une variable a une valeur inattendue, deux outils :
ansible-inventory --host <hôte>
Section intitulée « ansible-inventory --host <hôte> »Affiche les variables résolues pour un hôte donné, en montrant l’origine (group_vars, host_vars) :
ansible-inventory --host db1.labNe montre pas les vars: du play ni les set_fact: (qui sont dynamiques), mais c’est suffisant pour vérifier group_vars/ et host_vars/.
Un debug stratégique en début de play
Section intitulée « Un debug stratégique en début de play »- name: Debug — voir toutes les sources de la variable ansible.builtin.debug: var: priority_test- name: Debug — voir la valeur réellement utilisée ansible.builtin.debug: msg: "priority_test = {{ priority_test }}"Ajoutez ce duo en haut de votre play quand vous chassez un bug de précédence. Vous voyez immédiatement la valeur active.
Patterns pratiques RHCE
Section intitulée « Patterns pratiques RHCE »Pattern 1 — defaults/main.yml pour permettre l’override
Section intitulée « Pattern 1 — defaults/main.yml pour permettre l’override »Dans un rôle, toujours mettre les valeurs paramétrables dans defaults/main.yml (niveau 2) :
nginx_port: 80nginx_workers: 4nginx_user: nginxLe caller peut alors les écraser via vars:, --extra-vars, ou role params.
Pattern 2 — vars/main.yml pour les constantes du rôle
Section intitulée « Pattern 2 — vars/main.yml pour les constantes du rôle »Réservez vars/main.yml (niveau 15) aux constantes immuables que le caller ne doit pas pouvoir changer :
# Constantes : pas paramétrables par le callernginx_pid_file: /var/run/nginx.pidnginx_log_dir: /var/log/nginxPattern 3 — group_vars/<env>.yml pour les overrides d’environnement
Section intitulée « Pattern 3 — group_vars/<env>.yml pour les overrides d’environnement »Structure type d’un projet multi-environnement :
inventory/├── prod.yml├── staging.yml└── group_vars/ ├── all.yml # variables partagées (niveau 4) ├── webservers.yml # variables groupe (niveau 6) ├── prod.yml # variables environnement prod (niveau 6) └── staging.yml # variables environnement staging (niveau 6)Lancement :
ansible-playbook site.yml -i inventory/prod.ymlgroup_vars/prod.yml charge automatiquement les variables prod, qui peuvent écraser all.yml.
Pattern 4 — --extra-vars pour CI/CD
Section intitulée « Pattern 4 — --extra-vars pour CI/CD »Un job de CI qui déploie une version :
deploy: script: - ansible-playbook site.yml -i inventory/prod.yml --extra-vars "release_tag=$CI_COMMIT_TAG"Aucune variable du repo ne peut écraser release_tag — c’est garanti par le niveau 22.
Pièges fréquents
Section intitulée « Pièges fréquents »| Symptôme | Cause | Fix |
|---|---|---|
--extra-vars ignoré | Mauvais format CLI | Format correct : --extra-vars "k=v k2=v2" |
group_vars/ introuvable | Doit être à côté de l’inventaire OU du playbook | Vérifier les deux emplacements |
| Variable d’un rôle non-overridable | C’est dans vars/main.yml (niveau 15) | Déplacer dans defaults/main.yml (niveau 2) |
set_fact perdu entre runs | Sans cacheable: true, set_fact est éphémère | Ajouter cacheable: true (mais attention : devient persistent !) |
host_vars/ ne gagne pas sur group_vars/ | Mauvais nom de fichier (host_vars/web1 vs host_vars/web1.lab) | Le nom doit matcher exactement inventory_hostname |
À retenir
Section intitulée « À retenir »- 22 niveaux officiels Ansible — du plus faible (
role defaults) au plus fort (--extra-vars). - 3 règles pratiques couvrent 95 % des cas :
--extra-varsgagne sur tout ; plus c’est local, plus c’est prioritaire ;vars/main.ymld’un rôle écrasevars:du play. defaults/main.ymld’un rôle = paramétrable ;vars/main.yml= constante.--extra-varsest l’outil CI/CD par excellence (niveau 22 inattaquable).- En cas de surprise,
ansible-inventory --host <h>+debug: var=.
Pratiquer dans le lab
Section intitulée « Pratiquer dans le lab »Cette page a un lab d’accompagnement : labs/ecrire-code/precedence-variables/ dans
stephrobert/ansible-training. Il contient
un README.md guidé, un Makefile (make verify lance les tests), et un
challenge final auto-évalué : valider que —extra-vars (niveau 22) écrase vars: du play et vars_files:.
Une fois le lab provisionné :
cd ~/Projets/ansible-training/labs/ecrire-code/precedence-variables/
cat README.md # tuto pas à pascat challenge/README.md # consigne du challenge finalpytest -v challenge/tests/ # lancer les tests testinfraSi les tests passent, vous maîtrisez les concepts couverts dans ce guide. En
cas de blocage, docs/troubleshooting.md
à la racine du repo couvre les pièges fréquents (rate-limit SSH, clé absente,
collection manquante).