Un fichier à trous et une alerte unique
Un modèle Jinja2 est un fichier à trous : Ansible remplit les trous avec des variables pour fabriquer le fichier final. Un handler est une tâche qui ne tourne que si une autre a vraiment changé quelque chose, et une seule fois.
Le restaurant universitaire veut une carte du jour fabriquée depuis une liste de plats, et sa cuisine prévenue une fois par changement, pas trois.
À la fin de cette leçon
Remarque
Je peux remplir un modèle Jinja2 à partir de variables et faire tourner un handler une seule fois.
Mots-clés
| Mot | Ce que ça veut dire | Exemple |
|---|---|---|
| Modèle | un fichier à trous que l’outil remplit avec des variables | menu.conf.j2 |
| Jinja2 | le langage des trous d’un modèle Ansible | {{ lieu }} |
| Condition if | garde un morceau du modèle seulement si une valeur est vraie | |
| Boucle for | répète un morceau du modèle pour chaque élément d’une liste | |
| Handler | une tâche qui attend d’être prévenue par une autre | |
| notify | le mot qui prévient un handler quand une tâche a changé quelque chose |
Les cellules que les étudiants remplissent restent vides dans cet aperçu.
Un modèle est un fichier à trous
Dans un modèle, {{ lieu }} est un trou : Ansible met la valeur de la variable lieu. {% if menu_vegetarien %} garde les lignes qui suivent seulement si la variable est vraie. {% for plat in plats %} les répète pour chaque plat.
La tâche template écrit le fichier fini. Rejouée sans rien changer, elle ne réécrit rien : le fichier est déjà bon.
Les valeurs du rôle et son modèle
# roles/menu/defaults/main.yml
lieu: Resto U
tarif: 4
menu_vegetarien: true
plats: [salade, gratin, fruit]
# roles/menu/templates/menu.conf.j2
restaurant = {{ lieu }}
prix = {{ tarif }}
{% if menu_vegetarien %}
choix_vegetarien = oui
{% endif %}
{% for plat in plats %}
plat.{{ loop.index }} = {{ plat }}
{% endfor %}
Créer le dossier du fichier fabriqué
mkdir -p ~/atelier-ansible/sortieAffichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Aller dans le projet
cd ~/atelier-ansibleAffichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Créer les dossiers du rôle
mkdir -p roles/menu/defaults roles/menu/templates roles/menu/tasks roles/menu/handlersAffichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Écrire les valeurs par défaut
printf 'lieu: Resto U\ntarif: 4\nmenu_vegetarien: true\nplats: [salade, gratin, fruit]\n' > roles/menu/defaults/main.ymlAffichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Écrire le modèle
printf 'restaurant = {{ lieu }}\nprix = {{ tarif }}\n{%% if menu_vegetarien %%}\nchoix_vegetarien = oui\n{%% endif %%}\n{%% for plat in plats %%}\nplat.{{ loop.index }} = {{ plat }}\n{%% endfor %%}\n' > roles/menu/templates/menu.conf.j2Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Écrire la tâche qui fabrique le fichier
printf -- '- name: Ecrire le menu\n ansible.builtin.template:\n src: menu.conf.j2\n dest: "{{ dossier }}/menu.conf"\n mode: "0644"\n' > roles/menu/tasks/main.ymlAffichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Écrire le jeu qui appelle le rôle
printf -- '- hosts: localhost\n gather_facts: false\n vars:\n dossier: /home/student/atelier-ansible/sortie\n roles:\n - menu\n' > menu.ymlAffichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Jouer le rôle et lire le bilan
ansible-playbook -i localhost, -c local menu.yml | grep ^localhostAffichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Lire le fichier fabriqué
cat sortie/menu.confAffichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Rejouer sans rien changer
ansible-playbook -i localhost, -c local menu.yml | grep ^localhostAffichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Erreur fréquente
Attention
Beaucoup de gens écrivent -e menu_vegetarien=false pour éteindre une option. Mais Ansible reçoit alors le texte « false », qui est vrai pour un if : rien ne change. Passez un vrai booléen avec la forme JSON : -e '{"menu_vegetarien": false}'.
Donner « false » comme texte
ansible-playbook -i localhost, -c local menu.yml -e menu_vegetarien=false | grep ^localhostAffichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Donner un vrai booléen
ansible-playbook -i localhost, -c local menu.yml -e '{"menu_vegetarien": false}' | grep ^localhostAffichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Un handler tourne une fois, à la fin
Une tâche peut dire notify: Prevenir la cuisine. Si elle a changé quelque chose, le handler de ce nom est mis en attente. S’il est prévenu dix fois, il attend une seule fois.
Il tourne à la fin du jeu, et pas du tout si rien n’a changé. Le handler de cette leçon affiche un message : il ne redémarre aucun service.
Écrire deux tâches qui préviennent
printf -- '- name: Ecrire le menu\n ansible.builtin.template:\n src: menu.conf.j2\n dest: "{{ dossier }}/menu.conf"\n mode: "0644"\n notify: Prevenir la cuisine\n\n- name: Ecrire la carte du jour\n ansible.builtin.copy:\n content: "nombre de plats : {{ plats | length }}\\n"\n dest: "{{ dossier }}/carte.txt"\n mode: "0644"\n notify: Prevenir la cuisine\n' > roles/menu/tasks/main.ymlAffichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Écrire le handler
printf -- '- name: Prevenir la cuisine\n ansible.builtin.debug:\n msg: la cuisine est prevenue\n' > roles/menu/handlers/main.ymlAffichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Changer les plats et compter le handler
ansible-playbook -i localhost, -c local menu.yml -e '{"plats": ["soupe", "tarte"]}' | grep -c "RUNNING HANDLER"Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Rejouer avec les mêmes plats
ansible-playbook -i localhost, -c local menu.yml -e '{"plats": ["soupe", "tarte"]}' | grep -c "RUNNING HANDLER"Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Pour aller plus loin
Ajoutez une tâche meta: flush_handlers entre les deux tâches du rôle. Changez les plats et comptez les lignes RUNNING HANDLER.
Combien de fois le handler tourne-t-il, et pourquoi ? Expliquez ce que cela change pour une tâche qui a besoin du travail du handler.