Et si le module block Ansible n'était pas ce que tu croyais ?

Temps de lecture estimé : 3 minutes

Habituellement, les tâches Ansible sont séquentielles et indépendantes entre elles. Cependant, il arrive parfois qu’on ait besoin de les regrouper, pour gérer les erreurs en une fois ou conditionner plusieurs tâches. C’est ce dernier cas qui va nous occuper aujourd’hui, car il y a une subtilité à connaître pour ne pas se laisser surprendre. Et le moins qu’on puisse dire, c’est qu’elle est drôlement piégeuse.

Chez Ansible, toute tâche peut être conditionnée :

- name: Ensure configuration file existence
  ansible.builtin.file:
    path: /etc/myapp.conf
    state: touch
  when: 'myapp' in allowed_app

Naturellement, le pseudo-module block hérite de ce fonctionnement. Grâce à ça, nous pouvons écrire :

- name: Install, configure, and start Nginx
  block:
    - name: Install webserver
      apt:
        name:
        - nginx
        state: present

    - name: Configure webserver
      copy:
        src: vhost.conf
        dest: /etc/nginx/conf.d/

    - name: Enable webserver
      systemd:
        daemon_reload: true
        name: nginx
        state: started
        enabled: True

  when: with_webserver|bool

Ce when commun est tout l’objectif de notre block, il permet d’éviter les répétitions et d’affirmer sémantiquement que ces tâches vont ensemble. Mais qu’arrive-t-il si nous changeons la valeur de notre condition en cours de route ? Les tâches se poursuivent-elles, maintenant qu’on est déjà entré dans le block ?

- name: Install, configure, and start Nginx
  block:
    - name: Install webserver
      apt:
        name:
        - nginx
        state: present

    - name: Configure webserver
      copy:
        src: vhost.conf
        dest: /etc/nginx/conf.d/

    - name: Change webserver "fact"
      set_fact:
        with_webserver: false

    - name: Enable webserver
      systemd:
        daemon_reload: true
        name: nginx
        state: started
        enabled: True

  when: with_webserver|bool

Non, et c’est là qu’est l’os. Si la valeur de notre fact change via l’exécution d’un module set_fact, toutes les opérations suivantes s’en trouvent remises en cause. Pourquoi cela ? En fait, la documentation nous l’explique très bien :

The directive does not affect the block itself, it is only inherited by the tasks enclosed by a block.

visualisation du fonctionnement de block et when sous ansible

Ceci étant, cette explication n’a pas l’emphase qu’elle mérite et c’est dommage. En effet, elle est essentielle pour comprendre le fonctionnement du module block, mais puisque les autres directives (ex: become ou ignore_errors) sont statiques il n’est in fine pas nécessaire de la connaître ; dans ces cas, que la directive soit ventilée ou non ne change rien.

La versatilité du when le rend à part et bien qu’il soit un cas spécial, c’est bien grâce à ce petit détail qu’on comprend la véritable nature du block lui-même : block est une facilité d’écriture et de lecture pour l’humain, autrement dit un sucre syntaxique. Ansible lui-même s’en fiche.

Comme d’habitude, vous pouvez retrouver le code pour essayer par vous-même sur le dépôt d’exemple.


Sources:


    Ce billet vous a plu ? Partagez-le sur les réseaux…


    … Ou inscrivez-vous à la newsletter pour ne manquer aucun article (Si vous ne voyez pas le formulaire, désactivez temporairement uBlock).

    Voir aussi