Wie man die Skriptausgabe in einem Ansible Playbook anzeigt

AnsibleAnsibleBeginner
Jetzt üben

💡 Dieser Artikel wurde von AI-Assistenten übersetzt. Um die englische Version anzuzeigen, können Sie hier klicken

Einführung

Ansible ist ein leistungsstarkes Automatisierungstool, das Systemadministratoren und Entwicklern hilft, die Infrastruktur effizient zu verwalten. Beim Ausführen von Skripten oder Befehlen über Ansible Playbooks ist es oft entscheidend, deren Ausgabe zu erfassen und anzuzeigen, um sie zu überwachen und Fehler zu beheben.

In diesem praktischen Lab werden Sie lernen, wie Sie die Skriptausgabe in Ihren Ansible Playbooks effektiv anzeigen können. Wir beginnen mit den Grundlagen der Ansible Playbook-Struktur, untersuchen dann verschiedene Techniken zum Erfassen und Anzeigen von Befehlsausgaben und behandeln schließlich einige fortgeschrittene Methoden zum Formatieren und Filtern von Ausgabedaten.

Am Ende dieses Labs werden Sie praktische Erfahrungen mit verschiedenen Ansätzen zur Handhabung der Skriptausgabe in Ansible haben, sodass Sie informativere und leichter zu debuggende Automatisierungs-Workflows erstellen können.

Einrichten Ihres ersten Ansible Playbooks

Bevor wir untersuchen können, wie man die Skriptausgabe anzeigt, müssen wir eine grundlegende Ansible-Umgebung einrichten und unser erstes Playbook erstellen.

Installieren von Ansible

Beginnen wir damit, sicherzustellen, dass Ansible auf unserem System installiert ist:

sudo apt update
sudo apt install -y ansible

Dieser Befehl installiert Ansible auf Ihrem Ubuntu-System. Sobald die Installation abgeschlossen ist, überprüfen Sie sie, indem Sie die Ansible-Version überprüfen:

ansible --version

Sie sollten eine Ausgabe ähnlich der folgenden sehen, die bestätigt, dass Ansible korrekt installiert ist:

ansible [core 2.12.x]
  config file = /etc/ansible/ansible.cfg
  configured module search path = ['/home/labex/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3/dist-packages/ansible
  ansible collection location = /home/labex/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/bin/ansible
  python version = 3.10.x (default, Mar 14 2023, 14:50:41) [GCC 11.3.0]
  jinja version = 3.0.3
  libyaml = True

Verstehen des Ansible Inventory

Ansible muss wissen, mit welchen Hosts es sich verbinden soll. Für dieses Lab verwenden wir eine einfache Inventory-Datei, die nur die lokale Maschine enthält.

Erstellen Sie ein Verzeichnis für unser Ansible-Projekt:

mkdir -p ~/project/ansible-lab
cd ~/project/ansible-lab

Erstellen Sie nun eine Inventory-Datei namens inventory.ini:

echo "localhost ansible_connection=local" > inventory.ini

Diese Inventory-Datei weist Ansible an, Befehle auf der lokalen Maschine auszuführen, ohne SSH zu verwenden.

Erstellen Ihres ersten Playbooks

Lassen Sie uns nun ein grundlegendes Ansible Playbook erstellen. Erstellen Sie in der WebIDE eine neue Datei namens first_playbook.yml im Verzeichnis ~/project/ansible-lab mit folgendem Inhalt:

---
- name: My First Ansible Playbook
  hosts: localhost
  gather_facts: yes

  tasks:
    - name: Display a simple message
      debug:
        msg: "Hello from Ansible!"

    - name: Display system information
      debug:
        msg: "You are running {{ ansible_distribution }} {{ ansible_distribution_version }}"

Dieses einfache Playbook hat zwei Aufgaben:

  1. Eine einfache Grußnachricht anzeigen
  2. Informationen über das Betriebssystem anzeigen, das Sie ausführen

Lassen Sie uns dieses Playbook ausführen, um zu sehen, wie es funktioniert:

cd ~/project/ansible-lab
ansible-playbook -i inventory.ini first_playbook.yml

Sie sollten eine Ausgabe ähnlich dieser sehen:

PLAY [My First Ansible Playbook] *********************************************************

TASK [Gathering Facts] *******************************************************************
ok: [localhost]

TASK [Display a simple message] **********************************************************
ok: [localhost] => {
    "msg": "Hello from Ansible!"
}

TASK [Display system information] ********************************************************
ok: [localhost] => {
    "msg": "You are running Ubuntu 22.04"
}

PLAY RECAP *******************************************************************************
localhost                  : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

Diese Ausgabe zeigt:

  • Das Playbook wurde erfolgreich ausgeführt
  • Alle Aufgaben wurden mit dem Status "ok" abgeschlossen
  • Die Ausgabe von jeder Debug-Aufgabe wird angezeigt

Nachdem wir nun ein grundlegendes Playbook zum Laufen gebracht haben, können wir detaillierter untersuchen, wie man Skripte ausführt und deren Ausgabe anzeigt.

Skripte ausführen und Ausgabe erfassen

Nachdem wir nun eine grundlegende Ansible-Umgebung eingerichtet haben, wollen wir untersuchen, wie man Skripte ausführt und deren Ausgabe mithilfe der Module command und shell erfasst.

Der Unterschied zwischen Command- und Shell-Modulen

Ansible bietet zwei Hauptmodule zum Ausführen von Befehlen:

  • command: Führt einen Befehl auf einem Remote-Knoten aus, ohne eine Shell zu durchlaufen, was bedeutet, dass Shell-Operatoren wie |, >, <, und & nicht funktionieren.
  • shell: Führt einen Befehl über eine Shell aus, wodurch Shell-Operatoren und Umgebungsvariablen verwendet werden können.

Erstellen eines einfachen Skripts zum Ausführen

Zuerst erstellen wir ein einfaches Shell-Skript, das wir mit Ansible ausführen können. Erstellen Sie eine Datei namens system_info.sh in Ihrem Verzeichnis ~/project/ansible-lab:

cd ~/project/ansible-lab

Erstellen Sie in der WebIDE die Datei mit folgendem Inhalt:

#!/bin/bash

echo "=== System Information ==="
echo "Hostname: $(hostname)"
echo "Kernel Version: $(uname -r)"
echo "CPU Info: $(grep 'model name' /proc/cpuinfo | head -1 | cut -d':' -f2 | xargs)"
echo "Memory Info: $(free -h | grep Mem | awk '{print $2 " total, " $3 " used, " $4 " free"}')"
echo "Disk Usage: $(df -h / | grep / | awk '{print $5 " of " $2 " used"}')"

Machen Sie das Skript ausführbar:

chmod +x ~/project/ansible-lab/system_info.sh

Führen wir nun dieses Skript manuell aus, um zu sehen, welche Ausgabe es erzeugt:

./system_info.sh

Sie sollten eine Ausgabe ähnlich der folgenden sehen:

=== System Information ===
Hostname: labex-xxxxxxxx
Kernel Version: 5.15.0-xx-generic
CPU Info: Intel(R) Xeon(R) xxxxxx
Memory Info: 8.0G total, 1.2G used, 5.8G free
Disk Usage: 15% of 50G used

Ausführen des Skripts mit Ansible

Erstellen wir nun ein neues Playbook, das dieses Skript ausführt und seine Ausgabe erfasst. Erstellen Sie eine Datei namens script_output.yml in Ihrem Verzeichnis ~/project/ansible-lab:

---
- name: Run Script and Capture Output
  hosts: localhost
  gather_facts: no

  tasks:
    - name: Run system info script
      command: ./system_info.sh
      register: script_result

    - name: Display script output
      debug:
        msg: "{{ script_result.stdout }}"

Dieses Playbook tut zwei Dinge:

  1. Führt unser Skript system_info.sh mit dem Modul command aus
  2. Speichert die Ausgabe in einer Variable namens script_result mithilfe des Schlüsselworts register
  3. Zeigt die erfasste Ausgabe mit dem Modul debug an

Lassen Sie uns dieses Playbook ausführen:

cd ~/project/ansible-lab
ansible-playbook -i inventory.ini script_output.yml

Sie sollten eine Ausgabe ähnlich der folgenden sehen:

PLAY [Run Script and Capture Output] ***************************************************

TASK [Run system info script] ***********************************************************
changed: [localhost]

TASK [Display script output] ************************************************************
ok: [localhost] => {
    "msg": "=== System Information ===\nHostname: labex-xxxxxxxx\nKernel Version: 5.15.0-xx-generic\nCPU Info: Intel(R) Xeon(R) xxxxxx\nMemory Info: 8.0G total, 1.2G used, 5.8G free\nDisk Usage: 15% of 50G used"
}

PLAY RECAP *****************************************************************************
localhost                  : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

Beachten Sie, wie die Ausgabe als einzelner String mit Zeilenumbruchzeichen (\n) erscheint. Verbessern wir die Anzeige im nächsten Abschnitt.

Verstehen der Register-Variable

Das Schlüsselwort register erstellt eine Variable, die mehrere Attribute enthält, nicht nur die Ausgabe des Befehls. Erstellen wir ein neues Playbook, um diese Attribute zu untersuchen.

Erstellen Sie eine Datei namens register_details.yml in Ihrem Verzeichnis ~/project/ansible-lab:

---
- name: Explore Register Variable
  hosts: localhost
  gather_facts: no

  tasks:
    - name: Run system info script
      command: ./system_info.sh
      register: script_result

    - name: Display all register properties
      debug:
        var: script_result

    - name: Display just stdout
      debug:
        var: script_result.stdout

    - name: Display stdout as a list of lines
      debug:
        var: script_result.stdout_lines

Führen Sie dieses Playbook aus:

ansible-playbook -i inventory.ini register_details.yml

Sie sehen eine detailliertere Ausgabe, die alle Eigenschaften der Variable script_result zeigt, einschließlich:

  • stdout: Die Standardausgabe als einzelner String
  • stderr: Die Standardfehlerausgabe (falls vorhanden)
  • rc: Der Rückgabecode (0 bedeutet Erfolg)
  • stdout_lines: Die Standardausgabe aufgeteilt in eine Liste von Zeilen

Die letzte Aufgabe ist besonders nützlich, da sie die Ausgabe als Liste von Zeilen formatiert, was sie viel lesbarer macht.

Fortgeschrittene Techniken zur Ausgabeverarbeitung

Nachdem wir die Grundlagen der Erfassung der Skriptausgabe verstanden haben, wollen wir einige fortgeschrittenere Techniken zur Verarbeitung und Anzeige der Ausgabe in Ansible Playbooks untersuchen.

Umgang mit Skriptfehlern

Beim Ausführen von Skripten ist es wichtig, Fehlerbedingungen richtig zu behandeln. Ansible markiert eine Aufgabe als fehlgeschlagen, wenn der Befehl einen Wert ungleich Null als Exit-Code zurückgibt. Erstellen wir ein Playbook, das die Fehlerbehandlung demonstriert.

Erstellen Sie eine Datei namens error_handling.yml in Ihrem Verzeichnis ~/project/ansible-lab:

---
- name: Handling Script Errors
  hosts: localhost
  gather_facts: no

  tasks:
    - name: Run a command that might fail
      command: ls /nonexistent_directory
      register: cmd_result
      ignore_errors: yes

    - name: Show error message if command failed
      debug:
        msg: "Command failed with error: {{ cmd_result.stderr }}"
      when: cmd_result.rc != 0

    - name: Show success message if command succeeded
      debug:
        msg: "Command succeeded with output: {{ cmd_result.stdout }}"
      when: cmd_result.rc == 0

In diesem Playbook:

  1. Wir versuchen, ein Verzeichnis aufzulisten, das nicht existiert
  2. Wir verwenden ignore_errors: yes, um zu verhindern, dass das Playbook anhält, wenn der Befehl fehlschlägt
  3. Wir überprüfen den Rückgabecode (cmd_result.rc), um festzustellen, ob der Befehl erfolgreich war oder fehlgeschlagen ist
  4. Wir zeigen entsprechende Meldungen basierend auf dem Ergebnis an

Lassen Sie uns dieses Playbook ausführen:

cd ~/project/ansible-lab
ansible-playbook -i inventory.ini error_handling.yml

Sie sollten eine Ausgabe ähnlich der folgenden sehen:

PLAY [Handling Script Errors] ***********************************************************

TASK [Run a command that might fail] ***************************************************
fatal: [localhost]: FAILED! => {"changed": true, "cmd": ["ls", "/nonexistent_directory"], "delta": "0:00:00.003398", "end": "2023-09-15 12:34:56.789012", "msg": "non-zero return code", "rc": 2, "start": "2023-09-15 12:34:56.785614", "stderr": "ls: cannot access '/nonexistent_directory': No such file or directory", "stderr_lines": ["ls: cannot access '/nonexistent_directory': No such file or directory"], "stdout": "", "stdout_lines": []}
...ignoring

TASK [Show error message if command failed] *********************************************
ok: [localhost] => {
    "msg": "Command failed with error: ls: cannot access '/nonexistent_directory': No such file or directory"
}

TASK [Show success message if command succeeded] ****************************************
skipping: [localhost]

PLAY RECAP *******************************************************************************
localhost                  : ok=2    changed=0    unreachable=0    failed=0    skipped=1    rescued=0    ignored=1

Beachten Sie, dass das Playbook trotz des Fehlschlagens des Befehls weiterläuft und die Fehlermeldung anzeigt.

Formatieren von mehrzeiliger Ausgabe

Erstellen wir ein komplexeres Skript, das mehrzeilige Ausgabe generiert, und formatieren wir es dann in unserem Playbook ansprechend.

Erstellen Sie eine Datei namens package_info.sh in Ihrem Verzeichnis ~/project/ansible-lab:

#!/bin/bash

echo "TOP 5 LARGEST INSTALLED PACKAGES"
echo "================================"
dpkg-query -W -f='${Installed-Size}\t${Package}\n' | sort -n -r | head -5

Machen Sie es ausführbar:

chmod +x ~/project/ansible-lab/package_info.sh

Erstellen Sie nun ein Playbook, um dieses Skript auszuführen und die Ausgabe ansprechend zu formatieren. Erstellen Sie eine Datei namens formatted_output.yml:

---
- name: Format Script Output
  hosts: localhost
  gather_facts: no

  tasks:
    - name: Run package info script
      shell: ./package_info.sh
      register: pkg_info

    - name: Display raw output
      debug:
        msg: "{{ pkg_info.stdout }}"

    - name: Display formatted output with a title
      debug:
        msg: |
          Below is the package information:
          --------------------------------
          {% for line in pkg_info.stdout_lines %}
          {{ line }}
          {% endfor %}
          --------------------------------
          Total lines: {{ pkg_info.stdout_lines | length }}

Dieses Playbook:

  1. Führt unser Skript package_info.sh aus
  2. Zeigt die Rohausgabe an
  3. Verwendet eine Jinja2-Vorlage, um die Ausgabe mit einem Titel und einer Fußzeile zu formatieren

Lassen Sie uns es ausführen:

ansible-playbook -i inventory.ini formatted_output.yml

Sie sollten eine ansprechend formatierte Ausgabe sehen:

PLAY [Format Script Output] ***********************************************************

TASK [Run package info script] ********************************************************
changed: [localhost]

TASK [Display raw output] *************************************************************
ok: [localhost] => {
    "msg": "TOP 5 LARGEST INSTALLED PACKAGES\n================================\n112233\tsome-large-package\n99887\tanother-package\n...\n"
}

TASK [Display formatted output with a title] ******************************************
ok: [localhost] => {
    "msg": "Below is the package information:\n--------------------------------\nTOP 5 LARGEST INSTALLED PACKAGES\n================================\n112233\tsome-large-package\n99887\tanother-package\n...\n--------------------------------\nTotal lines: 7"
}

PLAY RECAP ****************************************************************************
localhost                  : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

Bedingtes Anzeigen der Ausgabe

Manchmal möchten Sie die Ausgabe nur unter bestimmten Bedingungen anzeigen, z. B. im ausführlichen Modus. Sehen wir uns an, wie das geht.

Erstellen Sie eine Datei namens conditional_output.yml in Ihrem Verzeichnis ~/project/ansible-lab:

---
- name: Conditional Output Display
  hosts: localhost
  gather_facts: yes

  tasks:
    - name: Get disk usage information
      shell: df -h
      register: disk_info

    - name: Display disk usage (always shown)
      debug:
        msg: "{{ disk_info.stdout_lines[0:2] }}"

    - name: Display detailed disk usage (only in verbose mode)
      debug:
        msg: "{{ disk_info.stdout_lines }}"
        verbosity: 1

In diesem Playbook:

  1. Wir erfassen Informationen zur Festplattennutzung
  2. Wir zeigen immer eine Zusammenfassung an (die ersten beiden Zeilen)
  3. Wir zeigen die vollständigen Details nur im ausführlichen Modus an (mit dem Flag -v)

Führen wir es zuerst im normalen Modus aus:

ansible-playbook -i inventory.ini conditional_output.yml

Führen wir es nun im ausführlichen Modus aus:

ansible-playbook -i inventory.ini conditional_output.yml -v

Sie werden feststellen, dass Sie im ausführlichen Modus die vollständigen Informationen zur Festplattennutzung erhalten, während Sie im normalen Modus nur die Zusammenfassung sehen.

Diese Technik ist nützlich, um potenziell sensible oder überwältigende Ausgaben standardmäßig auszublenden und sie dennoch bei Bedarf zur Fehlerbehebung verfügbar zu machen.

Zusammenfassung

In diesem Lab haben Sie verschiedene Techniken zum Erfassen und Anzeigen der Skriptausgabe in Ansible Playbooks gelernt:

  1. Sie haben eine grundlegende Ansible-Umgebung eingerichtet und Ihr erstes Playbook erstellt
  2. Sie haben gelernt, wie man Skripte mit den Modulen command und shell ausführt
  3. Sie haben die Skriptausgabe mithilfe der Direktive register erfasst
  4. Sie haben die Ausgabe mit dem Modul debug in verschiedenen Formaten angezeigt
  5. Sie haben Fehlerbedingungen behandelt und die bedingte Ausgabendarstellung implementiert
  6. Sie haben Formatierungstechniken angewendet, um die Ausgabe lesbarer zu machen

Diese Fähigkeiten ermöglichen es Ihnen, informativere Ansible Playbooks zu erstellen, die während der Ausführung klares Feedback geben. Diese Transparenz ist sowohl für die Überwachung automatisierter Prozesse als auch für die Fehlerbehebung bei auftretenden Problemen von entscheidender Bedeutung.

Durch die Nutzung dieser Techniken zur Ausgabeverarbeitung können Sie robustere Automatisierungs-Workflows erstellen, die nicht nur Aufgaben ausführen, sondern auch klar kommunizieren, was in jedem Schritt geschieht. Dies macht Ihre Automatisierung transparenter und einfacher zu warten, insbesondere wenn Sie in Teamumgebungen oder mit komplexer Infrastruktur arbeiten.