Aller au contenu principal
AnsibleDevOpsAutomationInfrastructure as Code

Variables et priorités

30 min de lecture Ansible — Chapitre 5

Maîtrise la hiérarchie des variables Ansible, host_vars et group_vars, et sécurise tes secrets avec Ansible Vault.

🎯 Objectif : À la fin de ce chapitre, tu maîtriseras le système de variables Ansible, la précédence, et tu sauras organiser tes secrets avec Vault. ⏱️ Durée estimée : 50 minutes | Niveau : Intermédiaire

Un playbook Ansible sans variables, c’est comme un script avec des valeurs en dur partout : ça marche une fois, sur une machine, dans un contexte précis. Dès que tu gères plusieurs environnements — staging, production, DR — les variables deviennent ton outil principal pour écrire du code réutilisable. Le problème, c’est qu’Ansible permet de définir la même variable à une vingtaine d’endroits différents. Si tu ne comprends pas qui gagne, tu vas passer des heures à debugger des comportements inexplicables.

Ce chapitre t’apprend à organiser tes variables proprement, à comprendre la précédence, et à chiffrer tes secrets pour ne jamais les exposer dans Git.

Pourquoi les variables sont essentielles

Dans un projet Ansible réel, tu ne déploies pas un seul serveur identique. Tu gères des groupes de machines avec des rôles différents — serveurs web, bases de données, monitoring — chacun avec ses propres paramètres. Les variables te permettent d’écrire un playbook unique qui s’adapte automatiquement à chaque contexte.

Sans variables, tu te retrouves à dupliquer tes playbooks par environnement, à copier-coller des rôles pour changer un port ou un mot de passe. C’est la recette parfaite pour les incohérences et les oublis en prod.

🔥 Cas réel : Une équipe avait dupliqué son playbook Nginx pour staging et production. Au bout de 6 mois, les deux versions avaient divergé silencieusement. Un rollback en production a appliqué une config staging par erreur — 2h de downtime. Un seul playbook avec des group_vars par environnement aurait évité le problème.

💡 Tip DevOps : Adopte le principe DRY (Don’t Repeat Yourself) dès le départ. Un playbook, des variables par environnement. Toujours.

Comprendre la hiérarchie de précédence

Ansible définit 22 niveaux de précédence pour les variables. Bonne nouvelle : tu n’as pas besoin de tous les connaître. En pratique, retiens ces cinq niveaux du plus faible au plus fort :

  • Très basseroles/x/defaults/main.yml : les valeurs par défaut de tes rôles, faites pour être overridées
  • Basse — Variables d’inventaire (définies directement dans le fichier d’inventaire)
  • Moyennegroup_vars/ et host_vars/ : le cœur de ta configuration par groupe et par hôte
  • Hautevars: dans le play ou la task : override local dans le playbook
  • Très haute--extra-vars (-e) en ligne de commande : gagne toujours, sur tout

Pour bien comprendre, voici un exemple concret. On définit nginx_port à quatre niveaux différents et Ansible résout la valeur selon la priorité :

# roles/nginx/defaults/main.yml → priorité basse
nginx_port: 80

# group_vars/webservers.yml → override le default
nginx_port: 8080

# host_vars/web01.yml → override le group_var pour web01
nginx_port: 9090

# Ligne de commande : ansible-playbook site.yml -e "nginx_port=443"
# → 443 gagne partout, sur tous les hôtes

Sur web01, sans extra-vars, la valeur sera 9090. Sur web02 (pas de host_var), ce sera 8080. Avec -e, tout le monde passe à 443.

🧠 À retenir : Mets tes valeurs par défaut dans defaults/, tes configurations spécifiques dans group_vars/ et host_vars/, et réserve -e pour les urgences ou le CI/CD.

Commandes essentielles : group_vars, host_vars et Vault

Organiser ses variables

La structure recommandée pour un projet multi-environnement utilise des dossiers group_vars/ et host_vars/ à côté de ton inventaire. Chaque fichier YAML correspond à un groupe ou un hôte :

project/
├── inventory/
│   ├── production.yml
│   ├── group_vars/
│   │   ├── all.yml           # Variables globales (tous les hôtes)
│   │   ├── all/
│   │   │   ├── vars.yml      # Variables en clair
│   │   │   └── vault.yml     # Secrets chiffrés
│   │   ├── webservers.yml    # Groupe webservers
│   │   └── dbservers.yml     # Groupe dbservers
│   └── host_vars/
│       ├── web01.yml          # Override spécifique à web01
│       └── db01/
│           ├── vars.yml
│           └── vault.yml

Le dossier all/ avec un split vars.yml / vault.yml est une convention clé : ça te permet de garder les variables lisibles dans vars.yml tout en chiffrant les secrets dans vault.yml.

Chiffrer avec Ansible Vault

Ansible Vault chiffre tes fichiers sensibles avec AES-256. Voici les commandes indispensables :

# Créer un fichier chiffré (ouvre l'éditeur)
ansible-vault create group_vars/all/vault.yml

# Chiffrer un fichier existant
ansible-vault encrypt group_vars/dbservers/secrets.yml

# Éditer un fichier chiffré
ansible-vault edit group_vars/all/vault.yml

# Voir le contenu sans modifier
ansible-vault view group_vars/all/vault.yml

⚠️ Attention : Ne lance jamais ansible-vault decrypt sur un fichier déjà committé dans Git. Tu risques de pousser des secrets en clair. Utilise edit ou view à la place.

La convention vault_

Préfixe toujours tes variables chiffrées avec vault_, puis référence-les dans un fichier en clair. Cette indirection rend le code lisible tout en gardant les secrets protégés :

# group_vars/all/vault.yml (chiffré)
vault_db_password: "S3cur3P@ssw0rd!"
vault_api_key: "sk-abc123xyz789"

# group_vars/all/vars.yml (clair, référence le vault)
db_password: "{{ vault_db_password }}"
api_key: "{{ vault_api_key }}"

Pour exécuter un playbook qui utilise Vault, tu as trois options : --ask-vault-pass (interactif), --vault-password-file (fichier), ou une variable d’environnement en CI/CD.

# Interactif
ansible-playbook site.yml --ask-vault-pass

# Avec fichier de mot de passe (chmod 600 !)
ansible-playbook site.yml --vault-password-file ~/.vault_pass

# En CI/CD : passer via variable d'environnement
echo "$VAULT_PASSWORD" > /tmp/.vault_pass && chmod 600 /tmp/.vault_pass
ansible-playbook site.yml --vault-password-file /tmp/.vault_pass
rm -f /tmp/.vault_pass

💡 Tip DevOps : Ajoute vault_password_file = ~/.vault_pass dans ton ansible.cfg pour ne plus avoir à taper l’option à chaque fois. Et mets .vault_pass dans ton .gitignore.

Cas concret : déploiement multi-environnement

Imaginons une startup qui gère trois serveurs web et une base de données, avec staging et production. Voici comment structurer les variables pour que le même playbook serve partout.

Le fichier group_vars/all.yml contient ce qui est commun à toutes les machines — utilisateur de déploiement, serveurs NTP, configuration SSH :

# group_vars/all.yml
ansible_user: deploy
ansible_become: true
ntp_servers:
  - 0.ch.pool.ntp.org
  - 1.ch.pool.ntp.org
ssh_permit_root: false
env: production
domain: monapp.ch

Le fichier group_vars/webservers.yml définit les paramètres Nginx et PHP pour tous les serveurs web, tandis que host_vars/web01.yml override les workers Nginx pour le serveur principal qui reçoit plus de trafic. Quand tu lances le playbook, chaque hôte reçoit automatiquement les bonnes valeurs : web01 a 8 workers (host_var), web02 en a 4 (group_var), et tous partagent le même domaine (all.yml).

🔥 Cas réel : En CI/CD, tu peux utiliser -e "env=staging domain=staging.monapp.ch" pour déployer le même playbook sur l’environnement de staging sans toucher à un seul fichier de variables.

Pièges fréquents

Définir des variables dans l’inventaire directement. C’est tentant de mettre ansible_port=2222 à côté du hostname dans l’inventaire. Ça fonctionne, mais c’est impossible à maintenir à grande échelle. Utilise host_vars/ à la place.

Oublier que -e écrase tout. Un collègue qui lance ansible-playbook site.yml -e "env=staging" en croyant tester un truc va overrider la variable env sur tous les hôtes, y compris production si l’inventaire n’est pas bien séparé.

⚠️ Attention : Sépare toujours tes inventaires par environnement (inventory/production.yml, inventory/staging.yml) et lance tes playbooks avec -i inventory/production.yml explicitement. Ne mélange jamais staging et prod dans le même fichier d’inventaire.

Confondre defaults/ et vars/ dans un rôle. Les fichiers dans roles/x/defaults/ sont faits pour être overridés (priorité basse). Les fichiers dans roles/x/vars/ ont une priorité haute et sont difficiles à overrider. Mets presque tout dans defaults/.

Ne pas versionner les fichiers vault. Les fichiers chiffrés par Vault doivent être committés dans Git — c’est le principe. Ce qu’on ne committe jamais, c’est le fichier de mot de passe (.vault_pass).

🧠 À retenir : Un fichier vault chiffré dans Git = normal. Un mot de passe vault dans Git = incident de sécurité.

Exercice pratique

Crée un projet Ansible avec la structure suivante et vérifie la résolution des variables :

exercice-05/
├── inventory/
│   ├── production.yml
│   ├── group_vars/
│   │   ├── all.yml
│   │   ├── all/
│   │   │   └── vault.yml
│   │   └── webservers.yml
│   └── host_vars/
│       └── web01.yml
├── roles/
│   └── nginx/
│       └── defaults/
│           └── main.yml
└── site.yml
  1. Définis app_port: 3000 dans roles/nginx/defaults/main.yml
  2. Override avec app_port: 8080 dans group_vars/webservers.yml
  3. Override avec app_port: 9090 dans host_vars/web01.yml
  4. Crée un playbook site.yml qui affiche la valeur avec debug
  5. Lance avec ansible-playbook -i inventory/production.yml site.yml et vérifie la valeur
  6. Relance avec -e "app_port=443" et constate que -e gagne
  7. Crée un secret vault_db_password avec ansible-vault create et référence-le dans group_vars/all.yml

Résultat attendu : tu observes la cascade de précédence en action, et tu sais chiffrer un secret proprement.


🧠 À retenir

  • Les variables Ansible suivent une hiérarchie stricte de 22 niveaux — retiens les 5 principaux
  • defaults/ = valeurs par défaut (overridables), group_vars/ = config par groupe, host_vars/ = override par hôte
  • --extra-vars gagne toujours — utilise-le pour le CI/CD et les urgences
  • Ansible Vault chiffre avec AES-256 — committe les fichiers chiffrés, jamais le mot de passe
  • Convention vault_ + indirection = code lisible et secrets protégés
  • Un playbook + des variables par environnement > des playbooks dupliqués

➡️ La suite

Dans le prochain chapitre, on génère des configurations dynamiques avec les templates Jinja2 : filtres, boucles, conditions et macros.

🖥️ Pratique sur ton propre serveur

Pour suivre Ansible en conditions réelles, tu as besoin d'un VPS. DigitalOcean offre 200$ de crédit gratuit pour démarrer.

Obtenir 200$

Articles liés