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:
- Eine einfache Grußnachricht anzeigen
- 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:
- Führt unser Skript
system_info.shmit dem Modulcommandaus - Speichert die Ausgabe in einer Variable namens
script_resultmithilfe des Schlüsselwortsregister - Zeigt die erfasste Ausgabe mit dem Modul
debugan
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 Stringstderr: 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:
- Wir versuchen, ein Verzeichnis aufzulisten, das nicht existiert
- Wir verwenden
ignore_errors: yes, um zu verhindern, dass das Playbook anhält, wenn der Befehl fehlschlägt - Wir überprüfen den Rückgabecode (
cmd_result.rc), um festzustellen, ob der Befehl erfolgreich war oder fehlgeschlagen ist - 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:
- Führt unser Skript
package_info.shaus - Zeigt die Rohausgabe an
- 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:
- Wir erfassen Informationen zur Festplattennutzung
- Wir zeigen immer eine Zusammenfassung an (die ersten beiden Zeilen)
- 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:
- Sie haben eine grundlegende Ansible-Umgebung eingerichtet und Ihr erstes Playbook erstellt
- Sie haben gelernt, wie man Skripte mit den Modulen
commandundshellausführt - Sie haben die Skriptausgabe mithilfe der Direktive
registererfasst - Sie haben die Ausgabe mit dem Modul
debugin verschiedenen Formaten angezeigt - Sie haben Fehlerbedingungen behandelt und die bedingte Ausgabendarstellung implementiert
- 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.


