Skip to content

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 :

Exécution et surcharge des variables avec myvars1.yml

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 :

Précédence des extra vars sur le 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) :

---
mycar: 911
mybike: Suzuki
...

Fichier spécifique pour la cible 2 (host_vars/target02.yml) :

---
mycar: Porsche
mybike: Honda
...

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 :

Exécution avec group_vars et host_vars

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. Validation du fichier avec le test


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 :

exit
vagrant destroy -f

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 vars ont toujours la priorité absolue et ne peuvent pas être surchargées.
  • vars_prompt permet de saisir des valeurs interactivement (utile pour les secrets).
  • host_vars surcharge group_vars pour 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)


Précédent : Handlers Suite : Stored Variables