Seite wählen

NETWAYS Blog

Ansible – Use Blocks and Rescue Errors

Ansible is a widely used and powerful open-source configuration and deployment management tool. It can be used for simple repetitive daily tasks or complex application deployments, therefore Ansible is able to cover mostly any situation.

Since version 2.0.0 Ansible introduced the usage of blocks, they provide the possibility to group or rescue failed tasks.
On blocks we can assign most directives which are available for any other task at block level, only loops aren’t available.

- name: Update Systems
  hosts: all
  tasks:
    - name: execute this block only for rhel family hosts
      block:
        - name: install epel repository
          yum:
            name: epel-release
            state: present

        - name: install updates
          yum:
            name: '*'
            state: latest
            exclude: kernel*

      when: ansible_os_family == 'RedHat'
      become: true

When we try to deploy applications, sometimes we need to test connections or if requirements are met. When those tasks fail caused by the negative test result, the playbook by default fails and therefore stops.
To force Ansible to execute all other tasks, we could use the directive ignore_failed: true and checking the return value for any other depending task.

With blocks this is easily solved, by using rescue to catch the error and force a particular tasks to run.
The always will make sure that the listed tasks get executed.


- name: rescue my errors
  hosts: localhost
  tasks:
    - name: Try to reach host
      block:
        - name: "[Try reach DNS] Check Connection over DNS"
          command: ping client01.demo.local -c 2
          register: output
      rescue:
        - name: "[Rescue failed DNS] Check Connection over IP"
          command: ping 192.168.33.1 -c 2
          register: output
      always:
        - debug:
            var: output

To handle more than one rescue statement, the block can be simply used in the rescue section, like in the following example.


  - name: Try to execute skript
    block:
      - name: Check Connection over DNS
        command: ping nclient01.demo.local -c 2
        register: output
    rescue:
      - name: "this will fail"
        block:
          - name: it will be false
            command: /bin/false
            register: output
        rescue:
          - name: "this works"
            command: ping 192.168.33.1 -c 2
            register: output

Try to reduce ignored tasks in failed state with rescue blocks, this reduces the confusion of users when inspecting the output.
As second advice try to reduce code duplication by grouping tasks with similar directives.

Check out our Blog for more awesome posts and if you need help with Ansible send us a message or sign up for one of our trainings!

Thilo Wening
Thilo Wening
Manager Consulting

Thilo hat bei NETWAYS mit der Ausbildung zum Fachinformatiker, Schwerpunkt Systemadministration begonnen und unterstützt nun nach erfolgreich bestandener Prüfung tatkräftig die Kollegen im Consulting. In seiner Freizeit ist er athletisch in der Senkrechten unterwegs und stählt seine Muskeln beim Bouldern. Als richtiger Profi macht er das natürlich am liebsten in der Natur und geht nur noch in Ausnahmefällen in die Kletterhalle.

Warum veranschaulichen wir?

Jedem fällt wohl auf die Schnelle ein Beispiel ein, wo er in seinem Leben schon mal etwas veranschaulicht hat, ob nun für sich Selbst oder für Andere:

  • Das fängt schon in der Schule an; man hält ein Referat über ein kompliziertes Thema und muss dieses seinen Klassenkameraden verständlich erläutern.
  • Man arbeitet in der Uni an einem Text mit einer schier unermessbarer Tiefe und muss sich selbst veranschaulichen, was da nun eigentlich vorgeht.
  • Oder man ist auf der Arbeit in einer Position in der man neue Kollegen in ein Thema einführen muss, um diese nicht mit der Fülle an Informationen zu erschlagen, zieht man zum Vergleich einen ähnlichen, bereits bekannten Ablauf her.

In meinem praktischen Beispiel habe ich das neue Projekt, dass mein Mitazubi und ich nun zu bearbeiten haben.
Wir schreiben im Moment einen “Parser”, der für uns Informationen aus Übersetzungsdateien von Icinga Web 2 auslesen und in eine sortierte Array-Struktur packen soll.
Diese sind in dem .po Format von Poedit strukturiert.
Das sieht ungefähr so aus:
#: /this/is/the/location/toTranslate.php
#| msgid “tranlsate this”
msgid “Translate this.”
“This too, please”
msgtxt “Übersetze dies.”
“Das auch, bitte”
Diese Datei wird nun sortiert nach den verschiedenen Zeilenanfängen, die bereits anzeigen was der sich dahinter befindende String aussagt.
Die Veranschaulichung zur Lösung ist bei uns eine Art Wasserfall/Trichtersystem:
Die Zeile #| msgid “tranlsate this” würde wie folgt sortiert werden
blogpic
 
Im Code haben wir das mit einer sehr verschachtelten Konstruktion mit einigen Switch-Cases gelöst.
(Und dieses Chaos auch schon längst Grundüberholt)

switches
Dies zeigt auch, dass die Visualisierungen die wir machen um uns das Konzept darzustellen teilweise von der Umsetzung her stark abweichen. Solange es uns jedoch hilft die Übersicht zu bewahren, ist eine visuelle Darstellung immer gut.
In den meisten Fällen führt das Programmieren ohne visuelle Umsetzung dazu, dass der Code ungeordnet ist und man viele Fälle übersieht, die man nachher durch “dirty” Fixes wieder zu richten versucht. Das macht den Code unleserlich und führt dazu, dass die gesamte Arbeit umsonst war, da man den Code komplett neu strukturieren und neu schreiben muss.
Dies zeigt sich auch an unserem Projekt. Wir arbeiten gerade an der zweiten Version des Parsers, da wir das Problem in der ersten Version relativ ungeordnet angegangen sind, da wir fälschlicherweise angenommen hatten, dass so ein “kleines” Progrämmchen keiner größeren Planung bedarf. Oh wie wir uns geirrt haben.
Die jetzige Planung hat sich etwas gedehnt…
parser
Also daran denken: erst planen, dann schreiben.

Feu Mourek
Feu Mourek
Developer Advocate

Feu verbrachte seine Kindheit im schönen Steigerwald, bevor es sich aufmachte die Welt zu Erkunden. Seit September 2016 unterstützt es Icinga zunächst als Developer und seit 2020 als Developer Advocate, und NETWAYS als Git und GitLab Trainer. Seine Freizeit verbringt es hauptsächlich damit Video-, und Pen and Paper Rollenspiele zu spielen, sich Häuser zu designen (die es sich nie leisten können wird) oder ganz lässig mit seinem Cabrio durch die Gegend zu düsen.