
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 :
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 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 |
Contrôle de connaissances
Section intitulée « Contrôle de connaissances »Vérifiez que l'essentiel de ce guide est acquis. Les questions portent uniquement sur ce qui vient d'être expliqué ici.
Contrôle de connaissances
Validez vos connaissances avec ce quiz interactif
Informations
- Le chronomètre démarre au clic sur Démarrer
- Questions à choix multiples, vrai/faux et réponses courtes
- Vous pouvez naviguer entre les questions
- Les résultats détaillés sont affichés à la fin
Lance le quiz et démarre le chronomètre
Vérification
(0/0)Profil de compétences
Quoi faire maintenant
Ressources pour progresser
Des indices pour retenter votre chance ?
Nouveau quiz complet avec des questions aléatoires
Retravailler uniquement les questions ratées
Retour à la liste des certifications
À 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=.
Mettre en pratique
Section intitulée « Mettre en pratique »Les 22 niveaux ne s'apprennent pas par cœur, ils se constatent. Le lab vous fait déclarer la même variable dans defaults/main.yml, dans vars: du play, dans un vars_files: puis en --extra-vars, et écrire à chaque exécution la valeur gagnante dans un fichier. Isoler un niveau à la fois rend la hiérarchie lisible sans revenir au tableau officiel.
Pour aller plus loin
Section intitulée « Pour aller plus loin »- Filtres Jinja2 essentiels : le filtre
defaultcouvre le cas où aucun des 22 niveaux n'a fourni de valeur. - Conditions avec when : tester
is definedavant d'utiliser une variable évite l'échec en pleine exécution. - Tests Jinja2 : la liste complète des tests qui distinguent une variable absente d'une variable vide.