Maîtriser les conditions dans Ansible
Mise à jour :
Dans un environnement automatisé, toutes les tâches ne doivent pas forcément s’exécuter de la même manière. Vous devez parfois adapter vos actions à l’état du système, aux résultats précédents ou à l’environnement cible. C’est là qu’interviennent les conditions Ansible.
Grâce à l’instruction when
, vous pouvez contrôler l’exécution des
tâches en fonction de variables, de faits systèmes (facts) ou de résultats
enregistrés.
Ce chapitre vous montre, pas à pas, comment écrire des conditions efficaces, sûres et lisibles dans vos playbooks.
Conditions de base de when
La condition when
est la plus simple et la plus courante pour adapter
l’exécution d’une tâche selon une ou plusieurs conditions. Elle s’évalue
en langage Jinja2, utilisé dans Ansible pour manipuler les variables et
expressions.
Par exemple, vous voulez installer un paquet seulement sur Debian ? Voici comment faire :
- name: Installer Apache sur Debian ansible.builtin.apt: name: apache2 state: present when: ansible_facts['os_family'] == "Debian"
Ici, Ansible interroge les faits systèmes (facts) collectés automatiquement et exécute la tâche uniquement si la distribution appartient à la famille Debian.
Rappel: Pour retrouver les facts d’un hôte cible, utilisez la commande
ansible -m setup <host>
.
Condition avec une variable définie dans le playbook
Si vous avez une variable définie dans votre playbook, vous pouvez l’utiliser
directement dans la condition when
. Par exemple, si vous avez une variable
mon_environnement
définie dans votre playbook, vous pouvez conditionner
l’exécution d’une tâche en fonction de sa valeur :
vars: mon_environnement: prod
tasks: - name: Exécuter une tâche en production ansible.builtin.shell: echo "En production" when: mon_environnement == "prod"
Cela permet de gérer plusieurs environnements (test, pré-prod, prod) sans dupliquer les tâches.
Tester si une variable existe ou est définie
Avant d’accéder à une variable, vérifiez qu’elle est définie pour éviter les erreurs :
- name: Vérifier si une variable est définie ansible.builtin.debug: msg: "La variable existe" when: ma_variable is defined
Cette syntaxe évite les plantages si la variable est absente.
Conditions avancées
Ansible permet d’enregistrer le résultat d’une tâche grâce au mot-clé
register
. Cela vous donne la possibilité d’évaluer ce résultat dans une
condition when
, pour adapter la suite du playbook selon ce qui s’est passé
précédemment.
Par exemple, vous voudriez tester la présence d’un fichier, alors exploiter le
résultat du module stat
est une bonne pratique :
- name: Vérifier si un fichier existe ansible.builtin.stat: path: /etc/monfichier.conf register: resultat_fichier
- name: Afficher un message si le fichier existe ansible.builtin.debug: msg: "Le fichier est présent" when: resultat_fichier.stat.exists
La première tâche utilise le module stat
pour récupérer des informations
sur un fichier. Le résultat est stocké dans resultat_fichier
, et on teste
ensuite l’attribut exists
.
Quand vous utilisez register
dans une tâche Ansible, le module concerné
retourne un objet riche contenant plusieurs attributs. Ces données
permettent d’analyser le comportement de la tâche exécutée et de
conditionner les suivantes.
Voici les principaux attributs que vous pouvez exploiter :
stdout
etstdout_lines
Ils correspondent à la sortie standard du module :
stdout
est une chaîne brute de la sortie texte.stdout_lines
est la même sortie, mais découpée en une liste de lignes.
- name: Vérifier le contenu d’un fichier ansible.builtin.shell: cat /etc/hosts register: contenu_hosts
- name: Chercher une IP spécifique ansible.builtin.debug: msg: "L'entrée existe" when: "'192.168.1.1' in contenu_hosts.stdout"
Pour parcourir ligne par ligne :
when: "'192.168.1.1' in contenu_hosts.stdout_lines"
stderr
etstderr_lines
Ce sont les équivalents pour la sortie d’erreur. Très utile pour détecter un message d’erreur particulier :
when: "'Permission denied' in resultat_cmd.stderr"
rc
: le code de retour
Un standard dans les systèmes UNIX. 0
signifie succès, toute autre valeur
signale une erreur.
when: resultat_cmd.rc != 0
Cela permet de gérer manuellement les erreurs, notamment quand on utilise
ignore_errors: yes
.
changed
Ce booléen vaut true
si la tâche a modifié quelque chose sur le système. Il
est très utile pour déclencher d’autres actions seulement si un changement a
eu lieu.
when: resultat_update.changed
Ces attributs donnent une grande finesse de contrôle : vous pouvez conditionner des tâches sur des messages d’erreur, des changements réels ou des résultats de commande spécifiques. Cela rend vos playbooks plus intelligents et robustes.
Combiner plusieurs conditions logiques
Ansible permet d’exprimer des conditions complexes en combinant plusieurs
tests avec les opérateurs and
, or
et not
. Ces expressions,
évaluées en syntaxe Jinja2, donnent une très grande souplesse à vos
playbooks.
Syntaxe avec opérateurs logiques
Vous pouvez écrire les conditions directement en ligne :
when: variable1 == "valeur" and variable2 != "autre"
Ou bien les présenter sous forme de liste :
when: - variable1 == "valeur" - variable2 != "autre"
Dans ce cas, toutes les conditions doivent être vraies (équivalent d’un
and
).
Exemple concret : contrôler un service actif
Imaginons que vous ne voulez redémarrer nginx que s’il est présent ET en cours d’exécution. Voici comment faire :
- name: Vérifier si le service nginx est actif ansible.builtin.service_facts: register: resultat_service
- name: Redémarrer nginx si actif ansible.builtin.service: name: nginx state: restarted when: "'nginx' in resultat_service.services and resultat_service.services['nginx'].state == 'running'"
Ici :
- On vérifie d’abord que le service
nginx
est connu d’Ansible - Puis on teste si son état est
'running'
- Si ces deux conditions sont remplies, la tâche est exécutée
Utiliser or
et not
Exemple avec or
: exécuter une tâche si au moins un des systèmes est ciblé
when: ansible_os_family == "Debian" or ansible_os_family == "RedHat"
Exemple avec not
: éviter d’exécuter une tâche si une condition est vraie
when: not fichier_existe.stat.exists
Bonnes pratiques
Quand vous accédez à une donnée imbriquée (comme dans services['nginx']
),
assurez-vous d’abord que la clé existe :
when: - "'nginx' in resultat_service.services" - resultat_service.services['nginx'].state == 'running'
Cela évite les erreurs si le service n’est pas présent.
Tests Jinja spécialisés et filtres
Ansible s’appuie sur le moteur de template Jinja2, qui propose une large
gamme de tests pour écrire des conditions plus précises. Ces tests
s’utilisent souvent avec is
et permettent de vérifier l’état, l’existence
ou le type d’une variable ou d’un objet.
Tests courants
Voici les plus utiles pour vos playbooks :
is defined
: vérifie si une variable existeis not defined
: inverse du précédentis none
/is not none
: teste la nullité d’une variableis string
,is iterable
,is mapping
: teste le typeis failed
/is succeeded
: résultats de tâches enregistrées
Exemple : tester la définition d’une variable
Avant de manipuler une variable optionnelle :
- name: Vérifier si une variable est définie ansible.builtin.debug: msg: "La variable est présente" when: mon_parametre is defined
Exemple : contrôle d’une tâche avec register
- name: Exécuter une commande ansible.builtin.command: /usr/bin/true register: resultat_commande ignore_errors: yes
- name: Afficher si la commande a échoué ansible.builtin.debug: msg: "La commande a échoué" when: resultat_commande is failed
Ansible vous permet ainsi de réagir intelligemment à l’issue d’une tâche (réussite ou échec) sans gérer manuellement les codes retour.
Combinaison de tests
Les tests peuvent être combinés dans des expressions complexes :
when: variable is defined and variable is not none
C’est une bonne pratique pour sécuriser l’accès aux valeurs et éviter les erreurs de type “undefined variable”.
Différence entre tests et filtres
Attention à ne pas confondre :
- Tests → utilisés avec
is
, renvoient un booléen - Filtres → modifient la valeur (ex.
| default()
,| lower
)
Exemple de filtre :
when: (ma_variable | default("defaut")) == "defaut"
Ici, si ma_variable
n’est pas définie, la valeur "defaut"
est utilisée à la
place.
Debug et bonnes pratiques de contrôle
Travailler avec des conditionnels dans Ansible implique de bien comprendre le comportement des tâches, surtout en cas d’erreurs ou de conditions imprévues. Voici les outils et bonnes pratiques pour garder le contrôle de vos playbooks.
Utiliser le module debug
pour visualiser les variables
Le module debug
permet d’inspecter le contenu d’une variable ou d’un fait
système :
- name: Afficher la valeur d’une variable ansible.builtin.debug: var: ansible_distribution
C’est particulièrement utile pour valider la logique des conditions ou comprendre pourquoi une tâche ne s’exécute pas.
Le module assert
: sécuriser l’exécution
Avec assert
, vous pouvez interrompre le playbook si une condition n’est
pas respectée. Cela évite de poursuivre avec un état incohérent :
- name: Vérifier que nginx est installé ansible.builtin.assert: that: - "'nginx' in resultat_service.services" fail_msg: "nginx n’est pas installé" success_msg: "nginx détecté"
Ce mécanisme remplace les when
dans certains cas où l’arrêt est
obligatoire.
Gérer les erreurs avec ignore_errors
Meme si je ne recommande pas de l’utiliser systématiquement, il est parfois
nécessaire de continuer l’exécution même si une tâche échoue. Utilisez
ignore_errors: yes
pour continuer malgré une erreur, tout en évaluant le
résultat ensuite :
- name: Lister un fichier (qui peut ne pas exister) ansible.builtin.command: ls /chemin/inexistant register: resultat_ls ignore_errors: yes
- name: Afficher un message en cas d’échec ansible.builtin.debug: msg: "Fichier non trouvé" when: resultat_ls is failed
Je vous recommande de l’utiliser avec précaution, car cela peut masquer des
erreurs importantes. Privilégiez les conditions when
pour gérer les cas
spécifiques.
Astuces pour rendre les conditions plus lisibles
- Utilisez des parenthèses pour clarifier la logique :
when: (a == "ok" and b == "ok") or c == "erreur"
- Préférez des noms de variables explicites :
when: user_exists is true
when: user_exists is true
- Ne surchargez pas une seule ligne avec trop de logique : décomposez ou utilisez la forme liste.
Exercices pratiques : Maîtriser les conditionnels Ansible
Vous avez vu comment utiliser le mot-clé when
, manipuler des variables
avec register
, combiner des tests logiques et intégrer des filtres
Jinja2. Place à la pratique : un ensemble d’exercices pour apprendre à écrire
des conditions fiables, lisibles et adaptées à des situations concrètes.
👉 Travaux pratiques : TP 5 : Conditionnels Ansible ↗
Ces exercices couvrent notamment
- L’utilisation de
when
avec des faits système (ansible_facts
) pour piloter l’exécution selon le système d’exploitation ou l’état d’un service. - L’écriture de conditions combinées avec les opérateurs
and
,or
,not
pour orchestrer des logiques métier plus complexes.
Pourquoi pratiquer ?
- Apprendre à adapter l’exécution des tâches selon l’environnement sans dupliquer le code.
- Maîtriser les cas d’erreurs et écrire des playbooks tolérants aux différences d’infrastructure.
- Savoir structurer des conditions lisibles et maintenables, en prévenant les erreurs de logique.
Clonez le dépôt ou suivez les consignes en ligne ; ces exercices vous permettront de transformer vos playbooks en outils robustes, capables de s’ajuster à chaque contexte d’exécution.
Contrôle de connaissances
Pourquoi ce contrôle ?
Cet contrôle va vous permettre de valider vos connaissances sur le sujet abordé dans le guide. Il comporte des QCM, des questions vrai/faux et des réponses ouvertes à un mot.
🕒 Le chronomètre commence dès que vous cliquez sur Démarrer le test. Vous devrez terminer l’examen avant la fin du temps imparti.
🎯 Pour réussir, vous devez obtenir au moins 80% de bonnes réponses.
💡 Je ne fournis pas directement les réponses aux questions. Cependant, si certaines sont complexes, des pistes d’explication pourront être proposées dans le guide ou après l’examen.
Bonne chance ! 🚀
Conclusion
Vous avez maintenant les clés pour écrire des conditions efficaces dans Ansible. Que ce soit pour adapter l’exécution d’une tâche, gérer des erreurs ou contrôler l’état d’un service, les possibilités sont vastes.
Vous pouvez désormais passer à la suite avec les la création de rôles Ansible.