Définir des variables pour vos playbooks et rôles Ansible peut devenir difficile à mesure que votre projet se développe.
Parcourir le Documentation ansiblela diversité de l’emplacement des variables Ansible est pour le moins déroutante :
- valeurs de ligne de commande (par exemple,
-u my_user
ce ne sont pas des variables) - valeurs par défaut du rôle (définies dans
role/defaults/main.yml
) - fichier ou script d’inventaire
group_vars
- inventaire
group_vars/all
- livre de jeu
group_vars/all
- inventaire
group_vars/*
- livre de jeu
group_vars/*
- fichier ou script d’inventaire
host_vars
- inventaire
host_vars/*
- livre de jeu
host_vars/*
- héberger
facts
/ mis en cacheset_facts
- jouer à vars
- jouer
vars_prompt
- jouer
vars_files
- variables de rôle (définies dans
role/vars/main.yml
) - block vars (uniquement pour les tâches en bloc)
- variables de tâche (uniquement pour la tâche)
include_vars
set_facts
/ variables enregistrées- rôle (et
include_role
) paramètres - inclure les paramètres
- variables supplémentaires (par exemple,
-e "user=my_user"
)(toujours gagner la priorité)
Il y a 22 endroits différents où stocker vos variables ! Au fur et à mesure que votre code évolue et devient plus complexe, il peut devenir désordonné.
Définissez votre propre sous-ensemble d’emplacements de variables
La manière simple
Chaque fois que vous pensez à une variable, il devrait être évident où elle est définie. Si ce n’est pas le cas, vous diffusez peut-être vos variables dans trop d’endroits. Commencez par quelque chose de simple, par exemple n’avoir que 2 endroits où vos variables peuvent être définies :
- valeurs par défaut du rôle (définies dans role/defaults/main.yml)
- paramètres de rôle (et include_role)
roles/serviceA/default.yml
: ce fichier définit tout variables requises par le rôle, avec quelques valeurs par défaut. Notez comment nous pouvons commenter les variables requises, mais pour lesquelles nous ne voulons pas fournir de valeur par défaut. Ce faisant, nous documentons chaque variable dont le rôle a besoin.
servicea_log_dir: /var/log/servicea
servicea_autorestart: yes
serviceA.yml
: ce fichier est le playbook dans lequel le rôle est appelé. Nous mettons notre Douane configuration là-bas.
- hosts: groupa
roles:
- role: serviceA
vars:
servicea_user: gollum
servicea_autorestart: no
Nous avons choisi 2 emplacements pour notre projet : role defaults, et role params. Il est facile de savoir où trouver notre variable. Cela devrait fonctionner dans la plupart des situations.
Une méthode plus générique
Prenons un autre sous-ensemble d’emplacements.
- valeurs par défaut du rôle (définies dans role/defaults/main.yml)
- inventaire group_vars/*
roles/serviceA/default.yml
: rôles par défaut, définis de la même manière que dans l’exemple précédent.
servicea_log_dir: /var/log/servicea
servicea_autorestart: yes
inventory/group_vars/servicea.yml
: ces variables vont être associées au groupe appelé servicea
servicea_user: gollum
servicea_autorestart: no
Il est ensuite nécessaire d’associer correctement le rôle aux hôtes dont vous avez défini les variables (rappel : à l’exécution, les variables sont finalement associées à un hôte : il n’y a pas de groupe ou de rôle par défaut, uniquement des variables d’hôte). Le livret de jeu :
- hosts: servicea
roles:
- role: serviceA
Supposons maintenant que nous voulions avoir plusieurs rôles, servicea
et serviceb
pour s’exécuter sur un groupe appelé par exemple worker
. Nous pourrait écrire la configuration personnalisée pour les deux services (servicea
et serviceb
) dans un seul fichier : inventory/group_vars/worker.yml
; mais alors il n’est vraiment pas évident où trouver vos variables personnalisées.
Au lieu de cela, nous pouvons avoir 1 groupe par service, donc 1 fichier de configuration par service dans le group_vars
dossier (servicea.yml
et serviceb.yml
). On associe alors le worker
héberge au groupe de nos différents services. inventory/hosts
:
[worker]
worker01.local
worker02.local
worker03.local
worker04.local
[servicea:children]
worker
[serviceb:children]
worker
Un mauvais chemin
Prenons simplement les 2 exemples précédents et mélangeons-les. Nous choisissons 3 emplacements :
- valeurs par défaut du rôle (définies dans role/defaults/main.yml)
- inventaire group_vars/*
- paramètres de rôle (et include_role)
Disons que nous voulons modifier servicea_log_dir
variable. Nous ne pouvons pas modifier la variable par défaut du rôle, car nous voulons notre propre valeur personnalisée. Changeons-nous maintenant dans le group_vars
ou dans les paramètres de rôle? Les deux fonctionnent, et il n’y a aucun moyen de déterminer quel emplacement vous choisiriez, à moins qu’il n’y ait une logique spécifique derrière cela. Ce n’est pas correct et nous voulons garder les choses simples.
Pensez aux gitops
Lorsque vous choisissez les quelques emplacements à utiliser, pensez à l’effet que cela aura sur votre version de code.
La méthodologie gitops peut vous aider. En bref, vous souhaitez diviser votre code en 2 référentiels : votre référentiel de code et votre référentiel ops.
En l’appliquant à Ansible, votre référentiel de code est l’endroit où vous versionnez vos rôles ou votre Collections Ansible. Votre référentiel ops est l’endroit où vous versionnez tout ce qui est spécifique à une instance de votre code ; à savoir votre inventaire et vos variables personnalisées.
Lorsque vous utilisez la méthode simple, vous devrez versionner vos playbooks dans votre référentiel ops, car ils contiennent vos variables personnalisées. Lorsque vous utilisez la deuxième méthode que nous avons décrite, où chaque variable personnalisée se trouve dans le groupe d’inventaire vars, vous ne pouvez versionner que l’inventaire dans votre référentiel ops.
L’important est qu’il soit possible de scinder le code générique et les propriétés propres à une instance. Par exemple, stocker des variables personnalisées dans le vars
dossier d’un rôle (par ex. roles/servicea/vars/main.yml
) n’est pas correcte.
Si vous pensez à une variable et savez avec certitude où elle a été définie, alors vous faites probablement les choses correctement.