Fonctionnement d’un playbook
Objectifs du chapitre et prérequis
1. Contexte et prérequis
Si vous êtes arrivé à ce niveau du livre, vous devez avoir abordé les points suivants :
-
Configurer la communication avec les machines distantes (clé SSH).
-
Avoir des notions sur le fonctionnement des inventaires.
-
Connaître quelques notions sur l’utilisation de ces derniers.
-
Avoir vu comment fonctionne un playbook simple.
Ce chapitre est là pour reprendre tous ces éléments et aller plus loin dans la compréhension d’Ansible.
2. Fichiers téléchargeables
Vous pouvez récupérer les exemples des répertoires inventaires et variables sur le repository GitHub suivant : https://github.com/EditionsENI/ansible
Vous pouvez également récupérer ces fichiers dans l’archive chapitre-06.tar.gz depuis la page Informations générales.
Le moteur de template Jinja : principe de fonctionnement
Dans les exemples qui vont suivre, vous allez voir comment utiliser Ansible pour récupérer les informations qui caractérisent les machines afin de les répertorier. Vous aurez besoin pour cela d’aborder le fonctionnement du moteur Jinja.
Jinja est un moteur de template écrit en Python. Il est inspiré du moteur Django tout en restant plus simple dans son utilisation. Le principe est le suivant : un canevas va contenir toute la mise en page. Jinja charge ce patron et réalise la substitution des champs en fonction du contexte d’exécution.
On utilise généralement ce genre d’outil pour afficher une information dans une page web en fonction de variables (information sur un utilisateur, affichage de la date du jour, etc.). Pour bien comprendre comment fonctionne ce type de moteur, prenez le cas d’une page HTML présentant le nom d’une machine :
<html>
<head>
<title>Machine rec-apache-1</title>
</head>
<body>
<p>Cette machine s'appelle rec-apache-1</p>
</body>
</html>
Vous y retrouvez le nom de la machine à deux endroits distincts : dans la balise titre de la page (balise <title>...</title>) et dans le paragraphe (balise <p>...</p>) du corps de la page (balise <body>...</body>).
Imaginez maintenant que le nom de la machine soit stocké dans la variable inventory_hostname. Pour rendre la page précédente générique...
Template Jinja
Vous avez vu un mécanisme simple qui permet de générer des fichiers sur la machine locale en partant des informations de l’inventaire. Vous allez maintenant voir comment utiliser les informations remontées par le module setup (champ gather_facts des playbooks). Vous vous servirez ensuite de ces variables dans la génération du template.
Vous allez pour cela aborder plusieurs points :
-
Savoir réaliser une boucle avec un template Jinja.
-
Trouver la variable Ansible remontée par le module setup (nom complet ansible.builtin.setup) contenant ce qui vous intéresse.
-
Comprendre comment lancer les modules aux bons endroits avec l’option connection.
1. Mécanisme de boucle sur tableau avec Jinja
Sous Jinja, une boucle se déclare avec les éléments suivants :
-
Le mot-clé for.
-
Le nom de la variable d’itération.
-
Le mot-clé in.
-
Le tableau sur lequel vous allez itérer.
Ci-dessous un exemple de ce type de boucle :
{% for element in liste_element %}
Le contenu de la variable element est le suivant : {{element}}
{% endfor %}
Ici la variable liste_element sera un tableau d’éléments. Chaque élément générera une ligne.
Comme vous l’avez vu plus tôt, en plus des tableaux, vous pouvez également utiliser des tableaux de hachage. Dans ce cas, il faudra :
-
faire appel à la fonction items du tableau de hachage ;
-
remplacer la variable d’itération simple par un couple de variables clé/valeur.
Ci-dessous un exemple simple de ce type de déclaration :
{% for cle, valeur...
Délégation de tâche
En voulant récupérer des informations sur les différentes machines, on a en réalité récupéré celles en provenance de la machine qui a lancé Ansible.
Rassurez-vous, il est bien sûr possible de récupérer des informations sur les machines distantes avant de s’en servir en local. Pour cela, vous allez aborder la notion de plugin de connexion (ssh ou local) ainsi que la délégation (option delegate_to).
1. Changement du type de connexion au niveau d’une tâche
Revenons sur l’erreur que vous avez constatée sur la liste des adresses IP. Celle-ci est toute simple et vient du champ connection: local que vous avez positionné au niveau global du playbook. En réalité, vous aimeriez que l’opération gather_facts se passe sur les différentes machines de l’inventaire et que seule la dépose du fichier se fasse en local.
Dans ce cas, vous allez simplement déplacer le champ connection du précédent playbook au niveau de l’instruction template et laisser le reste se faire avec les valeurs par défaut (dans le cas présent, ça sera du SSH). En appliquant ces modifications, le code va ressembler à ce qui suit :
- name: "Generate html file for each host"
hosts: all
gather_facts: yes
tasks:
- name: "html file generation"
template:
src: "machine.html.j2"
dest:...
Gestion d’un serveur Apache
Le playbook de centralisation des informations sur les serveurs est maintenant terminé. Ce dernier est parfaitement fonctionnel pour peu que le serveur Apache sur lequel se trouve l’inventaire soit démarré et déjà configuré.
Vous allez maintenant voir comment réaliser l’installation du serveur Apache sur la machine qui vous servira de référentiel.
Première chose, vous n’allez pas installer Apache sur toutes les machines de l’inventaire, mais seulement sur la machine de centralisation. Pour cela, vous allez devoir procéder comme suit :
-
Modifier l’inventaire afin d’ajouter un groupe inventory dans lequel vous ajouterez la machine central-inventory.
-
Au niveau du playbook, le champ hosts prendra la valeur inventory.
Le playbook modifiera la configuration du serveur Apache afin d’autoriser les accès sur le répertoire inventaire. Ci-dessous l’extrait de la configuration Apache qui va réaliser cette opération :
Alias /inventaire /var/www/html/inventory
# Donne des droits d'accès à tout le monde
<Directory /var/www/html/inventory/>
Order Allow,Deny
Allow from All
</Directory>
Pour déposer ce fichier, l’instruction template prendra en paramètre les options suivantes :
-
Le nom du template (src: inventory.conf.j2)
-
L’emplacement du fichier de configuration (dest: /etc/http/conf.d/inventory.conf)
-
Le propriétaire du fichier (owner: apache et group: apache)
Reprenez le fichier install-apache.yml du chapitre Utilisation d’Ansible. Appliquez-y...
Réduction des opérations impactantes
De manière générale, il faut réduire au maximum les opérations inutiles. Parmi ces opérations, les arrêts/relances sont une source d’indisponibilité de service ou de perte de temps. Dans le cas présent, il n’y a pas de grosses conséquences à faire cet arrêt/relance. En revanche, ce point peut devenir gênant dans le cas d’une application à disposition d’utilisateurs.
Dans la suite, vous aborderez deux techniques permettant de réduire la fréquence de ces opérations :
-
via l’utilisation de tags ;
-
par l’utilisation de variables et le conditionnement du lancement d’opérations ;
-
par un mécanisme de handler.
1. Mécanisme des tags
Une première façon d’exclure une tâche d’un flot d’exécutions est de passer par les tags. Les tags peuvent se définir à plusieurs niveaux :
-
sur le playbook en lui-même ;
-
au niveau d’une tâche.
a. Déclaration d’un tag
L’ajout d’une annotation se fait avec le champ tag. Si vous ajoutez un tag restart sur la tâche de redémarrage du service Apache, le code de la tâche prendra la forme suivante :
- name: "Start apache service"
service:
name: "httpd"
state: "restarted"
enabled: yes
tags: [ "restart" ]
b. Comment lister les tags d’un playbook ?
Pour obtenir la liste des tags à disposition sur un playbook...