Compte rendu de TP : Manipulation et Précédence des Variables (Atelier 14)¶
Objectif
Explorer les différentes méthodes de déclaration des variables dans ansible (play vars, extra vars, set_fact, group_vars, host_vars, vars_prompt) afin d'appréhender concrètement leurs niveaux de précédence et leur comportement lors de l'exécution d'un playbook.
Durée
~35 minutes (4 playbooks à tester)
Objectif du TP¶
L'objectif de cet atelier est d'explorer les différentes méthodes de déclaration des variables dans ansible (play vars, extra vars, set_fact, group_vars, host_vars, et saisie interactive via vars_prompt) afin d'appréhender concrètement leurs niveaux de précédence et leur comportement lors de l'exécution d'un playbook.
1. Play vars et Extra vars (myvars1.yml)¶
Nous commençons par écrire un playbook qui définit des variables directement au niveau du "play" (play vars).
Création du fichier myvars1.yml :
---
# myvars1.yml
- hosts: all
gather_facts: false
vars:
mycar: Porsche
mybike: Yamaha
tasks:
- name: Display favorites
debug:
msg: "Ma voiture préférée est de chez {{ mycar }} et ma moto préférée est de la marque {{ mybike }}."
...
Les extra vars (passées via l'option -e en ligne de commande) ont la précédence absolue sur les play vars. Pour le prouver, nous exécutons le playbook d'abord sans argument, puis en surchargeant successivement les variables :

Comme le montre la capture ci-dessus (img01.jpg) :
* L'exécution standard affiche les valeurs définies dans le playbook (Porsche, Yamaha).
* L'ajout de -e mycar=Renault remplace dynamiquement la voiture.
* L'ajout de -e mybike=Kawasaki remplace la moto.
* L'ajout de -e mycar=Porsche -e mybike=Ducati écrase les deux valeurs simultanément.
2. Variables dynamiques avec set_fact (myvars2.yml)¶
La directive set_fact permet de définir des variables en cours d'exécution des tâches.
Création du fichier myvars2.yml :
---
# myvars2.yml
- hosts: all
gather_facts: false
tasks:
- name: Define variables dynamically
set_fact:
mycar: Porsche
mybike: Yamaha
- name: Display favorites
debug:
msg: "Ma voiture préférée de chez {{ mycar }} et ma moto préférée est de la marque {{ mybike }}."
...
Nous exécutons ce playbook en passant des extra vars (Ferrari et Suzuki*) pour vérifier si ces dernières l'emportent sur les variables définies via set_fact :

Comme illustré sur la capture (img02.png), le module debug affiche "Ferrari" et "Suzuki". Les extra vars conservent donc le plus haut niveau de priorité, supplantant totalement les valeurs générées par la tâche set_fact.*
3. Variables d'inventaire : group_vars et host_vars (myvars3.yml)¶
Nous souhaitons maintenant définir des valeurs par défaut pour tout notre parc, avec une exception spécifique pour l'hôte target02, le tout sans écrire les variables en dur dans le playbook.
Nous avons donc créé nos fichiers d'inventaire aux emplacements adéquats :
Fichier global pour tout le groupe (group_vars/all.yml) :
Fichier spécifique pour la cible 2 (host_vars/target02.yml) :
Création du fichier myvars3.yml (qui se contente d'appeler les variables sans les définir en interne) :
---
# myvars3.yml
- hosts: all
gather_facts: false
tasks:
- name: Display favorites from inventory variables
debug:
msg: "Voiture: {{ mycar }}, Moto: {{ mybike }}"
...
Exécution du playbook :

Le résultat (img03.png) confirme que target01 et target03 affichent les variables définies dans group_vars/all.yml (911 et Suzuki). En revanche, target02 affiche les variables issues de host_vars/target02.yml (Porsche et Honda). Cela démontre concrètement que les variables d'hôtes (host_vars) ont une priorité supérieure aux variables de groupes (group_vars).
4. Variables interactives : vars_prompt (display_user.yml)¶
Pour manipuler des informations sensibles sans les écrire en clair dans le code, ansible permet de demander une saisie interactive.
Création de display_user.yml :
---
# display_user.yml
- hosts: localhost
gather_facts: false
vars_prompt:
- name: user
prompt: "Veuillez saisir le nom d'utilisateur"
default: microlinux
private: false
- name: password
prompt: "Veuillez saisir le mot de passe"
default: yatahongaga
private: true
tasks:
- name: Display credentials
debug:
msg: "L'utilisateur est {{ user }} et le mot de passe est {{ password }}."
...
Lors de l'exécution (ansible-playbook display_user.yml), le terminal se met en pause, affiche le texte de prompt et masque la saisie du mot de passe (private: true), garantissant ainsi la sécurité de la donnée lors de la frappe.

5. Nettoyage de l'environnement¶
Toutes les manipulations sur les variables et leurs règles de précédence étant validées avec succès, nous quittons le Control Host et procédons à la destruction des machines virtuelles de l'atelier :
Je retiens
- Ordre de précédence (du plus faible au plus fort) :
group_vars<host_vars<play vars<set_fact<extra vars(-e). extra varsont toujours la priorité absolue et ne peuvent pas être surchargées.vars_promptpermet de saisir des valeurs interactivement (utile pour les secrets).host_varssurchargegroup_varspour un hôte spécifique.
Cheatsheet¶
| Symptôme | Cause probable | Correction |
|---|---|---|
-e mycar=Renault est ignoré |
Une extra var avec un = non échappé ou une précédence mal comprise (pourtant c'est le plus fort…) |
Vérifier la syntaxe : -e "mycar=Renault" ou -e '{"mycar": "Renault"}' (JSON) |
ERROR! 'mycar' is undefined sur target02 uniquement |
Le fichier host_vars/target02.yml n'est pas au bon endroit (relatif à l'inventaire, pas au playbook) |
Placer host_vars/ à côté du fichier d'inventaire ou du playbook racine |
group_vars/all.yml n'est jamais chargé |
Mauvais nom de fichier ou répertoire (all.yml / all.yaml / sans extension sont tolérés mais pas All.yml) |
Respecter la casse exacte all.yml |
vars_prompt affiche le mot de passe en clair à l'écran |
private: true oublié sur la variable sensible |
Ajouter private: true pour masquer la saisie |
Une variable définie dans un rôle écrase une host_vars inattendue |
Précédence : role defaults < inventory vars < play vars < task vars < extra vars |
Consulter la table de précédence officielle avant de placer une variable |
Un secret saisi via vars_prompt apparaît dans les logs |
Niveau de verbosité -vvv affiche les variables, ou no_log non positionné sur la tâche qui l'utilise |
Ajouter no_log: true sur les tâches qui manipulent le secret |
Sources (principales)¶
- Docs
ansibleVariable precedence: Where should I put a variable? - Docs
ansibleUsing variables (group_vars,host_vars) - Docs
ansibleset_factmodule - Docs
ansiblevars_prompt(saisie interactive) - Docs
ansiblePassing variables on the command line (-e) - Docs
ansibleProtecting sensitive data withno_log - Docs
ansibleAnsible Vault (chiffrer des variables sensibles)
Précédent : Handlers Suite : Stored Variables