Aller au contenu

Maîtriser les conditions dans Ansible

Mise à jour :

logo Ansible

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 et stdout_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 et stderr_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 existe
  • is not defined : inverse du précédent
  • is none / is not none : teste la nullité d’une variable
  • is string, is iterable, is mapping : teste le type
  • is 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.