Les filtres Jinja avancés
Mise à jour :
Dans ce guide, nous allons explorer l’utilisation des filtres Jinja dans Ansible, qui sont essentiels pour manipuler, transformer et valider les variables dans vos playbooks et templates. Ces filtres permettent d’adapter les données selon vos besoins, que ce soit pour formater des chaînes de caractères, gérer des listes, ou sécuriser des informations sensibles. Grâce à eux, vous pouvez gérer les configurations dynamiques de manière plus flexible et efficace.
Dans notre précédent guide sur les templates Jinja, nous avons vu comment utiliser des concepts comme les inclusions, les conditions et les boucles dans Ansible. Ici, nous allons approfondir l’utilisation des filtres, afin de vous montrer comment optimiser le traitement des données dans vos playbooks. Qu’il s’agisse de gérer des valeurs par défaut, d’utiliser des filtres conditionnels ou de transformer des données complexes, les filtres Jinja offrent une large palette d’outils pour rendre vos configurations Ansible plus puissantes.
Pourquoi les filtres sont-ils importants ?
Les filtres Jinja permettent non seulement de formater et transformer des données, mais aussi de s’assurer que celles-ci sont correctement manipulées avant d’être utilisées dans vos tâches Ansible. Par exemple, ils vous permettent de valider des valeurs, de convertir des types, ou encore de combiner des données issues de différentes sources. Ils sont essentiels pour éviter les erreurs liées aux variables non définies ou mal configurées.
Gestion des valeurs non définies
Dans vos playbooks Ansible, il arrive souvent que certaines variables ne soient pas définies ou ne contiennent aucune valeur. Cela peut entraîner des erreurs lors de l’exécution, comme des échecs liés à des variables manquantes ou des comportements inattendus. Heureusement, les filtres Jinja offrent des moyens simples de gérer ces situations, en fournissant des valeurs par défaut, en rendant des variables facultatives, ou en définissant certaines variables comme obligatoires.
Définir des valeurs par défaut
L’une des solutions les plus simples pour éviter les erreurs liées aux variables
non définies est d’utiliser le filtre default
. Ce filtre permet de
spécifier une valeur par défaut à utiliser si la variable n’est pas définie ou
est vide. Cela évite les interruptions dues à des variables manquantes tout en
assurant que le playbook continue de s’exécuter normalement.
Si la variable variable
n’est pas définie ou vide, Ansible utilisera
automatiquement la valeur par défaut spécifiée. Cela est particulièrement
utile pour les configurations où certaines valeurs peuvent varier selon
l’environnement, mais où vous souhaitez éviter d’écrire des valeurs spécifiques
pour chaque scénario.
Prenons l’exemple d’un fichier de configuration où vous devez définir un port pour un service. Si la variable correspondant au port n’est pas fournie, Ansible utilisera le port par défaut 8080 :
Si la variable port
n’est pas définie dans le playbook ou l’inventaire,
Ansible définira automatiquement le port à 8080 dans le fichier de
configuration.
Valeur par défaut dans les fichiers de rôle
Une autre approche consiste à définir des valeurs par défaut dans les fichiers
defaults/main.yml
d’un rôle. Cela permet de centraliser la définition des
variables par défaut au niveau du rôle et d’éviter d’avoir à les spécifier dans
les templates ou les tâches.
Exemple dans defaults/main.yml
:
Cela permet de toujours avoir une valeur de repli pour la variable port
,
même si elle n’est pas définie ailleurs dans le playbook ou l’inventaire.
Rendre les variables facultatives
Dans certains cas, vous pouvez souhaiter que certaines variables soient
facultatives. Si une variable facultative n’est pas définie, vous pouvez
utiliser le filtre omit
pour ignorer complètement une option ou un
paramètre dans une tâche.
Le filtre omit
permet de ne pas inclure un paramètre dans une tâche si la
variable n’est pas définie. Cela est particulièrement utile lorsque vous ne
voulez pas qu’Ansible utilise une valeur par défaut, mais plutôt qu’il
n’applique pas du tout le paramètre concerné.
Voici un exemple où le mode d’un fichier est optionnel. Si la variable
mode
n’est pas définie pour un fichier particulier, Ansible ignore le
paramètre :
Dans cet exemple, seuls les fichiers ayant un mode explicitement défini
l’appliqueront. Le fichier /tmp/foo
et /tmp/bar
seront créés sans
qu’un mode spécifique soit appliqué, tandis que /tmp/baz
aura le mode
0444
.
Définition des valeurs obligatoires
Dans certains cas, vous pouvez avoir des variables qui doivent être définies
pour que le playbook fonctionne correctement. Ansible permet de marquer
certaines variables comme obligatoires en utilisant le filtre
mandatory
. Si la variable n’est pas définie, Ansible générera une erreur
et arrêtera l’exécution du playbook.
Le filtre mandatory
force la validation d’une variable. Si la variable
n’est pas définie, Ansible renverra une erreur explicite et interrompra
l’exécution.
Cela garantit que la variable variable
est définie. Si elle ne l’est pas,
Ansible retournera une erreur “variable mandatory not defined”, vous aidant
ainsi à identifier rapidement les problèmes liés aux variables non spécifiées.
Imaginons un playbook où la configuration du mot de passe d’une base de données
est obligatoire. Le filtre mandatory
s’assurera que cette variable est
correctement définie avant de procéder à la tâche :
Si la variable db_password
n’est pas définie, le playbook s’arrêtera
immédiatement et Ansible vous alertera qu’une variable critique est manquante.
Définition de valeurs ternaires (vrai / faux / nul)
Pour éviter l’utilisation excessive de conditions if/else ou de blocs
set_fact
, vous pouvez utiliser le filtre ternary
dans les templates ou
les playbooks. Ce filtre permet de choisir entre deux valeurs en fonction d’une
condition et offre une manière concise de gérer des choix bivalents (comme
vrai/faux).
Le filtre ternary
vous permet de choisir entre deux options en fonction de
la valeur d’une variable ou d’une expression :
Dans cet exemple, si le statut est égal à needs_restart
, Ansible renverra
restart
. Sinon, il renverra continue
. Cela permet de traiter des cas
simples de manière élégante et concise sans écrire des conditions complexes.
Gestion des types de données
En travaillant avec Ansible, vous serez souvent confronté à des types de données variés comme les chaînes de caractères, les entiers, les listes, ou les dictionnaires. Bien que les données soient généralement bien gérées par Ansible, il est parfois nécessaire de manipuler ou forcer un type de donnée pour s’assurer que les variables sont utilisées correctement dans les tâches et les templates. Les filtres Jinja permettent d’inspecter et de transformer ces types de données selon vos besoins.
Dans cette section, nous allons explorer comment Ansible et Jinja vous permettent de gérer et de manipuler efficacement les types de données à travers plusieurs filtres spécifiques.
Afficher le type d’une variable
Avant de manipuler une variable, il peut être utile de connaître son type de donnée exact. Cela est particulièrement utile lorsque vous travaillez avec des variables provenant de sources externes, des inventaires dynamiques ou des modules, où le type peut ne pas être immédiatement évident.
Pour ce faire, le filtre type_debug
vous permet d’afficher le type Python
sous-jacent d’une variable.
Ce filtre retournera un résultat comme "str"
, "int"
, "list"
, ou "dict"
en fonction du type réel de la variable my_var
. Cela permet de valider
facilement si une variable est du type attendu avant de l’utiliser dans des
opérations spécifiques.
Si vous travaillez avec une liste d’adresses IP et que vous n’êtes pas sûr que
chaque variable soit effectivement une chaîne de caractères, vous pouvez
utiliser type_debug
pour valider le type :
Dans cet exemple, Ansible affichera que la variable ip_address
est de type
str
(chaîne de caractères).
Forçage du type
Il est parfois nécessaire de convertir explicitement le type d’une variable
pour assurer une exécution correcte des tâches. Ansible propose plusieurs
filtres Jinja pour forcer le type des variables, notamment int
,
float
, bool
, string
et list
. Cela est particulièrement
utile lorsque les données sont issues de fichiers de configuration,
d’inventaires externes, ou de systèmes tiers et qu’elles peuvent ne pas avoir
le format attendu.
Le filtre bool
est couramment utilisé pour convertir une variable en type
booléen (vrai ou faux). Cela est utile lorsque vous devez vérifier qu’une chaîne
de caractères ou un nombre se comporte comme un booléen dans des conditions.
Dans cet exemple, Ansible convertira la chaîne some_string_value
en un
booléen avant de vérifier la condition. Les chaînes comme "yes"
, "true"
,
"1"
, ou tout autre valeur non nulle seront interprétées comme true
,
tandis que les chaînes comme "no"
, "false"
, "0"
, ou des valeurs nulles
seront interprétées comme false
.
Conversion en entier avec int
Si vous devez utiliser des entiers dans des calculs ou des conditions, le
filtre int
vous permet de convertir une variable en nombre entier.
Ce filtre est particulièrement utile lorsque vous travaillez avec des variables
qui pourraient être des chaînes représentant des nombres. Par exemple, une
variable "42"
sera convertie en entier 42
.
Conversion en liste avec list
Le filtre list
est pratique lorsque vous devez convertir une chaîne de
caractères ou une autre structure de données en une liste utilisable.
Ce filtre prend chaque caractère de la chaîne et le place dans une liste. Par
exemple, la chaîne "hello"
deviendra ['h', 'e', 'l', 'l', 'o']
. Il est
également utile pour convertir des tuples ou des ensembles en listes.
Convertir des dictionnaires en listes et vice-versa
Dans Ansible, il est courant de travailler avec des dictionnaires et des listes. Parfois, il peut être nécessaire de convertir un dictionnaire en liste ou inversement, notamment lorsque vous devez itérer sur des éléments ou manipuler des données dans un format spécifique.
Convertir un dictionnaire en liste : dict2items
Le filtre dict2items
permet de transformer un dictionnaire en une
liste de paires clé/valeur. Cela est utile lorsque vous devez parcourir ou
manipuler un dictionnaire comme une liste.
Exemple de dictionnaire dans un fichier Ansible :
Pour convertir ce dictionnaire en liste avec dict2items
:
Le résultat sera une liste de paires clé/valeur comme ceci :
Cela est particulièrement utile pour parcourir des dictionnaires de manière itérative dans vos templates ou vos tâches.
Convertir une liste en dictionnaire : items2dict
Inversement, vous pouvez utiliser le filtre items2dict
pour convertir une
liste de paires clé/valeur en un dictionnaire. Cela est utile lorsque
vous travaillez avec des données sous forme de liste, mais que vous devez les
utiliser comme un dictionnaire dans Ansible.
Exemple d’utilisation :
En appliquant items2dict
, cela devient :
Quelques Filtres sur les chaines de caractères
Les filtres Jinja offrent plusieurs outils pour manipuler du texte dans Ansible, que ce soit pour ajouter des commentaires à des fichiers, formater des chaînes, ou encoder/décoder des valeurs.
Expressions régulières
Les expressions régulières sont indispensables pour manipuler et valider des
chaînes dans Ansible. Les trois filtres principaux sont regex_search
,
regex_findall
et regex_replace
.
Le filtre regex_search
vous permet de rechercher une correspondance dans
une chaîne de caractères. Vous pouvez spécifier des options comme multiline
ou ignorecase.
Le filtre regex_findall
extrait toutes les occurrences d’un motif dans une
chaîne. Par exemple, pour extraire toutes les adresses IP d’une chaîne de texte
:
Gestion des chemins de fichiers
Ansible offre des filtres pour manipuler les chemins de fichiers sur différents systèmes.
Travailler avec des chemins Windows
win_basename
: Récupère le nom de fichier à partir d’un chemin Windows.win_splitdrive
: Sépare la lettre du lecteur du chemin de fichier.
Travailler avec des chemins Linux
dirname
: Récupère le répertoire à partir d’un chemin.expanduser
: Remplace le caractère tilde (~
) par le chemin de l’utilisateur.
expandvars
: Remplace les variables d’environnement dans un chemin.
Convertir une chaîne en objet date
Le filtre to_datetime
convertit une chaîne en un objet date que vous
pouvez ensuite manipuler.
Le filtre strftime
formate une date ou une heure selon un modèle
spécifique.
Ajouter des commentaires à un fichier
Le filtre comment
permet d’ajouter des commentaires à un texte. Par
défaut, Ansible utilise le symbole #
pour les commentaires, mais vous
pouvez personnaliser le style de commentaire.
Résultat :
Il est possible de choisir d’autres styles de commentaire :
Ajouter des guillemets à une commande shell
Le filtre quote
permet d’ajouter des guillemets à une commande shell pour
s’assurer qu’elle est correctement interprétée.
Encodage et décodage Base64
Les filtres b64encode
et b64decode
permettent d’encoder et
décoder des chaînes en base64.
un filtre pour les URL
Le filtre urlsplit
permet de décomposer une URL en ses différentes
parties (schéma, hôte, chemin, etc.).
Résultat :
Vous pouvez extraire une seule partie de l’URL en la spécifiant dans le filtre :
Quelques filtres mathématiques
En plus de manipuler des chaînes et des listes, Ansible permet également d’effectuer des calculs mathématiques simples à l’aide de filtres spécifiques.
-
Logarithme : Calcule le logarithme naturel ou basé sur un autre nombre.
-
Puissance : Calcule la puissance d’un nombre.
-
Racine carrée : Calcule la racine carrée.
Travailler avec les listes
Les listes sont une structure de données courante dans Ansible et les filtres Jinja permettent de les manipuler efficacement. Voici quelques filtres qui vous aideront à gérer vos listes de manière dynamique.
Obtenir un élément aléatoire d’une liste
Le filtre random
vous permet de sélectionner un élément aléatoire d’une
liste.
Vous pouvez également générer un nombre aléatoire à partir d’une plage d’entiers :
Pour générer des nombres aléatoires reproductibles (idempotents), vous pouvez
initialiser le générateur aléatoire avec une graine (seed
), comme le nom
de l’inventaire :
Obtenir les valeurs minimum et maximum d’une liste
Les filtres min
et max
permettent de récupérer les valeurs minimale
et maximale d’une liste.
Aplatir une liste
Le filtre flatten
permet de décomposer les sous-listes imbriquées en
une seule liste. Vous pouvez également spécifier un niveau d’imbrication à
aplatir.
Mélanger une liste
Le filtre shuffle
mélange les éléments d’une liste. Comme pour
random
, vous pouvez définir une graine pour que le résultat soit
reproductible.
Obtenir les valeurs uniques d’une liste
Le filtre unique
supprime les doublons d’une liste.
Opérations sur les listes
Ansible permet de combiner, croiser et comparer des listes à l’aide de plusieurs filtres spécifiques.
-
Union de listes : Combine deux listes en une seule sans enlever les doublons.
-
Intersection de listes : Récupère les éléments communs aux deux listes.
-
Différence de listes : Renvoie les éléments présents dans la première liste mais pas dans la seconde.
-
Différence symétrique : Renvoie les éléments qui ne sont présents que dans l’une des deux listes.
Concaténer une liste en une chaîne
Vous pouvez utiliser le filtre join
pour concaténer une liste en une
chaîne de caractères avec un séparateur spécifique.
Combiner et sélectionner des données
Ansible vous permet de manipuler et transformer des données complexes, qu’il s’agisse de listes, de dictionnaires, ou d’autres structures de données imbriquées. Grâce aux filtres Jinja, vous pouvez non seulement combiner plusieurs variables en une seule structure, mais aussi sélectionner ou extraire des éléments spécifiques à partir de ces données. Cela vous donne une grande flexibilité pour gérer des jeux de données variés et adapter vos playbooks à des environnements complexes.
Combiner différentes variables en une liste
Le filtre zip
est utilisé pour combiner deux ou plusieurs listes en une
seule, en associant chaque élément de la première liste avec celui de la
seconde. Cela permet de traiter des données provenant de différentes variables
ou sources de manière simultanée.
Le filtre zip
prend deux listes ou plus et les regroupe en une seule. Cela
est utile lorsque vous voulez lier les éléments de plusieurs listes entre eux
pour les traiter ensemble.
Exemple :
Ce playbook associera chaque élément des deux listes et produira le résultat suivant :
Si les listes ont des longueurs différentes, le filtre zip
ne conservera
que le nombre d’éléments correspondant à la plus petite liste. Si vous souhaitez
inclure des éléments manquants avec des valeurs null, vous pouvez utiliser
zip_longest
à la place.
Le filtre zip_longest
permet de gérer des listes de longueurs différentes,
en ajoutant des valeurs nulles lorsque l’une des listes est plus courte.
Ce playbook génère le résultat suivant, où le troisième élément de la première liste est associé à null :
Combiner des objets avec leurs sous-éléments
Lorsqu’on travaille avec des objets complexes, comme des utilisateurs ayant
plusieurs groupes ou des machines associées à plusieurs services, le filtre
subelements
permet de combiner chaque élément avec ses sous-éléments. Cela
est utile lorsque vous devez itérer sur chaque objet principal et traiter chacun
de ses éléments associés séparément.
Le filtre subelements
prend une liste d’objets et permet d’extraire et de
combiner les sous-éléments définis à l’intérieur de ces objets. Cela permet de
parcourir des relations un à plusieurs, comme des utilisateurs ayant
plusieurs autorisations ou appartenant à plusieurs groupes.
Exemple d’une liste d’utilisateurs avec des groupes associés :
Dans ce cas, vous pouvez utiliser subelements
pour parcourir chaque
utilisateur et ses groupes associés :
Le résultat affichera chaque utilisateur et le groupe auquel il appartient, sous forme de paires :
Cela vous permet de traiter chaque combinaison utilisateur/groupe de manière individuelle dans votre playbook, facilitant ainsi la gestion des relations complexes.
Combiner des dictionnaires
Les dictionnaires sont des structures de données couramment utilisées dans
Ansible pour stocker des paires clé/valeur. Le filtre combine
vous permet
de fusionner plusieurs dictionnaires en un seul. Vous pouvez également utiliser
des options comme recursive
pour effectuer des fusions plus profondes, ou
list_merge
pour contrôler la manière dont les listes sont combinées.
Utilisation du filtre combine
Le filtre combine
fusionne deux ou plusieurs dictionnaires. Si des clés
identiques sont présentes dans plusieurs dictionnaires, la valeur du dernier
dictionnaire écrasera celles des précédents, sauf si vous utilisez des options
pour spécifier un comportement différent.
Exemple simple de combinaison de dictionnaires :
En appliquant le filtre combine
:
Cela produira le résultat suivant, où la valeur de env
dans
overrides
écrase celle de defaults
:
Option recursive
pour des combinaisons profondes
Si vos dictionnaires contiennent des sous-dictionnaires, vous pouvez utiliser
l’option recursive=True
pour fusionner également leurs sous-niveaux.
En utilisant recursive=True
:
Le résultat sera :
Ici, le filtre combine les sous-dictionnaires au lieu de simplement écraser le
dictionnaire app
dans son ensemble.
Option list_merge
pour gérer les listes
Lorsque vous combinez des dictionnaires contenant des listes, l’option
list_merge
vous permet de contrôler comment les listes sont combinées. Par
défaut, Ansible remplace les listes, mais vous pouvez les fusionner de plusieurs
façons : replace
, append
, ou keep
.
Exemple avec l’option list_merge: 'append'
:
Avec list_merge: 'append'
:
Le résultat sera :
Les listes ont été combinées sans remplacer les valeurs précédentes.
Sélectionner des valeurs de listes ou de dictionnaires
Le filtre extract
permet d’extraire des éléments spécifiques à partir de
listes ou de dictionnaires. Il est particulièrement utile lorsque vous
travaillez avec des tableaux de données complexes et que vous avez besoin de
sélectionner des éléments précis en fonction de certaines clés ou indices.
Exemple d’extraction de valeurs spécifiques dans une liste :
Ce playbook extrait les éléments à la position 0 et 2 de la liste
['x', 'y', 'z']
, générant ainsi le résultat suivant :
Vous pouvez également utiliser extract
avec des dictionnaires pour
extraire des valeurs basées sur des clés spécifiques.
Permutations et combinaisons à partir de listes
Les filtres combinations
et permutations
permettent de générer des
combinais
ons et permutations à partir de listes d’éléments. Ces filtres sont utiles lorsque vous avez besoin d’explorer toutes les combinaisons ou permutations possibles entre plusieurs valeurs.
Cela générera toutes les combinaisons possibles de 2 éléments à partir de la liste [1, 2, 3] :
Ce playbook générera toutes les permutations possibles des nombres 1 et 2 :
Produit cartésien
Le filtre product
permet de créer un produit cartésien entre deux listes.
Cela est utile lorsque vous avez besoin de combiner chaque élément d’une liste
avec chaque élément d’une autre.
Supposons que vous ayez une liste de noms de domaines et que vous souhaitiez ajouter un suffixe comme “.com” à chaque nom.
Ce playbook génère le résultat suivant, combinant chaque nom avec le suffixe .com :
Utilisation du filtre json_query
pour extraire des données JSON
Le format JSON est couramment utilisé par les API REST pour échanger des
données et il est essentiel de savoir comment les manipuler efficacement avec
Ansible. Pour rechercher des éléments spécifiques dans une variable JSON,
Ansible propose le filtre json_query
, qui s’appuie sur JMESPath, un
langage de requête conçu pour parcourir et analyser des documents JSON.
Transformer des variables au format JSON
Avant d’extraire des informations depuis une API, il est utile de savoir comment
transformer des variables en JSON. Ansible propose deux filtres pour cette
opération : to_json
et to_nice_json
. Ces filtres transforment une
variable en chaîne JSON, avec une mise en forme brute ou plus lisible.
Prenons un exemple avec deux applications partageant certaines configurations grâce à l’utilisation des ancres YAML et des alias.
Ici, nous utilisons l’ancre &jvm_opts
pour partager les mêmes options JVM
entre app1 et app2. Grâce à l’alias *jvm_opts
, les propriétés
opts et port sont héritées par app2, tandis que path est
fusionné pour chaque application. Avec to_json
, les données sont
converties au format JSON, tandis que to_nice_json
ajoute un
indentation pour rendre le résultat plus lisible.
Pour illustrer l’utilisation du filtre json_query
, utilisons un exemple
concret avec les données JSON provenant de l’API
jsonplaceholder ↗. Prenons comme
exemple un schéma JSON représentant des utilisateurs.
Exemple de données JSON retournées par l’API :
Vous pouvez utiliser le module uri
pour obtenir ces données et les stocker
dans une variable.
Extraire un champ particulier d’un JSON
Supposons que vous souhaitiez obtenir la liste des noms d’utilisateurs
présents dans les données JSON. Pour ce faire, vous pouvez utiliser le filtre
json_query
avec une requête JMESPath pour extraire les noms de la
liste.
Avant de pouvoir utiliser json_query
, vous devez installer le module
Python JMESPath :
Nous allons modifier notre playbook pour extraire uniquement les noms des utilisateurs.
Le filtre json_query
est ici utilisé pour parcourir tous les objets JSON
et en extraire le champ name
.
Retrouver un élément particulier
Il est également possible d’extraire un élément spécifique du JSON. Par exemple, pour retrouver l’utilisateur ayant l’ID 1, vous pouvez utiliser une requête JMESPath filtrant les résultats en fonction de ce critère.
Cette requête JMESPath permet de filtrer les utilisateurs en fonction de leur ID, ne renvoyant que l’utilisateur correspondant à ID 1.
Vous pouvez combiner des conditions OU (||
) et ET (&&
) dans
votre requête JMESPath pour filtrer plusieurs utilisateurs ou ajouter des
critères supplémentaires.
Exemple d’extraction des noms des entreprises pour les utilisateurs ayant ID 1 ou ID 5 :
Vous pouvez tester vos expressions JMESPath ici ↗
Combiner les données extraites
En plus d’extraire des données, Ansible vous permet de combiner les
résultats extraits pour créer de nouvelles structures de données. Le filtre
combine
peut être utilisé pour associer des informations, comme lier un
nom à une adresse e-mail.
Dans cet exemple, nous allons combiner le nom et l’email des utilisateurs ID 1 et ID 5 pour créer une nouvelle structure de données.
Ce playbook associe chaque nom d’utilisateur à son adresse e-mail, créant ainsi une structure clé/valeur avec les noms comme clés et les e-mails comme valeurs.
Manipuler des données YAML
Les filtres to_yaml
et to_nice_yaml
dans Ansible permettent de
convertir des données (variables, objets ou structures complexes) au format
YAML. Ce format est couramment utilisé pour rendre les configurations et les
fichiers de données plus lisibles et faciles à interpréter. Ces filtres sont
particulièrement utiles lorsque vous devez afficher ou manipuler des données
dans un fichier de sortie ou générer des fichiers de configuration.
Utilisation du filtre to_yaml
Le filtre to_yaml
permet de convertir des variables au format YAML brut.
Cela est utile lorsque vous travaillez avec des structures de données complexes
et que vous souhaitez les afficher dans un format facilement compréhensible ou
lorsque vous devez écrire des données directement dans un fichier YAML.
Dans cet exemple, la variable variable
sera convertie en texte YAML. Ce
filtre est surtout utile pour convertir des objets JSON ou des dictionnaires en
YAML sans mise en forme particulière.
Utilisation du filtre to_nice_yaml
Le filtre to_nice_yaml
est une version améliorée de to_yaml
,
permettant de générer un YAML lisible avec une mise en forme plus agréable.
Il ajoute des indentations et organise les données de manière plus claire. Cela
le rend plus adapté pour l’affichage humain ou l’écriture dans des fichiers de
configuration.
Ici, le paramètre indent=4
spécifie que chaque niveau d’imbrication dans
la structure YAML sera indéterminé avec 4 espaces. Ce format est souvent utilisé
pour améliorer la lisibilité lorsque vous travaillez avec des structures
complexes dans des fichiers de configuration.
Le filtre to_nice_yaml
propose plusieurs options supplémentaires, telles
que l’ajustement de l’indentation ou le contrôle de la largeur des lignes.
Ce paramètre définit la largeur maximale des lignes, utile pour éviter que les lignes ne dépassent une certaine longueur dans les fichiers YAML générés.
Exemple complet : Écrire dans un fichier YAML
Voici un exemple où les données d’un inventaire sont converties au format YAML lisible, puis écrites dans un fichier.
Dans cet exemple, le contenu de inventory_data
est converti en YAML bien
formaté, avec une indentation de 2 espaces, puis est écrit dans un fichier
inventory.yaml
.
Sécuriser les données avec des filtres
Ansible propose des filtres pour sécuriser les données sensibles, notamment pour la gestion des mots de passe et le chiffrement de chaînes de caractères.
Générer des mots de passe
Le filtre password_hash
permet de générer des mots de passe sécurisés à
l’aide d’algorithmes comme SHA-512 ou SHA-256. Vous pouvez ajouter des
salts et définir des rounds pour renforcer la sécurité.
Chiffrer des chaînes
Les filtres hash
permettent de chiffrer une chaîne avec divers
algorithmes comme MD5, SHA1, ou Blowfish.
Calculer un checksum
Le filtre checksum
calcule un hash à partir d’une chaîne de
caractères.
Bonnes pratiques pour l’utilisation des filtres Jinja dans Ansible
L’utilisation des filtres Jinja dans Ansible est un outil puissant pour automatiser vos configurations. Toutefois, il est essentiel de suivre certaines bonnes pratiques pour garantir que vos playbooks restent lisibles, faciles à maintenir et efficaces. L’une des premières règles à retenir est de garder les choses simples. La complexité excessive rend les configurations plus difficiles à comprendre et plus coûteuses à maintenir.
Première règle : La simplicité
Le principe de base dans Ansible et plus largement dans l’automatisation, est de faire simple. Un code complexe est non seulement plus difficile à lire mais aussi à maintenir. Des configurations trop imbriquées ou l’utilisation excessive de filtres complexes peuvent rapidement rendre vos playbooks difficiles à déboguer.
- Utilisez des filtres uniquement lorsque c’est nécessaire. Ne complexifiez
pas votre code avec des filtres Jinja sophistiqués si une solution plus simple
peut être utilisée. Par exemple, utilisez des conditions
when
basiques au lieu d’imbriquer plusieurs filtres pour rendre le code plus clair. - N’utilisez pas des filtres pour des transformations excessives. Si une donnée doit être transformée avec plusieurs filtres à la suite, il est souvent préférable de préparer cette donnée en amont dans une tâche distincte avec des variables intermédiaires.
Éviter la duplication de code
L’une des sources les plus courantes de complexité est la duplication de code. Si vous répétez des blocs de configuration ou des appels de filtres dans plusieurs tâches, cela rend la maintenance plus difficile. Les modifications devront être faites à plusieurs endroits, ce qui accroît le risque d’erreurs.
- Centralisez vos transformations de données en utilisant des variables
set_fact
. Si un filtre ou une transformation complexe doit être utilisé à plusieurs reprises, il est plus efficace de définir une variable avec le résultat intermédiaire.
Cela rend le playbook plus lisible et plus facile à ajuster en cas de changement de logique.
Séparation des responsabilités
Les playbooks bien structurés sont faciles à comprendre et à maintenir. Une bonne pratique consiste à séparer les tâches en fonction de leurs responsabilités. Par exemple, les tâches de récupération de données ne devraient pas inclure des filtres Jinja complexes pour transformer ces données dans la même étape.
- Séparez la récupération des données de leur transformation. Collectez d’abord les données dans une tâche, puis traitez-les avec des filtres dans une autre tâche. Cela permet une meilleure lisibilité et facilite le débogage si quelque chose ne fonctionne pas comme prévu.
Utiliser des variables intermédiaires
Lorsque vous travaillez avec plusieurs filtres enchaînés, il peut être tentant d’appliquer directement les transformations dans une seule tâche. Cela rend cependant le code plus difficile à lire et augmente le risque d’erreurs. Une bonne pratique consiste à utiliser des variables intermédiaires pour séparer les étapes de transformation.
- Décomposez les filtres sur plusieurs lignes en utilisant des variables. Cela permet de suivre plus facilement la transformation des données à chaque étape.
Privilégier la lisibilité
Les playbooks lisibles sont plus faciles à maintenir et à transmettre à d’autres membres de l’équipe. Utilisez des noms de variables explicites et évitez d’imbriquer trop de transformations dans une seule tâche.
- Choisissez des noms de variables clairs et descriptifs. Cela aide à comprendre ce que fait une tâche sans avoir à lire toute la logique en profondeur.
- Commentez vos filtres complexes. Lorsque vous devez utiliser des filtres Jinja avancés, expliquez dans un commentaire ce que vous faites et pourquoi cela est nécessaire.
Testez les transformations étape par étape
Avant de vous lancer dans des filtres complexes, il est conseillé de tester
chaque étape de la transformation. Vous pouvez utiliser des tâches debug
pour afficher des résultats intermédiaires et vous assurer que chaque
transformation se déroule comme prévu.
- Utilisez le module
debug
pour afficher le contenu des variables à différents points de votre playbook.
Cela permet de valider chaque étape de la transformation et de repérer plus facilement les erreurs.
Conclusion
En résumé, l’utilisation des filtres Jinja dans Ansible est une compétence
clé pour rendre vos playbooks plus flexibles et dynamiques. Nous avons exploré
une grande variété de filtres, allant de la manipulation des listes et des
textes, aux filtres plus avancés pour la sécurisation des données, la
gestion des formats JSON/YAML et les calculs mathématiques. Les filtres
comme to_yaml
et to_nice_yaml
simplifient l’écriture des fichiers de
configuration, tandis que d’autres filtres comme json_query
permettent de
manipuler des données complexes issues des API.
Cependant, la complexité peut rapidement alourdir vos configurations, rendant la maintenance plus difficile. C’est pourquoi il est essentiel de suivre les bonnes pratiques que nous avons abordées : faire simple, éviter la duplication et tester étape par étape pour assurer la robustesse et la clarté de vos playbooks.
L’objectif final est de maintenir des configurations lisibles, efficaces et faciles à comprendre, même pour des équipes élargies ou des projets à long terme. En suivant ces principes, vous garantissez que vos playbooks Ansible restent non seulement fonctionnels, mais également pérennes et maintenables.