block, rescue, always)Blöcke in Ansible sind eine Möglichkeit, mehrere Aufgaben (Tasks) zu gruppieren und diese als eine logische Einheit zu behandeln. Dies ist besonders nützlich, wenn es darum geht, Fehlerbehandlung und bedingte Ausführungen in Playbooks zu integrieren. Mit Blöcken können Sie sicherstellen, dass bestimmte Aktionen immer ausgeführt werden, unabhängig davon, ob eine vorherige Aufgabe erfolgreich war oder nicht.
Ein Block besteht aus einer oder mehreren Aufgaben, die
zusammengefasst werden. Zusätzlich können rescue- und
always-Sektionen verwendet werden, um Fehler zu behandeln
und sicherzustellen, dass bestimmte Aufgaben immer ausgeführt
werden.
Beispiel für einen einfachen Block:
---
- name: Beispiel für die Verwendung von Blöcken
hosts: all
tasks:
- name: Block mit mehreren Tasks
block:
- name: Installiere Apache
apt:
name: apache2
state: present
- name: Konfiguriere Apache
lineinfile:
path: /etc/apache2/ports.conf
regexp: '^Listen'
line: "Listen 8080"
rescue:
- name: Fehlerbehandlung, falls ein Fehler auftritt
debug:
msg: "Ein Fehler ist aufgetreten und wurde abgefangen."
always:
- name: Task, der immer ausgeführt wird
debug:
msg: "Dieser Task wird immer ausgeführt, egal ob ein Fehler aufgetreten ist oder nicht."blockDer block-Schlüssel definiert eine Gruppe von Aufgaben,
die als Einheit behandelt werden. Alle Aufgaben in einem Block werden
nacheinander ausgeführt, es sei denn, es tritt ein Fehler auf.
rescueDer rescue-Block wird nur ausgeführt, wenn eine der
Aufgaben im block-Abschnitt fehlschlägt. Dies ist nützlich,
um alternative Aktionen auszuführen oder Fehler zu protokollieren, bevor
das Playbook weiterläuft.
alwaysDer always-Block wird immer ausgeführt, unabhängig
davon, ob eine Aufgabe im block-Abschnitt erfolgreich war
oder nicht. Dies ist ideal, um Aufräumarbeiten oder Protokollierungen
sicherzustellen.
ignore_errors, failed_when)Fehlerbehandlung ist ein wichtiger Aspekt bei der Erstellung robuster Playbooks. Ansible bietet verschiedene Mechanismen, um auf Fehler zu reagieren und Playbooks stabil zu halten.
ignore_errorsMit ignore_errors können Sie Ansible anweisen, einen
Fehler in einer bestimmten Aufgabe zu ignorieren und das Playbook
fortzusetzen.
Beispiel:
- name: Installiere ein Paket, ignoriere Fehler
apt:
name: ein_paket
state: present
ignore_errors: yesIn diesem Beispiel wird das Playbook auch dann fortgesetzt, wenn die Installation des Pakets fehlschlägt.
failed_whenMit failed_when können Sie benutzerdefinierte
Bedingungen definieren, die bestimmen, wann eine Aufgabe als
fehlgeschlagen betrachtet werden soll. Dies ist nützlich, wenn eine Task
erfolgreich sein könnte, aber bestimmte Ergebnisse dennoch als Fehler
behandelt werden sollen.
Beispiel:
- name: Überprüfe den freien Speicherplatz
command: df -h /
register: disk_space
- name: Überprüfe, ob der Speicherplatz kritisch ist
fail:
msg: "Nicht genügend freier Speicherplatz auf der Festplatte."
when: disk_space.stdout.find('100%') != -1In diesem Beispiel wird die Playbook-Ausführung gestoppt, wenn der freie Speicherplatz auf der Festplatte 100 % erreicht.
register und failed_whenDie Kombination von register, when und
failed_when ermöglicht sehr präzise Fehlerbehandlung
basierend auf den tatsächlichen Ergebnissen der ausgeführten
Befehle.
Praxisbeispiel - Webserver-Verfügbarkeitsprüfung:
- name: Prüfe Webserver-Verfügbarkeit
block:
- name: Versuche Verbindung zum Webserver
shell: curl -s -o /dev/null -w "%{http_code}" http://localhost
register: http_result
failed_when: http_result.stdout != "200"
- name: Prüfe Antwortzeit des Webservers
shell: curl -s -o /dev/null -w "%{time_total}" http://localhost
register: response_time
failed_when: response_time.stdout | float > 2.0
rescue:
- name: Webserver-Problem erkannt
debug:
msg: "Webserver antwortet nicht korrekt. HTTP-Code: {{ http_result.stdout | default('unbekannt') }}"
- name: Versuche Webserver-Neustart
service:
name: apache2
state: restartedErweiterte Bedingungen mit mehreren Registervariablen:
- name: System-Gesundheitsprüfung
shell: "{{ item.command }}"
register: health_checks
failed_when:
- health_checks.rc != 0
- "'error' in health_checks.stdout.lower()"
loop:
- { command: "systemctl status apache2" }
- { command: "df -h /" }
- { command: "free -m" }loop, when)Ansible bietet Mechanismen, um Aufgaben basierend auf Bedingungen und Schleifen auszuführen. Dies ermöglicht eine flexible und dynamische Steuerung des Playbook-Ablaufs.
looploop ermöglicht die Wiederholung einer Aufgabe für eine
Liste von Elementen. Dies ist besonders nützlich, wenn Sie dieselbe
Aufgabe für mehrere Elemente ausführen müssen, wie z.B. das Installieren
mehrerer Pakete oder das Erstellen mehrerer Benutzer.
Beispiel für die Verwendung von
loop:
- name: Installiere eine Liste von Paketen
apt:
name: "{{ item }}"
state: present
loop:
- apache2
- mysql-server
- phpIn diesem Beispiel wird die apt-Task für jedes Paket in
der Liste ausgeführt.
whenMit when können Sie bedingte Aufgaben definieren, die
nur ausgeführt werden, wenn eine bestimmte Bedingung erfüllt ist. Dies
ist nützlich, um Aufgaben dynamisch basierend auf Variablenwerten oder
Fakten zu steuern.
Beispiel für die Verwendung von
when:
- name: Installiere Apache nur auf Debian-Systemen
apt:
name: apache2
state: present
when: ansible_os_family == "Debian"In diesem Beispiel wird Apache nur installiert, wenn das Betriebssystem ein Debian-Derivat ist.
loop und whenSie können loop und when kombinieren, um
Aufgaben basierend auf Bedingungen für jedes Element in einer Liste
auszuführen.
Beispiel:
- name: Installiere Pakete auf Debian-Systemen
apt:
name: "{{ item }}"
state: present
loop:
- apache2
- mysql-server
- php
when: ansible_os_family == "Debian"Hier wird jedes Paket in der Liste nur dann installiert, wenn das Betriebssystem des Zielhosts Debian ist.
Eine gute Fehlerbehandlung ist entscheidend, um Playbooks robust und zuverlässig zu gestalten. Durch die Implementierung von Fehlerbehandlungsstrategien können Sie sicherstellen, dass Ihr Playbook auch in Ausnahmefällen stabil bleibt und dass Probleme frühzeitig erkannt und behoben werden.
Verwendung von block, rescue,
always: Nutzen Sie Blöcke, um sicherzustellen,
dass zusammenhängende Aufgaben als Einheit behandelt werden, und um
Fehler gezielt abzufangen und zu behandeln.
Nutzung von failed_when mit
register: Definieren Sie klare Bedingungen
basierend auf tatsächlichen Kommando-Ergebnissen, unter denen eine
Aufgabe als fehlgeschlagen betrachtet wird.
Aufräumarbeiten: Verwenden Sie den
always-Block, um sicherzustellen, dass Aufräumarbeiten oder
Protokollierungen auch bei Fehlern durchgeführt werden.
Verwendung von ignore_errors mit
Vorsicht: Verwenden Sie ignore_errors nur in
Situationen, in denen ein Fehler wirklich ignoriert werden kann, ohne
den weiteren Ablauf des Playbooks zu gefährden.
Logging und Debugging: Nutzen Sie Debug- und Log-Module, um im Fehlerfall detaillierte Informationen zu sammeln und Probleme leichter diagnostizieren zu können.
Proaktive Statusprüfungen: Verwenden Sie
register in Kombination mit Bedingungen, um Systemzustände
zu prüfen, bevor kritische Operationen ausgeführt werden.
Beispiel für eine umfassende Fehlerbehandlung:
---
- name: Beispiel für umfassende Fehlerbehandlung
hosts: all
tasks:
- name: Block mit Fehlerbehandlung
block:
- name: Prüfe Systemvoraussetzungen
shell: systemctl is-active network
register: network_status
failed_when: network_status.stdout != "active"
- name: Installiere Apache
apt:
name: apache2
state: present
- name: Konfiguriere Apache
lineinfile:
path: /etc/apache2/ports.conf
regexp: '^Listen'
line: "Listen 8080"
- name: Teste Apache-Konfiguration
shell: apache2ctl configtest
register: config_test
failed_when: config_test.rc != 0
rescue:
- name: Logge detaillierte Fehlerinformationen
debug:
msg: |
Ein Fehler ist aufgetreten:
- Netzwerkstatus: {{ network_status.stdout | default('unbekannt') }}
- Apache-Konfiguration: {{ config_test.stderr | default('nicht getestet') }}
- name: Versuche Rollback
apt:
name: apache2
state: absent
ignore_errors: yes
always:
- name: Protokolliere Abschluss und Systemstatus
debug:
msg: "Playbook abgeschlossen. Systemzeit: {{ ansible_date_time.iso8601 }}"Die in diesem Kapitel behandelten Konzepte - block,
rescue, always, loop und
when - sind auch innerhalb von Rollen einsetzbar und
ermöglichen dort eine modularisierte, wiederverwendbare
Fehlerbehandlung. In Rollen können Sie diese Mechanismen nutzen, um:
Dies wird besonders relevant, wenn Sie komplexe, mehrschichtige Anwendungsdeployments mit Ansible automatisieren möchten.