
Comprendre la précédence des variables Ansible
Introduction
La gestion des variables Ansible peut s'avérer complexe en raison du nombre de possibilité de déclaration et leur emplacement.
ça peut entraîner des erreurs de configuration et des déploiements KO si l'ordre de priorité n'est pas correctement compris.
Cet article décrypte comment définir et prioriser les variables dans Ansible pour garantir des configurations justes.
Les sources de variables dans Ansible
Ansible permet de définir des variables à plusieurs endroits, chacune ayant un niveau de priorité. En tout, il y en a 22 !!
On ne va pas toutes les lister mais les principales. La liste complète est disponible dans la documentation officielle. (par ordre de priorité) :
- Variables defaults des roles : Ce sont les variables définies dans
defaults/main.ymld'un role. Comme son nom l'indique, ce sont les valeurs pa rdéfaut pour éviter une erreur au lancement. - Variables d'inventaire : Elles incluent les variables dans les fichiers
group_varsethost_vars. - Variables d'inventaire hiérarchisé : Les groupes d'inventaire enfants surchargent les variables des groupes parents.
- Facts : Ces valeurs sont obtenues via le module
setupou les facts personnalisés. - Variables définies dans un playbook : Les variables ajoutées directement dans un playbook sous la section
vars. - Variables vars de roles : Ce sont les variables définies dans
vars/main.ymldu role. - Variables passées via la ligne de commande : Celles définies avec l'option
-elors de l'exécution d'un playbook. Elles ont toujours la priorité maximale.
Savoir ou positionner ses variables
Prenons un scénario simple pour illustrer ça. Imaginons qu'on doive configurer une application web avec un port d'écoute, et que ce port (app_port) est défini à différents niveaux :
Variables par défaut des roles
Dans defaults/main.yml d'un role nommé web_app :
1defaults:
2 app_port: 8080
3Variables d'inventaire
Dans group_vars/webservers.yml :
1app_port: 9090
2Variables d'inventaire dans un groupe enfant (children)
Dans group_vars/production.yml, supposons que le groupe production est enfant de webservers :
1app_port: 7070
2Variables dans un playbook
Dans le playbook principal :
1- name: Deploy application
2 hosts: webservers
3 vars:
4 app_port: 8000
5 roles:
6 - web_app
7Variables passées via la ligne de commande
Lors de l'exécution d'Ansible :
1ansible-playbook deploy.yml -e "app_port=6060"
2Résultat
L'ordre de priorité détermine la valeur finale de app_port :
- 8080 (defaults) est surchargé par 9090 (inventaire de
webservers). - 9090 est surchargé par 7070 (inventaire du groupe
production). - 7070 est ensuite surchargé par 8000 (playbook).
- 8000 est finalement surchargé par 6060 (ligne de commande).
La valeur finale utilisée sera donc 6060.
Gestion des inventaires multi-sources et ordre ASCII
Lorsqu'on utilise des inventaires multi-sources, par exemple avec un inventaire dynamique et un statique, Ansible applique un ordre ASCII pour déterminer quelles variables sont chargées en premier. Par exemple, si vous avez les fichiers suivants dans votre répertoire d'inventaire :
group_vars/01-aws.ymlgroup_vars/10-static.yml
Ansible charge les variables de 01-aws.yml avant celles de 10-static.yml. ça signifie que les variables définies dans 10-static.yml prendront la priorité sur celles de 01-aws.yml. Pour exploiter cet ordre, il est recommandé de nommer vos fichiers avec un préfixe numérique ou alphabétique qui reflète leur priorité.
Exemple pratique
Dans group_vars/01-aws.yml :
1app_port: 8080
2environment: development
3Dans group_vars/10-static.yml :
1app_port: 9090
2environment: production
3Si vous exécutez un playbook dans le contexte de l'inventaire global, la valeur finale de app_port sera 9090, car 10-static.yml est chargé après 01-aws.yml.
Tests et validation des variables
Pour s'assurer que les variables sont correctement résolues, on peut utiliser le module debug dans un playbook. Par exemple :
1- name: Debug variable app_port
2 hosts: webservers
3 tasks:
4 - debug:
5 msg: "La valeur de app_port est {{ app_port }}"
6Détails supplémentaires sur les sources de variables
Variables par défaut des roles
Les variables dans defaults/main.yml sont pratiques pour définir des valeurs génériques. Elles ne doivent pas contenir de valeurs critiques ou sensibles, car elles sont facilement surchargées.
Pour autant, même si vous savez que la valeur par défaut ne servira jamais, je recommande de les noter, ne serait-ce qu'à des fins de documentations pour l'exhaustivité des variables.
Variables d'inventaire
Les fichiers dans group_vars et host_vars permettent de personnaliser les variables selon des groupes ou des hôtes spécifiques. Exemple :
- Dans
group_vars/webservers.yml:yaml1app_port: 9090 2environment: production 3 - Dans
host_vars/web1.yml:yaml1app_port: 8081 2
Si un hôte appartient au groupe webservers, mais qu'il a aussi une configuration dans host_vars, la configuration dans host_vars a la priorité.
Ansible Facts
Les facts sont des données dynamiques collectées via le module setup. Par exemple :
1ansible web1 -m setup
2ça retourne des informations sur la machine cible, comme l'adresse IP, la mémoire, etc. Ces facts peuvent être utilisés dans vos playbooks :
1ansible_default_ipv4.address
2Variables passées via la ligne de commande
Les variables définies avec l'option -e (extra-vars) ont la priorité maximale. Je ne les utilise quasi jamais car ne rentrent pas dans l'idéal d'un modèle GitOps.
Quelques conseils pour vos variables
-
Visualisez l'ordre :
- Placez les valeurs génériques dans
defaults/main.yml. - Utilisez
group_varspour des configurations partagées par plusieurs hôtes. - Spécifiez les détails propres à un hôte dans
host_vars.
- Placez les valeurs génériques dans
-
Privilégiez la lisibilité :
- Documentez chaque variable pour qu'on comprenne son objectif.
-
Testez vos configurations :
- Exécutez des tests avec le module
debugpour valider les valeurs des variables.
- Exécutez des tests avec le module
-
Réduisez les surcharges inutiles :
- Essayez de ne pas définir la variable à plusieurs endroits, ou supprimez les anciennes références.