Les templates Jinja avec Ansible
Jinja2 est un système de templates puissant qui peut être utilisé directement dans vos playbooks, via les filtres, mais aussi pour générer des fichiers dynamiquement.
En effet, Ansible permet, via le système de template Jinja, de créer des documents dans lesquels une partie du contenu peut être remplacé dynamiquement. Les fichiers résultants peuvent être au format HTML, JSON, XML ou tout ce qui utilise du texte pur comme encodage. On peut ainsi générer des fichiers de configuration, des documents, des fichiers de ligne de commandes, …
Utilisation des templates Jinja2 dans vos playbooks Ansible
Les modèles Jinja2 sont de simples fichiers textes contenant des variables qui sont remplacées par les valeurs définies lors de l’éxecution du module template d’Ansible. Ces données peuvent être celles définies dans des inventaires Ansible, dans des variables ou bien encore collectées lors de l’éxécution du playbook.
Les fichiers de templates jinja2 utilisent, en plus des variables et expressions, des balises qui permettent de contrôler la logique du document. La syntaxe utilise des délimiteurs qui sont du type suivant:
- {{ … }}pour les variables, comme dans les playbooks
- {% … %}pour les instructions de contrôle: if, for, raw, block, …
- {# … #} pour les commentaires qui ne seront pas inclus le fichier résultat
- # … ## pour les instructions de ligne
Les filtres
Les filtres permettent de manipuler des variables. La syntaxe utilisée est la suivante :
Je vous ai déjà largement documenté les filtres disponibles dans les billets suivant 1 2 3
Par exemple pour définir une valeur par défaut :
Les conditions
Jinja2 utilise l’instruction conditionnelle de type if avec elif else. Une condition s’écrie comme suit :
Les tests
Les tests peuvent être utilisés pour contrôler le type d’une variable, qu’elle est définie, qu’un nombre est divisible par, qu’il est pair, …
Pour tester une variable ou une expression, vous ajoutez is
plus le nom du test après la variable.
Par exemple, pour savoir si une variable est définie :
Je ne vais pas vous en faite le listing, je vous renvoie plutôt sur la référence
Les boucles
Il est possible de boucler sur une liste d’éléments. Par exemple, pour afficher une liste d’utilisateurs fournie dans une variable appelée users :
Vous remarquez peut-être la variable interne loop.index
qui le compteur de la
boucle. Il existe d’autres qui permettent d’ajouter encore
plus de
logique à vos boucles.
Par exemple, nous voudrions que seuls les users dont l’index est pair soit imprimé, on fait à l’instruction jinja if :
Écriture d’un template Ansible
Prenons comme exemple un fichier de configuration ntp simplifié. Voici le template qui généra ce fichier de configuration.
Dans cet exemple, on retrouve un exemple d’utilisation :
- Des filtres avec
{{ ansible_managed | comment }}
qui produit une ligne de commentaire grâce au filtre| comment
indiquant que ce fichier a été généré par Ansible. - Des conditions avec l’instruction
{% if ... %} .. {% endif %}
. - Des boucles avec l’instruction
{% for item ... %} {{ item }} {% endfor %}
.
Qui peut être utilisé via ce playbook ansible :
Cet exemple produit un fichier en local /tmp/ntp.conf
juste pour illustrer la
logique des templates Ansible !
Pour lancer ce playbook:
Qui produit le fichier :
Gérer les espacements et les retours à la ligne
Si vos fichiers produits doivent respecter des règles strictes d’espacement ou de retour, Ansible permet de contrôler l’impression via des paramètres suivants :
- lstrip_blocks : les espaces et les tabulations au début des variables sont supprimés
- trim_blocks : si défini à yes les nouvelles lignes après la suppression d’un bloc.
Vous pouvez aussi utiliser des caractères de contrôle manuel pour modifier la gestion d’un espace autour d’un bloc.
{%- if … %} vire la ligne avant {%+ if … %} garde la ligne avant {%+ if … -%} garde la ligne avant mais vire celle après
Par exemple dans notre exemple la variable ntp_tinker_panic
est définie à false
mais dans le fichier généré, on se retrouve avec une ligne vide. Si vous ne voulez
pas de cette ligne, vous pourriez soit :
- Utiliser cette syntaxe dans votre template :
- Utiliser les paramètres dans le playbook :
D’autres paramètres
Conserver les anciens fichiers
Il est possible de demander à Ansible de conserver les fichiers en les horodatant :
Forcer l’encodage
Il est possible de forcer l’encodage d’un fichier avec le paramètre :
output_encoding
: utf-8
par défaut
Si vous voulez plus de tutorials Ansible je vous renvoie sur le billet de l’introduction à ansible