Utilisation des variables avec Ansible
Mise à jour :
Les variables Ansible sont indispensables pour rendre vos playbooks réutilisables, dynamiques et faciles à maintenir. Elles permettent de personnaliser l’exécution des tâches selon les hôtes, les environnements ou les rôles. Que ce soit pour définir un chemin d’installation, une adresse IP ou un mot de passe, les variables évitent de dupliquer du code en dur. Elles sont définissables à plusieurs endroits — dans un playbook, un fichier d’inventaire, un rôle ou même en ligne de commande — et Ansible gère leur priorité grâce à un système de précédence bien établi.
Définir des variables
Ansible permet de définir des variables à différents endroits dans un projet. Chaque emplacement a ses usages privilégiés, selon que l’on souhaite définir des variables globales, par hôte, par groupe, ou spécifiques à un rôle. Bien organiser ces variables est essentiel pour garder des playbooks lisibles, maintenables et réutilisables.
Rappel : Dans le guide sur l’écriture de playbooks, nous avons vu comment construire l’arborescence d’un projet Ansible. Voici les emplacements principaux où vous pouvez définir des variables :
Répertoireprojet_ansible
Répertoireinventory
- hosts
Répertoiregroup_vars
- all.yml
- webservers.yml
Répertoirehost_vars
- server1.yml
- server2.yml
Répertoirefiles
- sample_file.txt
Répertoiretemplates
- service.j2
- ansible.cfg
- install_apache.yml
- configure_apache.yml
Déclaration de base
Les variables simples s’écrivent en YAML, sous forme de paires clé: valeur
. On
les définit généralement dans les blocs vars
du playbook.
- name: Exemple de playbook avec des variables simples hosts: all vars: http_port: 80 package_name: nginx tasks:
Utilisation de fichiers de variables
On peut séparer les variables dans un fichier YAML et les inclure dans un playbook :
- hosts: all vars_files: - vars/config.yml
Fichier vars/config.yml
:
timezone: Europe/Paris
Avec les --extra-vars
Les variables passées avec -e
sont utiles pour les surcharges dynamiques ou
dans les scripts d’automatisation :
ansible-playbook site.yml -e "app_env=production debug=false"
Dans l’inventaire (fichiers host_vars
et group_vars
)
group_vars/
Utile pour appliquer des variables à tous les hôtes d’un groupe.
Fichier group_vars/webservers.yml
:
http_port: 80nginx_enabled: true
host_vars/
Spécifique à un hôte individuel.
Fichier host_vars/web1.yml
:
hostname: web1.example.comdatacenter: paris
Ces fichiers sont automatiquement lus par Ansible si leur nom correspond à celui de l’hôte ou du groupe dans l’inventaire.
Précédence des variables
Lorsque des variables sont définies à plusieurs endroits, Ansible applique un ordre de priorité strict pour décider quelle valeur utiliser. C’est ce qu’on appelle la précédence des variables. Comprendre cette hiérarchie est essentiel pour éviter des comportements inattendus dans vos playbooks.
Quand une variable est définie plusieurs fois sous le même nom, Ansible garde
la valeur avec la priorité la plus haute. Par exemple, une variable passée
en ligne de commande via -e
l’emportera sur celle définie dans un fichier
defaults/main.yml
d’un rôle.
Voici les principales sources de variables, classées de la plus haute à la plus basse priorité :
- Variables extra (
--extra-vars
ou-e
) - Variables définies dans un playbook
- Variables dans
host_vars/
etgroup_vars/
- Facts collectés automatiquement
La précédence des variables permet à Ansible de rester flexible, mais elle nécessite une bonne organisation pour éviter les conflits et garder le contrôle sur les valeurs réellement utilisées pendant l’exécution.
Plus d’informations sur la précédence des variables ↗
Les différents types de variables
Les variables simples
Les variables sont la base de la personnalisation dans Ansible. Elles stockent une seule valeur : une chaîne de caractères, un nombre, un booléen ou une valeur nulle. Ces variables facilitent la maintenance et évitent la duplication d’informations dans les playbooks.
Les variables simples peuvent être de différents types :
-
Chaînes de caractères : Utilisées pour représenter du texte, elles peuvent être entourées de guillemets ou d’apostrophes.
server_name: "example.com" -
Nombres : Représentent des valeurs numériques, sans guillemets.
max_connections: 100 -
Booléens : Représentent des valeurs vraies (true) ou fausses (false), sans guillemets.
enable_ssl: true
Variables complexes
En plus des variables simples, Ansible permet d’utiliser des listes (arrays) et des dictionnaires (objets). Ces structures de données sont particulièrement utiles pour organiser des informations complexes, comme une liste de paquets à installer ou une configuration de service complète.
Les listes
Une liste est un ensemble de valeurs ordonnées. Elle se déclare avec un
tiret (-
) devant chaque élément :
packages: - nginx - php - mysql-server
On peut aussi écrire la liste sur une seule ligne :
packages: ["nginx", "php", "mysql-server"]
Les dictionnaires
Un dictionnaire (ou objet YAML) regroupe des paires clé/valeur. Il permet de structurer des données hiérarchiques :
mysql_config: user: root password: secret host: localhost port: 3306
Pour accéder à une valeur :
- name: Afficher le nom d’utilisateur ansible.builtin.debug: msg: "Utilisateur MySQL : {{ mysql_config.user }}"
Dictionnaires imbriqués
On peut combiner plusieurs niveaux pour décrire des services, des utilisateurs, ou des configurations complètes :
services: nginx: enabled: true port: 80 php: enabled: true version: "8.1" mysql: enabled: false databases: - nom: app_db user: app_user
Accès à un élément de dictionnaire imbriqué :
{{ services.nginx.port }}
Quand utiliser listes et dictionnaires ?
- Listes : plusieurs éléments similaires à traiter en boucle (paquets, services, chemins).
- Dictionnaires : structurer des configurations liées à une entité (base de données, utilisateur, application).
- hosts: all vars: users: - name: alice uid: 1001 - name: bob uid: 1002
tasks: - name: Créer les utilisateurs ansible.builtin.user: name: "{{ item.name }}" uid: "{{ item.uid }}" state: present loop: "{{ users }}"
Grâce aux listes et dictionnaires, vous pouvez décrire des systèmes complexes de manière lisible, modulaire et réutilisable. Ces structures sont fondamentales pour tirer pleinement parti d’Ansible dans vos playbooks.
Utilisation des variables
Une fois déclarées, les variables Ansible s’utilisent à travers la syntaxe
Jinja2, avec des doubles accolades : {{ variable }}
. Cette syntaxe permet
de référencer dynamiquement n’importe quelle variable dans un module, une
condition, un chemin de fichier ou même un nom de tâche. Leur usage dans les
tâches Ansible est central pour rendre les playbooks génériques, dynamiques et
réutilisables.
Utilisation dans les modules
C’est l’usage le plus courant : insérer une variable comme argument d’un module
Ansible. Voici un exemple avec ansible.builtin.apt
:
- name: Installer un paquet ansible.builtin.apt: name: "{{ package_name }}" state: present
Le nom du paquet sera injecté dynamiquement selon la valeur de package_name
.
Utilisation dans les noms de tâches
On peut rendre les noms de tâches plus lisibles en utilisant des variables :
- name: Redémarrer le service {{ service_name }} ansible.builtin.service: name: "{{ service_name }}" state: restarted
Cela permet de mieux suivre l’exécution du playbook selon les contextes. Attention les variables ne sont autorisées qu’à la fin du nom de la tâche.
Utilisation dans les chemins de fichiers
Ansible utilise des chemins souvent variables selon l’environnement. Vous pouvez injecter une variable dans un chemin :
- name: Créer un répertoire spécifique ansible.builtin.file: path: "/opt/{{ app_name }}/logs" state: directory
Variables spéciales : Les facts et variables magiques
Ansible propose des variables spéciales appelées facts et variables magiques. Ces informations sont automatiquement disponibles durant l’exécution d’un playbook. Elles permettent d’adapter les tâches à l’environnement cible sans avoir à tout définir manuellement.
Les facts Ansible : ansible_facts
Les facts sont des données collectées automatiquement sur un hôte distant :
version du système, interfaces réseau, mémoire, architecture, etc. Ansible les
collecte en début de playbook via le module setup
.
ansible all -m setup
...
"ansible_virtualization_tech_host": [], "ansible_virtualization_type": "lxc", "discovered_interpreter_python": "/usr/bin/python3.11", "gather_subset": [ "all" ], "module_setup": true }, "changed": false}
Vous pouvez aussi utiliser la syntaxe courte :
{{ ansible_distribution }}
Exemples courants de facts disponibles
ansible_hostname
: nom d’hôteansible_distribution
: type de distribution Linuxansible_memory_mb
: mémoire RAM en Moansible_processor
: architecture processeuransible_interfaces
: interfaces réseauansible_default_ipv4.address
: adresse IP principale
Contrôle de la collecte des facts
La collecte des facts se fait automatiquement, sauf si on la désactive :
- hosts: all gather_facts: false
Pour la récupérer manuellement, on peut appeler le module setup
:
- name: Récupérer les facts ansible.builtin.setup:
Par défaut, Ansible collecte tous les facts, mais vous pouvez restreindre cette collecte pour améliorer les performances, surtout sur de nombreux hôtes.
- name: Collecter uniquement les facts de base ansible.builtin.setup: gather_subset: - network
Enregistrer la sortie de tâches (register
)
Ansible permet de capturer le résultat d’une tâche dans une variable à
l’aide de l’instruction register
. Cela permet de réutiliser la sortie dans
une autre tâche, de faire des vérifications, ou de prendre des décisions
conditionnelles.
- name: Lister les fichiers ansible.builtin.command: ls /etc register: liste_etc
Structure de la variable enregistrée
La variable enregistrée contient plusieurs champs : stdout
, stderr
, rc
,
changed
, failed
, etc.
Voici les principales clés accessibles :
stdout
: sortie standardstderr
: sortie d’erreurrc
: code retour (0 = succès)changed
: booléen indiquant si une modification a eu lieufailed
: booléen indiquant l’échec
On peut ensuite afficher ou utiliser le contenu :
- name: Afficher le résultat ansible.builtin.debug: msg: "Contenu : {{ liste_etc.stdout }}"
Bonnes pratiques d’utilisation des variables
L’usage des variables dans Ansible est puissant, mais sans discipline, il peut rapidement rendre un projet difficile à maintenir, voire exposer des données sensibles. Voici une série de bonnes pratiques pour organiser, sécuriser et utiliser efficacement vos variables dans vos playbooks.
Séparer les variables sensibles avec Ansible Vault
Les mots de passe, tokens API ou clés SSH ne doivent jamais être stockés en clair dans vos fichiers YAML. Utilisez Ansible Vault pour chiffrer les fichiers contenant des informations confidentielles.
Masquer les sorties sensibles avec no_log
Quand vous utilisez une variable contenant une donnée confidentielle dans une
tâche, masquez sa sortie dans les logs grâce à l’option no_log
:
- name: Envoyer un mot de passe ansible.builtin.debug: msg: "Mot de passe : {{ password }}" no_log: true
Cela empêche Ansible d’écrire cette information dans la sortie standard et dans les fichiers de log.
Nommer les variables de façon explicite
Un bon nom de variable doit être compréhensible et explicite. Utilisez le
format snake_case
, et évitez les abréviations ambiguës :
- Préférer :
db_root_password
,webserver_port
,enable_tls
- Éviter :
pw
,x
,var1
,port1
Utiliser des fichiers séparés pour les environnements
Organisez vos variables par environnement : dev
, staging
, prod
, en créant
des fichiers distincts :
group_vars/ all.yml dev.yml prod.yml
Puis sélectionnez le bon fichier depuis la ligne de commande.
Limiter l’usage de set_fact
set_fact
est utile pour définir dynamiquement une variable pendant
l’exécution, mais son usage excessif peut brouiller la lisibilité du playbook.
Préférez l’usage des vars
et des conditions déclaratives.
Documenter les variables importantes
Ajoutez des commentaires dans vos fichiers de variables pour expliquer leur rôle :
db_port: 5432 # Port de la base PostgreSQLapi_timeout: 30 # Timeout en secondes pour les appels API
Vérifier les variables manquantes
Pour éviter les erreurs silencieuses, vous pouvez forcer l’échec si une variable est absente :
- name: Échouer si une variable n’est pas définie ansible.builtin.assert: that: - db_user is defined - db_password is defined
Conclusion
L’application rigoureuse de ces bonnes pratiques garantit la clarté, la sécurité et la robustesse de vos automatisations Ansible. En particulier dans les environnements professionnels, elles sont indispensables pour travailler en équipe et déployer en toute confiance.
Conclusion
Les variables Ansible sont un outil puissant pour rendre vos playbooks dynamiques, réutilisables et faciles à maintenir. En comprenant comment les définir, les organiser et les utiliser efficacement, vous pouvez automatiser des tâches complexes tout en gardant une structure claire et lisible.