Blog ENI : Toute la veille numérique !
🐠 -25€ dès 75€ 
+ 7 jours d'accès à la Bibliothèque Numérique ENI. Cliquez ici
Accès illimité 24h/24 à tous nos livres & vidéos ! 
Découvrez la Bibliothèque Numérique ENI. Cliquez ici

Contrôle de tâches

Itération de tâches

Répéter N fois une tâche en programmation s’effectue dans une boucle. Si vous avez déjà écrit du code avec des langages tels que Bash, Python ou C par exemple, vous avez forcément déjà utilisé des boucles. Leur utilisation avec Ansible permet d’écrire plusieurs tâches en bénéficiant du même module. Deux mots-clés permettant de créer des boucles : loop et with_*.

Avant la version 2.5 de Ansible, les mots-clés utilisés pour effectuer une boucle étaient uniquement des compositions de with_* :

  • with_list ;

  • with_items ;

  • with_indexed_items ;

  • with_flattened ;

  • with_together ;

  • with_dict ;

  • with_sequence ;

  • with_subelements ;

  • with_nested ;

  • with_cartesian ;

  • with_random_choice.

Vous pouvez encore rencontrer des playbooks contenant cette syntaxe qui sera probablement obsolète dans une version future. Il est donc recommandé d’utiliser dorénavant uniquement le mot-clé loop.

Pour explorer les techniques avancées sur les itérations, consultez la documentation en ligne de Ansible.

1. Itération sur une simple liste

Une boucle répète plusieurs fois la même tâche sur une liste d’éléments. Le mot-clé loop est ajouté à la tâche afin de prendre comme valeur la liste des éléments qu’une tâche doit itérer tandis que la variable de boucle item contient la valeur utilisée lors de chaque itération.

Les exemples ci-dessous vont démontrer comment écrire une boucle dans un playbook.

Exemple 1

Comment vérifier que les services mariadb et httpd sont démarrés sur les hôtes gérés du groupe web ?

Le mot-clé loop est ajouté à la tâche afin de prendre comme valeur la liste des éléments :

loop: 
 - mariadb 
 - httpd 

Et la variable de boucle item contient la valeur utilisée lors de chaque itération :

name: "{{ item }}" 

L’intégralité du playbook se présente ainsi :

--- 
- name: gestion des services 
  hosts: web 
  gather_facts: true 
 
  tasks: ...

Tâches conditionnelles

Les conditions utilisées dans Ansible permettent d’exécuter des tâches si certaines conditions sont remplies. Nous pouvons citer plusieurs exemples d’utilisation :

  • Une limite fixe peut être définie dans une variable pour la comparer avec la mémoire disponible sur un hôte géré.

  • Le résultat d’une commande peut être capturé avec l’instruction register puis évalué pour déterminer si une tâche précise est bien terminée avant de démarrer une nouvelle action.

  • L’utilisation des faits de Ansible pour déterminer la distribution Linux utilisée sur un hôte géré et ensuite décider s’il faut installer ou pas une application, etc.

L’instruction qui sert à exécuter une tâche de manière conditionnelle est when. Elle prend comme valeur la condition à tester. Si la condition est vraie, alors la tâche est exécutée sinon la tâche est ignorée.

L’instruction when n’est pas une variable de module. Par conséquent, elle doit être positionnée hors du module, c’est-à-dire au niveau supérieur de la tâche :

  tasks: 
  - name: Exemple1 
   debug: 
      msg: "Egalité" 
    when: message1 == "Hello World!" 

1. Conditions simples

La structure si-alors-sinon contient une condition unique. Pour écrire une expression conditionnelle, Ansible fournit des opérateurs permettant de comparer des chaînes de caractères, des données numériques ou des valeurs booléennes.

Chaînes de caractères :

Opérateur

Description

==

Égal

!=

Différent

Variable.find(mot) != -1

Contient

== ""

Est NULL (vide)

Exemple 1 : opérateur égal

La variable message1 est déclarée :

message1: "Hello World!" 

Avec le module debug le message « Egalité » s’affiche si message1 est égal à « Hello World! » :

debug: 
  msg: "Egalité" 
when: message1 == "Hello World!" 

Le playbook dans son intégralité :...

Gestionnaires Ansible

Du fait que les modules Ansible soient idempotents, les tâches d’un playbook exécutées sur les hôtes gérés auront le même effet qu’on les applique une ou plusieurs fois. Cependant, il est possible d’avoir parfois besoin d’exécuter une tâche additionnelle. Pour répondre à cette attente, les tâches appelées gestionnaires Ansible (Ansible handlers), réagissent à une notification déclenchée par d’autres tâches.

Les tâches gestionnaires Ansible sont déclenchées uniquement lorsqu’elles sont invoquées par le biais du mot-clé notify.

tasks: 
  - name: copier la configuration de Apache HTTP Server 
    template: 
      src: /src/httpd.conf 
      dest: /etc/httpd/conf/httpd.conf 
    notify: 
      - restart apache 

Le mot-clé notify, ci-dessus, mentionne le nom du gestionnaire à déclencher par la tâche.

Le mot-clé handlers, quant à lui, définit la liste des tâches du gestionnaire qu’il doit exécuter.

handlers: 
  - name: restart apache 
    service: 
      name: httpd 
      state: restarted 

Le traitement s’effectue toujours dans l’ordre...

Gestion des erreurs de tâche

Chaque tâche fournit un code de retour. Ainsi, Ansible peut évaluer si elle a réussi ou échoué. Généralement, Ansible arrête immédiatement l’exécution du « play » sur l’hôte géré et ignore toutes les tâches restantes. Il est cependant nécessaire, parfois, de poursuivre son exécution malgré tout.

Pour la gestion des erreurs durant l’exécution d’une tâche, Ansible propose plusieurs fonctions qui permettent :

  • d’ignorer l’échec d’une tâche ;

  • de forcer l’exécution des gestionnaires après l’échec d’une tâche ;

  • de spécifier les conditions d’échec d’une tâche ;

  • de gérer les erreurs au sein des blocs Ansible ;

  • de spécifier une tâche signalant un résultat Changed.

1. Ignorer l’échec d’une tâche

Quand une tâche a échoué, le play est arrêté. Il est possible d’ignorer cela en utilisant le mot-clé ignore_errors.

Exemple

Voici comment installer les paquets d’un logiciel appelé « nothing », lesquels n’existent pas dans les dépôts.

Soit le playbook suivant :

--- 
- name: installation du logiciel nothing 
  hosts: servers 
  
  tasks: 
  - name: installation des paquets nothing 
    yum: 
      name: nothing 
      state: latest 
 
  - name: Afficher un message 
      msg: La vie continue... 

Ansible va interrompre l’exécution de la tâche et, par conséquent, l’affichage du message « La vie continue... » ne sera pas effectué :

[root@server1 projet]# ansible-playbook pb-nothing.yml 
 
PLAY [installation du logiciel nothing] *********************** 
 
TASK [Gathering Facts] **************************************** 
ok: [server2] 
ok: [server3] 
 
TASK [installation des paquets nothing] *********************** 
fatal: [server3]: FAILED! => {"changed": false, "failures": 
["nothing aucun paquet 
correspondant: nothing"]...