Gestion des Erreurs Ansible

Objectifs de certification

RHCE EX294 (RHEL8)

Si vous poursuivez des objectifs de certification, vous pourriez trouvez ici des bases qui vous aideront pour :

  • 6. Création des jeux et des playbooks Ansible
    • 6.2. Utiliser des variables pour récupérer les résultats d’une commande exécutée
    • 6.3. Utiliser des conditions pour contrôler l’exécution des opérations
    • 6.4. Configurer la gestion des erreurs

1. Blocs (blocks) de tâches

Blocks

Les blocs permettent le regroupement logique des tâches et la gestion des erreurs dans le jeu. Tout ce que l’on peut appliquer à une tâche unique peut être appliqué au niveau du bloc ce qui facilite également la définition de données ou de directives communes aux tâches. Cela ne signifie pas que la directive affecte le bloc lui-même, mais elle est héritée par les tâches délimitées dans un bloc. Les directives seront appliqué aux tâches, mais pas au bloc lui-même.

  tasks:
    - name: Install Apache
      block:
        - yum:
            name:
              - httpd
              - memcached
            state: installed
        - template:
            src: templates/src.j2
            dest: /etc/foo.conf
        - service:
            name: bar
            state: started
            enabled: True
      when: ansible_distribution == 'CentOS'
      become: true
      become_user: root

Dans l’exemple ci-dessus, chacune des 3 tâches sera exécutée après l’ajout de la condition when: du bloc et son évaluation dans le contexte de la tâche. En outre, elles héritent des directives relatives à l’élévation des privilèges root (become: et become_user:) .

2. Gestion des exceptions

Les blocs permettent également de gérer les sorties d’erreurs de manière similaire aux exceptions de la plupart des langages de programmation.

  tasks:
    - name: Attempt and graceful roll back demo
      block:
        - debug:
            msg: 'I execute normally'
        - command: /bin/false
        - debug:
            msg: 'I never execute, due to the above task failing'
      rescue:
        - debug:
            msg: 'I caught an error'
        - command: /bin/false
        - debug:
            msg: 'I also never execute :-('
      always:
        - debug:
            msg: "This always executes"

Les tâches du block: s’exécutent normalement.

En cas d’erreur, la section rescue: s’exécute avec tout ce que vous devez faire pour résoudre l’erreur précédente.

La section always: est exécutée quelle que soit l’erreur précédente qui s’est produite ou non dans les sections de block: et rescue:.

Il convient de noter que le jeu continue si une section rescue: s’achève avec succès car elle “efface” le statut de l’erreur (mais n’en fait pas le rapport), ce qui signifie qu’elle ne déclenchera ni les configurations max_fail_percentage ni any_errors_fatal, mais elle apparaîtra dans les statistiques du livre de jeu.

Un autre exemple de la prise en charge des erreurs.

  tasks:
    - name: Attempt and graceful roll back demo
      block:
        - debug:
            msg: 'I execute normally'
          notify: run me even after an error
        - command: /bin/false
      rescue:
        - name: make sure all handlers run
          meta: flush_handlers
  handlers:
    - name: run me even after an error
      debug:
        msg: 'This handler runs even on error'

Ansible fournit également quelques variables pour les tâches de la partie rescue: d’un bloc.

  • ansible_failed_task : La tâche qui a renvoyé “failed” et a déclenché le sauvetage (rescue). Par exemple, pour obtenir le nom, utilisez ansible_failed_task.name.

  • ansible_failed_result Le résultat de routeur capturé de la tâche ayant échoué qui a déclenché le sauvetage. On pourait obtenir cette valeur grâce au mot clé register.

3. Ignorer les tâches en échec

Une tâche qui échoue (failed) arrête la lecture du livre de jeu.

ignore_errors permet d’outrepasser ce comportement.

- name: this will not be counted as a failure
  command: /bin/false
  ignore_errors: yes

4. Contrôler l’état changed

Annulation du résultat “changed”. Lorsqu’un shell, une commande ou un autre module s’exécute, il indique généralement le statut “changed” selon qu’il pense ou non qu’il affecte l’état de la machine.

En fonction du code de retour ou de la sortie, on sait que celui-ci n’a apporté aucune modification et on souhaiterait alors remplacer le résultat “changed” de sorte qu’il n’apparaisse pas dans la sortie du rapport ou ne provoque pas le déclenchement des handlers.

Il s’agit donc d’une condition qui contrôle l’état “changed” certainement en vue de rendre les livres de jeu idempotents.

   - name: Create DB if not exists
     ....
     register: db_create_result
     changed_when: "not db_create_result.stdout|search('already exists. Skipped')"

ou encore :

---
- hosts: web
  tasks:
    - name: "Start the Apache HTTPD Server"
      register: starthttpdout
      shell: "httpd -k start"
      changed_when: "'already running' not in starthttpdout.stdout"
    - debug:
        msg: "{{starthttpdout.stdout}}"

5. Contrôler l’état failed

De manière semblable, failed_when permet de contrôler l’état “failed”.

On trouvera ici un exemple de tâches qui créent un état “failed” qui en temps normal réussi toujours. Il s’agit de les utiliser comme “requirements” en espace de stockage d’un application Weblogic de Oracle.

---
- hosts: app
  tasks:
    - name: Making sure the /tmp has more than 1gb
      shell: "df -h /tmp|grep -v Filesystem|awk '{print $4}'|cut -d G -f1"
      register: tmpspace
      failed_when: "tmpspace.stdout|float < 1"

    - name: Making sure the /opt has more than 4gb
      shell: "df -h /opt|grep -v Filesystem|awk '{print $4}'|cut -d G -f1"
      register: tmpspace
      failed_when: "tmpspace.stdout|float < 4"

    - name: Making sure the Physical Memory more than 2gb
      shell: "cat /proc/meminfo|grep -i memtotal|awk '{print $2/1024/1024}'"
      register: memory
      failed_when: "memory.stdout|float < 2"

6. Tâche en échec et handlers

Une tâche qui échoue arrête la lecture du livre de jeu et empêche la prise en charge de “handlers” notifié par les tâches précédentes qui interviennent à la fin du jeu.

On peut placer la directive force_handlers: True dans le jeu pour qu’une tâche qui échoue n’empêche pas l’exécution de “handlers” notifiés.

Lorsque les “handlers” sont forcés, ils s’exécutent lorsqu’ils sont notifiés, même si une tâche échoue sur cet hôte.

7. Module fail

Le module fail met en échec la progression du jeu avec un message personnalisé.

---
- name: "End play if condition is meet"
  fail:
    msg: "End play with failed status"
  when: variable is defined

Laisser un commentaire