Aller au contenu principal

Utilisation des blocks Ansible

· 3 minutes de lecture
Stéphane ROBERT
Consultant DevOps

Les blocs Ansible permettent de regrouper des taches, mais aussi de gérer les erreurs à la manière des exceptions que l'on retrouve dans les langages de programmation. Je vous propose un cours billet de cette fonctionnalité plutôt pratique.

Regroupement des actions avec les blocks Ansible

Les block Ansible permettent de grouper des actions logiques de tâches. Toutes les tâches d'un bloc héritent des directives appliquées au niveau du bloc. La plupart de ce que vous pouvez appliquer à une seule tâche (à l'exception des boucles) peut être appliqué au niveau du bloc, de sorte que les blocs facilitent beaucoup la définition de données ou de directives communes aux tâches. Par exemple, une instruction when est appliquée aux tâches dans un bloc, pas au bloc lui-même.

Exemple :

 tasks:
   - name: Installation, configuration et démarrage d'Apache
     block:
       - name: Installation de httpd et memcached
         packages:
           name:
            - httpd
            - memcached
           state: present

       - name: Création d'un fichier de conf
         template:
           src: templates/src.j2
           dest: /etc/foo.conf

       - name: Activation et Démarrage du service httpd pour les distribs Centos
         ansible.builtin.service:
           name: httpd
           state: started
           enabled: True
     when: ansible_facts['distribution'] == 'CentOS'
     become: true
     become_user: root
     ignore_errors: yes

Dans l'exemple ci-dessus, la condition when sera évaluée avant qu'Ansible n'exécute chacune des trois tâches du bloc. Les trois tâches héritent également des directives d'escalade de privilèges, s'exécutant en tant qu'utilisateur root. Enfin, garantit qu'Ansible continue d'exécuter le playbook même si certaines des tâches échouent : ignore_errors: yes

Gestion des exceptions avec des blocks Ansible

Les blocs offrent une autre solution pour gérer les erreurs que celle du ignore_errors: yes.

En effet, dans un block on peut utiliser les balises rescue et always. C'est très proche de ce que l'on retrouve de la gestion des exceptions des langages de programmation comme try-catch en Java ou try-except en Python.

  tasks:
    - name: Exécuter une erreur en lançant une mauvaise commande
      block:
        - name: une commande
          command: uptime

        - name: une mauvaise commande
          command: blabla

        - name: Cette tache ne se lancera pas
          debug:
            msg: "Jamais je ne serais exécuté car la tache précédente sortira tjrs en erreur"

      rescue:
        - name: Se lance quand le playbook plante
          debug:
            msg: "Le bloc a planté, que faire ..."

La tache définie dans la section rescue sera exécuté que si les taches du block échoue.

Vous pouvez également ajouter une section always qui s'exécutera toujours même si le block est en erreur.

Un exemple : On souhaite que le playbook ne s'exécute que sur les machines actives de l'inventaire. Dans un block on va constituer une liste de machines qui ont répondu lors d'une tentative de connexion Ansible.

Ce qui donne :

---
- hosts: all
  connection: local
  gather_facts: no
  tasks:
    - block:
        - name: Tente une connexion à la machine
          wait_for_connection:
            timeout: 5
          vars:
            ansible_connection: ssh
        - name: Ajout de la machine au groupe "running_hosts"
          group_by:
            key: "running_hosts"
      rescue:
        - name: Ajout de la machine au groupe "dead_hosts"
          group_by:
            key: "dead_hosts"
- hosts: running_hosts
  gather_facts: no
  tasks:
    - name: get facts
      setup:
        gather_subset: facter

Vous pouvez ensuite stocker votre liste de machines qui n'ont pas été dans un fichier.

Si vous voulez plus de tutorials Ansible je vous renvoie sur le billet de l'introduction à ansible