Fehlerbehandlung mit Blocks, Rescue und Always

AnsibleBeginner
Jetzt üben

Einführung

Ansible-Blöcke gruppieren zusammengehörige Aufgaben. Ein rescue-Abschnitt wird ausgeführt, wenn eine Aufgabe innerhalb des Blocks fehlschlägt, während ein always-Abschnitt in jedem Fall ausgeführt wird.

In diesem Lab erzeugen Sie einen kontrollierten Fehler, führen eine Wiederherstellung durch und führen anschließend dasselbe Playbook ohne den Fehler aus, um den erfolgreichen Pfad zu beobachten.

Ein Projekt zur Fehlerbehandlung erstellen

In diesem Schritt erstellen Sie ein kleines Projekt mit einem lokalen verwalteten Host und einem reports-Verzeichnis für die Marker von block, rescue und always.

cd /home/labex/project
mkdir -p rhce-ansible/{inventory,playbooks,reports}
cd rhce-ansible
cat > ansible.cfg <<'EOF'
[defaults]
inventory = ./inventory/hosts
host_key_checking = False
retry_files_enabled = False
EOF
cat > inventory/hosts <<'EOF'
[managed]
host ansible_connection=local
EOF

Das reports-Verzeichnis dient dazu, dass das Playbook Marker für jeden Pfad schreibt. Dadurch wird das Verhalten der Blöcke sichtbar, ohne dass man sich ausschließlich auf die Terminalausgabe verlassen muss.

Einen Block mit Rescue und Always schreiben

In diesem Schritt schreiben Sie ein Playbook mit einem kontrollierten Fehler. Der Block schlägt fehl, wenn simulate_failure auf true gesetzt ist. Der rescue-Abschnitt schreibt einen Wiederherstellungs-Marker und der always-Abschnitt schreibt einen Audit-Marker. Bevor Sie die Befehle in diesem Schritt ausführen, kehren Sie in das Ansible-Projektverzeichnis zurück. Dies stellt sicher, dass die Befehle stabil bleiben, auch wenn LabEx jeden Schritt separat ausführt.

cd /home/labex/project/rhce-ansible
cat > playbooks/block-rescue.yml <<'EOF'
---
- name: Practice block rescue and always
  hosts: managed
  gather_facts: false
  vars:
    simulate_failure: true
  tasks:
    - name: Remove old markers
      ansible.builtin.file:
        path: "/home/labex/project/rhce-ansible/reports/{{ item }}.txt"
        state: absent
      loop:
        - block-success
        - rescued
        - always

    - name: Protect a risky operation with rescue
      block:
        - name: Run a command that may fail
          ansible.builtin.command: /usr/bin/false
          when: simulate_failure | bool

        - name: Mark block success
          ansible.builtin.copy:
            dest: /home/labex/project/rhce-ansible/reports/block-success.txt
            content: |
              block completed
            mode: '0644'
      rescue:
        - name: Mark rescue path
          ansible.builtin.copy:
            dest: /home/labex/project/rhce-ansible/reports/rescued.txt
            content: |
              rescued controlled failure
            mode: '0644'
      always:
        - name: Mark always path
          ansible.builtin.copy:
            dest: /home/labex/project/rhce-ansible/reports/always.txt
            content: |
              always ran
            mode: '0644'
EOF

Der riskante Befehl ist /usr/bin/false, der immer mit einem Fehler beendet wird. Wenn simulate_failure auf true steht, stoppt der Block bei dieser fehlerhaften Aufgabe, der rescue-Abschnitt schreibt rescued.txt und der always-Abschnitt schreibt in jedem Fall always.txt.

ansible-playbook playbooks/block-rescue.yml --syntax-check

Die Schlüsselwörter block, rescue und always müssen auf derselben Einrückungsebene ausgerichtet sein. Eine Syntaxprüfung ist eine schnelle Methode, um falsch platzierte Abschnitte zu finden, bevor der kontrollierte Fehler ausgeführt wird.

Den Pfad des kontrollierten Fehlers ausführen

In diesem Schritt führen Sie das Playbook mit dem standardmäßig aktivierten Fehler aus. Die Zusammenfassung des Plays (Play Recap) sollte eine gerettete (rescued) Aufgabe anstelle eines fehlgeschlagenen Plays anzeigen. Bevor Sie die Befehle in diesem Schritt ausführen, kehren Sie in das Ansible-Projektverzeichnis zurück.

cd /home/labex/project/rhce-ansible
ansible-playbook playbooks/block-rescue.yml | tee reports/failure-path.txt

Bei diesem Durchlauf sollten in der Zusammenfassung rescued=1 und failed=0 erscheinen. Das bedeutet, dass Ansible einen Fehler innerhalb des Blocks erkannt, die rescue-Aufgaben ausgeführt und das Play insgesamt nicht als fehlgeschlagen gewertet hat.

cat reports/rescued.txt reports/always.txt

Die beiden Marker-Dateien sollten rescued controlled failure und always ran enthalten. Sie sollten block-success.txt in diesem Pfad nicht sehen, da der Block die Aufgabe für den Erfolgs-Marker nicht erreicht hat.

Den Erfolgspfad mit einer zusätzlichen Variable ausführen

In diesem Schritt überschreiben Sie simulate_failure über die Befehlszeile. Der Block sollte normal abgeschlossen werden, rescue sollte nicht ausgeführt werden, aber always sollte weiterhin laufen. Bevor Sie die Befehle in diesem Schritt ausführen, kehren Sie in das Ansible-Projektverzeichnis zurück.

cd /home/labex/project/rhce-ansible
ansible-playbook playbooks/block-rescue.yml -e simulate_failure=false | tee reports/success-path.txt

Die Option -e simulate_failure=false überschreibt die Playbook-Variable nur für diesen Durchlauf. Jetzt wird der false-Befehl übersprungen, der normale Block erreicht block-success.txt und der rescue-Abschnitt sollte nicht ausgeführt werden.

cat reports/block-success.txt reports/always.txt

Der Erfolgspfad sollte block completed und always ran anzeigen. Da das Playbook zu Beginn alte Marker entfernt, sollte rescued.txt nach diesem Durchlauf nicht mehr existieren.

Fehler- und Erfolgsnachweise vergleichen

In diesem Schritt vergleichen Sie die beiden gespeicherten Playbook-Durchläufe. Das Aufbewahren der Nachweise hilft Ihnen bei der Fehlersuche, um festzustellen, welcher Pfad ausgeführt wurde, ohne die gesamte Ausgabe lesen zu müssen. Bevor Sie die Befehle in diesem Schritt ausführen, kehren Sie in das Ansible-Projektverzeichnis zurück.

cd /home/labex/project/rhce-ansible
grep -E 'rescued=|failed=' reports/failure-path.txt reports/success-path.txt

Der Bericht des Fehlerpfads sollte rescued=1 enthalten, während der Bericht des Erfolgspfads rescued=0 enthalten sollte. Beide sollten failed=0 aufweisen, jedoch aus unterschiedlichen Gründen.

ls -1 reports

Die Liste der Berichte sollte beide gespeicherten Playbook-Ausgaben sowie die Marker des letzten Pfads enthalten. Das Aufbewahren beider Ausgaben erleichtert den Vergleich, wie rescue die Zusammenfassung beeinflusst.

Zusammenfassung

Sie haben block-, rescue- und always-Abschnitte verwendet, um einen kontrollierten Fehler zu behandeln, das Playbook anschließend über einen normalen Erfolgspfad ausgeführt und die gespeicherten Nachweise verglichen.