
Une variable Ansible peut être déclarée à 5 endroits différents — et selon l’endroit, elle est plus ou moins prioritaire. Cette page pose les bases : les 5 emplacements principaux (vars:, vars_files:, --extra-vars, group_vars/, host_vars/), les types simples acceptés (string, integer, float, boolean), et les règles de portée d’une variable du play vers les tâches enfants. La précédence complète (22 niveaux officiels) est l’objet d’une page dédiée — ici on couvre les cas les plus fréquents.
L’exemple central : un playbook qui déclare des variables au niveau play, charge un fichier de variables externe, et accepte un override CLI via --extra-vars. C’est exactement le pattern utilisé en CI/CD pour pousser une variable de release au runtime sans modifier le code.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Déclarer une variable via
vars:au niveau d’un play - Charger un fichier YAML externe via
vars_files:(utile pour les secrets Vault) - Overrider via
--extra-varsdepuis la ligne de commande (niveau le plus prioritaire) - Comprendre le rôle de
group_vars/ethost_vars/comme emplacements automatiques - Reconnaître les types simples : string, integer, float, boolean, null
Prérequis
Section intitulée « Prérequis »- Avoir lu la sous-section Fondations ;
- Connaître les bases d’un play :
hosts:,become:,tasks:(cf. Plays et tasks).
Les 5 emplacements de déclaration
Section intitulée « Les 5 emplacements de déclaration »1. vars: — variables locales au play
Section intitulée « 1. vars: — variables locales au play »C’est l’emplacement le plus simple : un bloc vars: à l’intérieur d’un play. Les variables sont disponibles dans toutes les tâches du play.
- name: Démo variables play hosts: web1.lab become: true
vars: service_name: "default-service" service_port: 8000 debug_enabled: false
tasks: - name: Afficher ansible.builtin.debug: msg: "{{ service_name }} sur le port {{ service_port }}"Convient pour des variables courtes, qui n’ont de sens qu’à l’intérieur du play.
2. vars_files: — fichiers YAML externes
Section intitulée « 2. vars_files: — fichiers YAML externes »Quand le bloc vars: devient trop long ou contient des secrets (qu’on veut chiffrer avec ansible-vault), on bascule sur des fichiers externes :
- name: Démo vars_files hosts: web1.lab become: true
vars_files: - vars/app.yml - vars/secrets.yml # chiffré avec ansible-vault
tasks: - name: Afficher la version ansible.builtin.debug: msg: "Version : {{ app_version }}"vars/app.yml :
---app_version: "1.0"app_port: 80Les variables du fichier sont fusionnées avec les vars: du play. Si une clé existe dans les deux, le vars: du play l’emporte (mais cette nuance varie selon la précédence — cf. page dédiée).
3. --extra-vars — override CLI
Section intitulée « 3. --extra-vars — override CLI »L’emplacement le plus prioritaire (niveau 22) — même au-dessus de vars/main.yml d’un rôle. Permet d’injecter une variable au runtime sans toucher au code :
ansible-playbook site.yml --extra-vars "service_name=production-api"Plusieurs variables :
ansible-playbook site.yml \ --extra-vars "service_name=production-api db_max_connections=500"Depuis un fichier JSON ou YAML :
ansible-playbook site.yml --extra-vars "@vars/release.yml"C’est le pattern par excellence en CI/CD : la pipeline injecte la version, l’environnement, le tag de release.
4. group_vars/ — variables par groupe d’inventaire
Section intitulée « 4. group_vars/ — variables par groupe d’inventaire »Le dossier group_vars/ à côté de l’inventaire ou du playbook est chargé automatiquement :
group_vars/├── all.yml # variables pour TOUS les hôtes├── webservers.yml # variables pour le groupe webservers└── dbservers.yml # variables pour le groupe dbserversgroup_vars/webservers.yml :
---nginx_workers: 4nginx_port: 80Sans vars_files:, sans bloc vars:, ces variables sont disponibles dans tout play qui cible le groupe webservers.
5. host_vars/ — variables par hôte
Section intitulée « 5. host_vars/ — variables par hôte »Idem mais par hôte :
host_vars/├── web1.lab.yml # variables propres à web1.lab└── db1.lab.yml # variables propres à db1.labPlus prioritaire que group_vars/ : si une variable est définie dans les deux, host_vars/<hôte>.yml l’emporte.
Cas pratique — précédence vars / vars_files / —extra-vars
Section intitulée « Cas pratique — précédence vars / vars_files / —extra-vars »Reprenons l’exemple complet du lab. Un playbook qui combine les trois sources, et un --extra-vars qui override sélectivement :
---- name: Challenge variables-base (precedence vars play vs vars_files vs extra-vars) hosts: db1.lab become: true
vars: service_name: "default-service" service_port: 8000
vars_files: - vars/db.yml
tasks: - name: Poser le fichier marqueur avec toutes les variables résolues ansible.builtin.copy: dest: /tmp/challenge-vars.txt content: | service_name={{ service_name }} service_port={{ service_port }} db_engine={{ db_engine }} db_max_connections={{ db_max_connections }} mode: "0644"Avec vars/db.yml :
---db_engine: "postgresql"db_max_connections: 100Lancement avec override :
ansible-playbook site.yml \ --extra-vars "service_name=production-api db_max_connections=500"Contenu attendu de /tmp/challenge-vars.txt :
service_name=production-api ← écrasé par --extra-vars (niveau 22)service_port=8000 ← du vars: du play (niveau 4)db_engine=postgresql ← du vars_files: (niveau 7)db_max_connections=500 ← écrasé par --extra-vars--extra-vars gagne sur tout. Le vars: du play et le vars_files: ne sont actifs que pour les variables non surchargées.
Les types simples
Section intitulée « Les types simples »YAML 1.2 reconnaît automatiquement les types primitifs sans annotation :
# Stringservice_name: "production-api"service_short_name: nginx # OK sans quotes (pas de caractère ambigu)
# Integerservice_port: 8080max_connections: 100
# Floattimeout_seconds: 30.5
# Boolean (YAML 1.2 strict)debug_enabled: truessl_required: false
# Nulloptional_value: ~ # ou : nullRègles de portée
Section intitulée « Règles de portée »Une variable déclarée au niveau play (vars:) est disponible :
- Dans toutes les tâches (
tasks:,pre_tasks:,post_tasks:) - Dans les handlers déclenchés par ce play
- Dans les rôles appelés par ce play (sauf si le rôle redéfinit la variable dans
vars/main.yml) - Dans les modules d’expression :
when:,loop:,register:
Une variable déclarée dans group_vars/all.yml est disponible partout, dans tout play, du moment que l’inventaire est chargé.
Une variable déclarée dans vars/ d’un rôle (roles/<role>/vars/main.yml) est figée pour ce rôle — elle écrase même les vars: du play. À utiliser avec parcimonie : préférez defaults/main.yml (faible précédence, override naturel par le caller).
Pièges fréquents
Section intitulée « Pièges fréquents »| Symptôme | Cause | Fix |
|---|---|---|
--extra-vars ignoré | Mauvais format (--extra-vars="key=val" sans espace) | Format correct : --extra-vars "key=val key2=val2" ou --extra-vars '{"key":"val"}' |
vars_files: introuvable | Chemin relatif au playbook, pas au cwd | Tester avec ansible-playbook --syntax-check ou utiliser playbook_dir |
Variable définie dans group_vars/ non vue | Le group_vars/ doit être à côté de l’inventaire OU du playbook | Vérifier la doc Ansible sur les emplacements valides |
| Booléen non reconnu | yes/no au lieu de true/false | Migrer vers la forme stricte YAML 1.2 |
| Variable d’un rôle écrase celle du play | roles/<role>/vars/main.yml est niveau 18 (haut) | Utiliser defaults/main.yml (niveau 2) pour les overrides naturels |
À retenir
Section intitulée « À retenir »- 5 emplacements principaux pour déclarer une variable :
vars:,vars_files:,--extra-vars,group_vars/,host_vars/. --extra-varsest le niveau 22 — le plus prioritaire, écrase tout.group_vars/ethost_vars/sont automatiquement chargés depuis l’inventaire ou le playbook.- Les types simples YAML 1.2 sont auto-détectés ; toujours quoter les valeurs ambiguës.
vars/d’un rôle (niveau 18) écrase lesvars:du play — préférerdefaults/main.yml(niveau 2).
Pratiquer dans le lab
Section intitulée « Pratiquer dans le lab »Cette page a un lab d’accompagnement : labs/ecrire-code/variables-base/ dans
stephrobert/ansible-training. Il contient
un README.md guidé, un Makefile (make verify lance les tests), et un
challenge final auto-évalué : démontrer la précédence : —extra-vars > vars: du play > vars_files: dans un fichier marqueur.
Une fois le lab provisionné :
cd ~/Projets/ansible-training/labs/ecrire-code/variables-base/
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).