Wie man die Ausgabe eines von Ansible ausgeführten Skripts erfasst

AnsibleBeginner
Jetzt üben

Einführung

Ansible ist ein weit verbreitetes IT-Automatisierungstool, das die Verwaltung komplexer Infrastruktur- und Anwendungsbereitstellungen vereinfacht. In diesem Tutorial werden wir untersuchen, wie man die Ausgabe von Skripten erfasst, die über Ansible Playbooks ausgeführt werden. Diese Fähigkeit ist für die Überwachung, das Debugging und die Analyse der Ergebnisse Ihrer Automatisierungsaufgaben unerlässlich. Am Ende dieses Labs werden Sie verschiedene Techniken verstehen, um die Skriptausgabe in Ihren Ansible-Workflows zu erfassen und zu nutzen.

Einrichten der Ansible-Umgebung

Bevor wir beginnen können, Skriptausgaben mit Ansible zu erfassen, müssen wir eine grundlegende Ansible-Umgebung einrichten. Dies beinhaltet das Erstellen der notwendigen Verzeichnisstruktur und Konfigurationsdateien.

Grundlagen von Ansible verstehen

Ansible funktioniert, indem es sich mit Ziel-Hosts verbindet und kleine Programme, sogenannte Module, ausführt. Diese Module werden auf den Ziel-Hosts ausgeführt und nach Abschluss entfernt. Ansible ist agentenlos, was bedeutet, dass Sie keine spezielle Software auf den verwalteten Knoten installieren müssen.

Beginnen wir mit dem Erstellen eines Projektverzeichnisses und der erforderlichen Ansible-Dateien:

mkdir -p ~/project/ansible-output-demo/scripts
cd ~/project/ansible-output-demo

Erstellen wir nun eine einfache Inventardatei. In Ansible definiert die Inventardatei die Hosts und Hostgruppen, auf denen Befehle, Module und Aufgaben in einem Playbook ausgeführt werden.

Erstellen Sie eine Inventardatei mit dem Code-Editor:

  1. Klicken Sie im IDE in der oberen linken Ecke auf das Menü "Datei"
  2. Wählen Sie "Neue Datei"
  3. Speichern Sie sie als inventory im Verzeichnis ~/project/ansible-output-demo

Fügen Sie der Datei inventory den folgenden Inhalt hinzu:

[local]
localhost ansible_connection=local

Diese Inventardatei gibt an, dass wir Ansible auf dem lokalen Rechner ausführen werden.

Als Nächstes erstellen wir ein einfaches Skript, das eine Ausgabe für uns generiert, die wir erfassen können. Dieses Skript wird:

  1. Einige Systeminformationen ausgeben
  2. Einige Standardausgaben generieren
  3. Einige Standardfehlerausgaben generieren

Erstellen Sie eine neue Datei im Verzeichnis scripts mit dem Namen info.sh:

  1. Klicken Sie auf das Menü "Datei"
  2. Wählen Sie "Neue Datei"
  3. Speichern Sie sie als scripts/info.sh im Verzeichnis ~/project/ansible-output-demo

Fügen Sie der Datei info.sh den folgenden Inhalt hinzu:

#!/bin/bash

## Print system information
echo "=== System Information ==="
echo "Hostname: $(hostname)"
echo "Date: $(date)"
echo "Kernel: $(uname -r)"
echo "Memory:"
free -h

## Generate some standard output
echo "=== Standard Output ==="
echo "This is standard output"
echo "Hello from the script!"

## Generate some standard error
echo "=== Standard Error ===" >&2
echo "This is standard error" >&2
echo "An example error message" >&2

## Exit with a specific code
exit 0

Machen wir nun das Skript ausführbar:

chmod +x ~/project/ansible-output-demo/scripts/info.sh

Führen wir das Skript direkt aus, um zu sehen, welche Ausgabe es erzeugt:

~/project/ansible-output-demo/scripts/info.sh

Sie sollten eine Ausgabe sehen, die Systeminformationen, Standardausgaben und Standardfehlermeldungen enthält.

Jetzt haben wir unsere grundlegende Umgebung eingerichtet. Im nächsten Schritt erstellen wir ein Ansible Playbook, um dieses Skript auszuführen und seine Ausgabe zu erfassen.

Grundlegende Ausgabenerfassung mit Ansible

Nachdem wir unsere Umgebung eingerichtet haben, erstellen wir ein einfaches Ansible Playbook, das unser Skript ausführt und seine Ausgabe erfasst.

Erstellen eines einfachen Playbooks

In Ansible sind Playbooks YAML-Dateien, die eine Reihe von Aufgaben definieren, die auf Remote-Hosts ausgeführt werden sollen. Erstellen wir ein Playbook, das unser info.sh-Skript ausführt und seine Ausgabe mit dem Schlüsselwort register erfasst.

Erstellen Sie eine neue Datei mit dem Namen capture_output.yml im Verzeichnis ~/project/ansible-output-demo:

  1. Klicken Sie auf das Menü "Datei"
  2. Wählen Sie "Neue Datei"
  3. Speichern Sie sie als capture_output.yml im Verzeichnis ~/project/ansible-output-demo

Fügen Sie der Datei capture_output.yml den folgenden Inhalt hinzu:

---
- name: Capture Script Output
  hosts: local
  gather_facts: no

  tasks:
    - name: Execute the info.sh script
      command: "{{ playbook_dir }}/scripts/info.sh"
      register: script_output

    - name: Display the script output
      debug:
        var: script_output.stdout

Betrachten wir dieses Playbook:

  1. Das Playbook zielt auf die Gruppe local ab, die in unserem Inventar definiert ist.
  2. Die erste Aufgabe führt unser info.sh-Skript mit dem Modul command aus.
  3. Das Schlüsselwort register speichert die Ausgabe des Befehls in einer Variable namens script_output.
  4. Die zweite Aufgabe verwendet das Modul debug, um die Standardausgabe (stdout) des Skripts anzuzeigen.

Ausführen des Playbooks

Führen wir nun das Playbook aus, um zu sehen, wie es die Skriptausgabe erfasst und anzeigt:

cd ~/project/ansible-output-demo
ansible-playbook -i inventory capture_output.yml

Sie sollten eine Ausgabe ähnlich der folgenden sehen:

PLAY [Capture Script Output] *******************************************

TASK [Execute the info.sh script] **************************************
changed: [localhost]

TASK [Display the script output] ***************************************
ok: [localhost] => {
    "script_output.stdout": "=== System Information ===\nHostname: ubuntu\nDate: Tue Oct 17 12:34:56 UTC 2023\nKernel: 5.15.0-1031-aws\nMemory:\n              total        used        free      shared  buff/cache   available\nMem:          7.7Gi       1.2Gi       5.2Gi        12Mi       1.3Gi       6.3Gi\nSwap:            0B          0B          0B\n=== Standard Output ===\nThis is standard output\nHello from the script!"
}

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

Beachten Sie, dass nur die Standardausgabe angezeigt wird. Die Standardfehlerausgabe (stderr) wird nicht angezeigt, da wir nur gebeten haben, script_output.stdout anzuzeigen.

Verbesserung der Lesbarkeit der Ausgabe

Die Ausgabe ist als einzelner String etwas schwer zu lesen. Ändern wir unser Playbook, um die Ausgabe in einem besser lesbaren Format mit dem Attribut stdout_lines anzuzeigen, das die Ausgabe als Liste von Zeilen darstellt.

Bearbeiten Sie die Datei capture_output.yml und ändern Sie die zweite Aufgabe wie folgt:

- name: Display the script output
  debug:
    var: script_output.stdout_lines

Führen Sie das Playbook erneut aus:

ansible-playbook -i inventory capture_output.yml

Nun sollte die Ausgabe besser lesbar sein, wobei jede Zeile separat angezeigt wird:

TASK [Display the script output] ***************************************
ok: [localhost] => {
    "script_output.stdout_lines": [
        "=== System Information ===",
        "Hostname: ubuntu",
        "Date: Tue Oct 17 12:34:56 UTC 2023",
        "Kernel: 5.15.0-1031-aws",
        "Memory:",
        "              total        used        free      shared  buff/cache   available",
        "Mem:          7.7Gi       1.2Gi       5.2Gi        12Mi       1.3Gi       6.3Gi",
        "Swap:            0B          0B          0B",
        "=== Standard Output ===",
        "This is standard output",
        "Hello from the script!"
    ]
}

Dieses Format macht die Ausgabe viel einfacher zu lesen und zu verarbeiten. Im nächsten Schritt werden wir untersuchen, wie man verschiedene Arten von Ausgaben erfasst und anzeigt.

Erfassen verschiedener Arten von Ausgaben

Im vorherigen Schritt haben wir die Standardausgabe unseres Skripts erfasst und angezeigt. Bei der Ausführung von Skripten gibt es jedoch verschiedene Arten von Ausgaben, die wir möglicherweise erfassen möchten:

  1. Standardausgabe (stdout): Die normale Ausgabe des Skripts
  2. Standardfehler (stderr): Fehlermeldungen und Warnungen
  3. Rückgabecode (rc): Der Exit-Status des Skripts (0 bedeutet typischerweise Erfolg, Werte ungleich Null weisen auf Fehler hin)

Erstellen wir ein neues Playbook, das alle drei Arten von Ausgaben erfasst und anzeigt.

Erstellen Sie eine neue Datei mit dem Namen capture_all_output.yml im Verzeichnis ~/project/ansible-output-demo:

  1. Klicken Sie auf das Menü "Datei"
  2. Wählen Sie "Neue Datei"
  3. Speichern Sie sie als capture_all_output.yml im Verzeichnis ~/project/ansible-output-demo

Fügen Sie der Datei capture_all_output.yml den folgenden Inhalt hinzu:

---
- name: Capture All Types of Script Output
  hosts: local
  gather_facts: no

  tasks:
    - name: Execute the info.sh script
      command: "{{ playbook_dir }}/scripts/info.sh"
      register: script_output

    - name: Display standard output
      debug:
        msg: "Standard Output (stdout):"

    - name: Display stdout content
      debug:
        var: script_output.stdout_lines

    - name: Display standard error
      debug:
        msg: "Standard Error (stderr):"

    - name: Display stderr content
      debug:
        var: script_output.stderr_lines

    - name: Display return code
      debug:
        msg: "Return Code: {{ script_output.rc }}"

Dieses Playbook führt unser Skript aus und zeigt dann Folgendes an:

  1. Die Standardausgabe mit script_output.stdout_lines
  2. Den Standardfehler mit script_output.stderr_lines
  3. Den Rückgabecode mit script_output.rc

Ausführen des erweiterten Playbooks

Führen wir unser neues Playbook aus:

cd ~/project/ansible-output-demo
ansible-playbook -i inventory capture_all_output.yml

Sie sollten eine umfassende Anzeige aller drei Arten von Ausgaben sehen:

PLAY [Capture All Types of Script Output] *****************************

TASK [Execute the info.sh script] *************************************
changed: [localhost]

TASK [Display standard output] ****************************************
ok: [localhost] => {
    "msg": "Standard Output (stdout):"
}

TASK [Display stdout content] *****************************************
ok: [localhost] => {
    "script_output.stdout_lines": [
        "=== System Information ===",
        "Hostname: ubuntu",
        "Date: Tue Oct 17 12:40:22 UTC 2023",
        "Kernel: 5.15.0-1031-aws",
        "Memory:",
        "              total        used        free      shared  buff/cache   available",
        "Mem:          7.7Gi       1.2Gi       5.2Gi        12Mi       1.3Gi       6.3Gi",
        "Swap:            0B          0B          0B",
        "=== Standard Output ===",
        "This is standard output",
        "Hello from the script!"
    ]
}

TASK [Display standard error] *****************************************
ok: [localhost] => {
    "msg": "Standard Error (stderr):"
}

TASK [Display stderr content] *****************************************
ok: [localhost] => {
    "script_output.stderr_lines": [
        "=== Standard Error ===",
        "This is standard error",
        "An example error message"
    ]
}

TASK [Display return code] ********************************************
ok: [localhost] => {
    "msg": "Return Code: 0"
}

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

Jetzt können wir alle Arten von Ausgaben von unserem Skript sehen:

  • Die Standardausgabe zeigt Systeminformationen und unsere regulären Nachrichten
  • Der Standardfehler zeigt unsere Fehlermeldungen
  • Der Rückgabecode ist 0, was auf eine erfolgreiche Ausführung hindeutet

Erstellen eines Skripts mit Fehlern

Erstellen wir ein Skript, das einen Fehler erzeugt und einen Exit-Code ungleich Null zurückgibt, um zu sehen, wie Ansible damit umgeht.

Erstellen Sie eine neue Datei mit dem Namen error.sh im Verzeichnis scripts:

  1. Klicken Sie auf das Menü "Datei"
  2. Wählen Sie "Neue Datei"
  3. Speichern Sie sie als scripts/error.sh im Verzeichnis ~/project/ansible-output-demo

Fügen Sie der Datei error.sh den folgenden Inhalt hinzu:

#!/bin/bash

## Print some standard output
echo "Starting error demonstration script"
echo "This will appear in stdout"

## Print some standard error
echo "This will appear in stderr" >&2
echo "Error: Something went wrong!" >&2

## Exit with a non-zero code to indicate error
exit 1

Machen Sie das Skript ausführbar:

chmod +x ~/project/ansible-output-demo/scripts/error.sh

Erstellen wir nun ein Playbook, um dieses Skript auszuführen und den Fehler zu behandeln. Erstellen Sie eine neue Datei mit dem Namen handle_errors.yml:

  1. Klicken Sie auf das Menü "Datei"
  2. Wählen Sie "Neue Datei"
  3. Speichern Sie sie als handle_errors.yml im Verzeichnis ~/project/ansible-output-demo

Fügen Sie der Datei handle_errors.yml den folgenden Inhalt hinzu:

---
- name: Handle Script Errors
  hosts: local
  gather_facts: no

  tasks:
    - name: Execute the error script
      command: "{{ playbook_dir }}/scripts/error.sh"
      register: script_output
      ignore_errors: yes

    - name: Display standard output
      debug:
        var: script_output.stdout_lines

    - name: Display standard error
      debug:
        var: script_output.stderr_lines

    - name: Display return code
      debug:
        msg: "Return Code: {{ script_output.rc }}"

    - name: Check if script failed
      debug:
        msg: "The script failed with return code {{ script_output.rc }}"
      when: script_output.rc != 0

Beachten Sie die Hinzufügung von ignore_errors: yes, die Ansible anweist, das Playbook weiterhin auszuführen, auch wenn der Befehl fehlschlägt (einen Exit-Code ungleich Null zurückgibt).

Führen wir dieses Playbook aus:

ansible-playbook -i inventory handle_errors.yml

Sie sollten eine Ausgabe ähnlich der folgenden sehen:

PLAY [Handle Script Errors] *******************************************

TASK [Execute the error script] ***************************************
changed: [localhost]

TASK [Display standard output] ****************************************
ok: [localhost] => {
    "script_output.stdout_lines": [
        "Starting error demonstration script",
        "This will appear in stdout"
    ]
}

TASK [Display standard error] *****************************************
ok: [localhost] => {
    "script_output.stderr_lines": [
        "This will appear in stderr",
        "Error: Something went wrong!"
    ]
}

TASK [Display return code] ********************************************
ok: [localhost] => {
    "msg": "Return Code: 1"
}

TASK [Check if script failed] *****************************************
ok: [localhost] => {
    "msg": "The script failed with return code 1"
}

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

Dieses Beispiel zeigt, wie man:

  1. Ausgabe von einem Skript erfasst, das einen Fehler erzeugt
  2. Die Playbook-Ausführung trotz des Fehlers fortsetzt
  3. Aufgaben bedingt auf der Grundlage des Rückgabecodes des Skripts ausführt

Im nächsten Schritt werden wir erweiterte Anwendungsfälle und Best Practices für die Arbeit mit Skriptausgaben in Ansible untersuchen.

Erweiterte Ausgabeverarbeitung und praktische Anwendungsfälle

Nachdem wir verstanden haben, wie man verschiedene Arten von Ausgaben erfasst, wollen wir einige fortgeschrittenere Techniken zur Verarbeitung und Nutzung der Skriptausgabe in Ansible untersuchen.

Parsen der Ausgabe mit Filtern

Ansible bietet verschiedene Filter, mit denen Sie bestimmte Informationen aus der Skriptausgabe manipulieren und extrahieren können. In diesem Abschnitt werden wir uns einige gängige Filtertechniken ansehen.

Erstellen Sie eine neue Datei mit dem Namen parse_output.yml im Verzeichnis ~/project/ansible-output-demo:

  1. Klicken Sie auf das Menü "Datei"
  2. Wählen Sie "Neue Datei"
  3. Speichern Sie sie als parse_output.yml im Verzeichnis ~/project/ansible-output-demo

Erstellen wir zunächst ein Skript, das strukturierte Ausgaben erzeugt, die wir parsen können. Erstellen Sie eine neue Datei mit dem Namen system_stats.sh:

  1. Klicken Sie auf das Menü "Datei"
  2. Wählen Sie "Neue Datei"
  3. Speichern Sie sie als scripts/system_stats.sh im Verzeichnis ~/project/ansible-output-demo

Fügen Sie der Datei system_stats.sh den folgenden Inhalt hinzu:

#!/bin/bash

## Display CPU info
echo "CPU_MODEL: $(grep 'model name' /proc/cpuinfo | head -1 | cut -d ':' -f2 | xargs)"
echo "CPU_CORES: $(grep -c 'processor' /proc/cpuinfo)"

## Display memory info in GB
mem_total=$(free -g | grep Mem | awk '{print $2}')
echo "MEMORY_GB: $mem_total"

## Display disk usage
disk_usage=$(df -h / | tail -1 | awk '{print $5}' | tr -d '%')
echo "DISK_USAGE_PCT: $disk_usage"

## Display load average
load_avg=$(uptime | awk -F'load average: ' '{print $2}' | cut -d, -f1)
echo "LOAD_AVG: $load_avg"

exit 0

Machen Sie das Skript ausführbar:

chmod +x ~/project/ansible-output-demo/scripts/system_stats.sh

Erstellen wir nun ein Playbook, das dieses Skript ausführt, seine Ausgabe erfasst und es parst, um bestimmte Informationen zu extrahieren:

Fügen Sie der Datei parse_output.yml den folgenden Inhalt hinzu:

---
- name: Parse Script Output
  hosts: local
  gather_facts: no

  tasks:
    - name: Execute the system_stats.sh script
      command: "{{ playbook_dir }}/scripts/system_stats.sh"
      register: stats_output

    - name: Display raw output
      debug:
        var: stats_output.stdout_lines

    - name: Parse CPU model
      set_fact:
        cpu_model: "{{ stats_output.stdout | regex_search('CPU_MODEL: (.+)', '\\1') | first }}"

    - name: Parse CPU cores
      set_fact:
        cpu_cores: "{{ stats_output.stdout | regex_search('CPU_CORES: (\\d+)', '\\1') | first }}"

    - name: Parse memory
      set_fact:
        memory_gb: "{{ stats_output.stdout | regex_search('MEMORY_GB: (\\d+)', '\\1') | first }}"

    - name: Parse disk usage
      set_fact:
        disk_usage: "{{ stats_output.stdout | regex_search('DISK_USAGE_PCT: (\\d+)', '\\1') | first }}"

    - name: Parse load average
      set_fact:
        load_avg: "{{ stats_output.stdout | regex_search('LOAD_AVG: ([0-9.]+)', '\\1') | first }}"

    - name: Display parsed information
      debug:
        msg: |
          Parsed system information:
          - CPU Model: {{ cpu_model }}
          - CPU Cores: {{ cpu_cores }}
          - Memory (GB): {{ memory_gb }}
          - Disk Usage (%): {{ disk_usage }}
          - Load Average: {{ load_avg }}

Dieses Playbook:

  1. Führt unser system_stats.sh-Skript aus
  2. Zeigt die Rohausgabe an
  3. Verwendet den Filter regex_search, um bestimmte Informationen aus der Ausgabe zu extrahieren
  4. Speichert die extrahierten Informationen in Variablen
  5. Zeigt die geparsten Informationen in einem strukturierten Format an

Führen wir dieses Playbook aus:

cd ~/project/ansible-output-demo
ansible-playbook -i inventory parse_output.yml

Sie sollten eine Ausgabe ähnlich der folgenden sehen:

PLAY [Parse Script Output] ********************************************

TASK [Execute the system_stats.sh script] *****************************
changed: [localhost]

TASK [Display raw output] *********************************************
ok: [localhost] => {
    "stats_output.stdout_lines": [
        "CPU_MODEL: Intel(R) Xeon(R) CPU E5-2676 v3 @ 2.40GHz",
        "CPU_CORES: 2",
        "MEMORY_GB: 7",
        "DISK_USAGE_PCT: 58",
        "LOAD_AVG: 0.08"
    ]
}

TASK [Parse CPU model] ************************************************
ok: [localhost]

TASK [Parse CPU cores] ************************************************
ok: [localhost]

TASK [Parse memory] ***************************************************
ok: [localhost]

TASK [Parse disk usage] ***********************************************
ok: [localhost]

TASK [Parse load average] *********************************************
ok: [localhost]

TASK [Display parsed information] *************************************
ok: [localhost] => {
    "msg": "Parsed system information:\n- CPU Model: Intel(R) Xeon(R) CPU E5-2676 v3 @ 2.40GHz\n- CPU Cores: 2\n- Memory (GB): 7\n- Disk Usage (%): 58\n- Load Average: 0.08"
}

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

Entscheidungen basierend auf der Ausgabe treffen

Einer der leistungsstärksten Aspekte der Erfassung der Skriptausgabe ist die Verwendung zur Entscheidungsfindung in Ihren Ansible-Playbooks. Erstellen wir ein Playbook, das die bedingte Ausführung basierend auf der Skriptausgabe demonstriert.

Erstellen Sie eine neue Datei mit dem Namen conditional_actions.yml im Verzeichnis ~/project/ansible-output-demo:

  1. Klicken Sie auf das Menü "Datei"
  2. Wählen Sie "Neue Datei"
  3. Speichern Sie sie als conditional_actions.yml im Verzeichnis ~/project/ansible-output-demo

Fügen Sie den folgenden Inhalt hinzu:

---
- name: Conditional Actions Based on Script Output
  hosts: local
  gather_facts: no

  tasks:
    - name: Execute the system_stats.sh script
      command: "{{ playbook_dir }}/scripts/system_stats.sh"
      register: stats_output

    - name: Parse disk usage
      set_fact:
        disk_usage: "{{ stats_output.stdout | regex_search('DISK_USAGE_PCT: (\\d+)', '\\1') | first | int }}"

    - name: Parse load average
      set_fact:
        load_avg: "{{ stats_output.stdout | regex_search('LOAD_AVG: ([0-9.]+)', '\\1') | first | float }}"

    - name: Display system status
      debug:
        msg: "Current system status: Disk usage: {{ disk_usage }}%, Load average: {{ load_avg }}"

    - name: Warn about high disk usage
      debug:
        msg: "WARNING: Disk usage is high at {{ disk_usage }}%. Consider cleaning up disk space."
      when: disk_usage > 50

    - name: Warn about high load average
      debug:
        msg: "WARNING: Load average is high at {{ load_avg }}. Check for resource-intensive processes."
      when: load_avg > 1.0

    - name: Report healthy system
      debug:
        msg: "System is healthy. All metrics within normal ranges."
      when: disk_usage <= 50 and load_avg <= 1.0

Dieses Playbook:

  1. Führt das Skript system_stats.sh aus
  2. Parst die Werte für die Festplattenauslastung und die Load Average
  3. Zeigt verschiedene Meldungen basierend auf den Werten an:
    • Eine Warnung, wenn die Festplattenauslastung über 50 % liegt
    • Eine Warnung, wenn die Load Average über 1,0 liegt
    • Eine Meldung "gesundes System", wenn alle Metriken innerhalb der normalen Bereiche liegen

Führen wir dieses Playbook aus:

ansible-playbook -i inventory conditional_actions.yml

Die Ausgabe hängt vom aktuellen Zustand Ihres Systems ab, sollte aber bedingte Meldungen basierend auf Ihrer Festplattenauslastung und Load Average enthalten.

Diese Beispiele zeigen, wie Sie:

  1. Bestimmte Informationen aus der Skriptausgabe parsen und extrahieren können
  2. Diese Informationen verwenden können, um Entscheidungen in Ihren Ansible-Playbooks zu treffen
  3. Verschiedene Aktionen basierend auf der Skriptausgabe ausführen können

Diese Techniken sind unerlässlich für die Erstellung dynamischer, reaktionsfähiger Automatisierungs-Workflows, die sich an unterschiedliche Bedingungen und Szenarien anpassen können.

Real-World-Anwendungsfall – System-Health-Check

In diesem letzten Schritt erstellen wir ein vollständiges Real-World-Beispiel, das alles zusammenführt, was wir über das Erfassen und Verarbeiten der Skriptausgabe mit Ansible gelernt haben. Wir erstellen ein System-Health-Check-Tool, das:

  1. Verschiedene Systemmetriken sammelt
  2. Die Metriken analysiert, um potenzielle Probleme zu identifizieren
  3. Einen Gesundheitsbericht generiert
  4. Bei Bedarf Abhilfemaßnahmen ergreift

Erstellen des Health-Check-Skripts

Erstellen wir zunächst ein umfassendes Health-Check-Skript, das verschiedene Systemmetriken sammelt.

Erstellen Sie eine neue Datei mit dem Namen health_check.sh im Verzeichnis scripts:

  1. Klicken Sie auf das Menü "Datei"
  2. Wählen Sie "Neue Datei"
  3. Speichern Sie sie als scripts/health_check.sh im Verzeichnis ~/project/ansible-output-demo

Fügen Sie der Datei health_check.sh den folgenden Inhalt hinzu:

#!/bin/bash

## System Health Check Script

echo "HEALTH_CHECK_START: $(date)"

## CPU load
cpu_load=$(uptime | awk -F'load average: ' '{print $2}' | cut -d, -f1)
echo "CPU_LOAD: $cpu_load"
if (($(echo "$cpu_load > 1.0" | bc -l))); then
  echo "CPU_STATUS: WARNING"
else
  echo "CPU_STATUS: OK"
fi

## Memory usage
mem_total=$(free | grep Mem | awk '{print $2}')
mem_used=$(free | grep Mem | awk '{print $3}')
mem_pct=$(echo "scale=2; $mem_used / $mem_total * 100" | bc)
echo "MEM_USAGE_PCT: $mem_pct"
if (($(echo "$mem_pct > 80" | bc -l))); then
  echo "MEM_STATUS: WARNING"
else
  echo "MEM_STATUS: OK"
fi

## Disk usage
disk_usage=$(df -h / | tail -1 | awk '{print $5}' | tr -d '%')
echo "DISK_USAGE_PCT: $disk_usage"
if [ "$disk_usage" -gt 80 ]; then
  echo "DISK_STATUS: WARNING"
else
  echo "DISK_STATUS: OK"
fi

## Check for zombie processes
zombie_count=$(ps aux | grep -c Z)
echo "ZOMBIE_PROCESSES: $zombie_count"
if [ "$zombie_count" -gt 0 ]; then
  echo "ZOMBIE_STATUS: WARNING"
else
  echo "ZOMBIE_STATUS: OK"
fi

## Check system uptime
uptime_days=$(uptime | awk '{print $3}')
echo "UPTIME_DAYS: $uptime_days"

## Check last 5 log entries for errors
echo "RECENT_ERRORS: $(grep -i error /var/log/syslog 2> /dev/null | tail -5 | wc -l)"

echo "HEALTH_CHECK_END: $(date)"

Machen Sie das Skript ausführbar:

chmod +x ~/project/ansible-output-demo/scripts/health_check.sh

Erstellen des Health-Check-Playbooks

Erstellen wir nun ein umfassendes Playbook, das das Health-Check-Skript ausführt, die Ergebnisse analysiert und basierend auf den Ergebnissen geeignete Maßnahmen ergreift.

Erstellen Sie eine neue Datei mit dem Namen system_health_check.yml im Verzeichnis ~/project/ansible-output-demo:

  1. Klicken Sie auf das Menü "Datei"
  2. Wählen Sie "Neue Datei"
  3. Speichern Sie sie als system_health_check.yml im Verzeichnis ~/project/ansible-output-demo

Fügen Sie der Datei system_health_check.yml den folgenden Inhalt hinzu:

---
- name: System Health Check
  hosts: local
  gather_facts: no

  tasks:
    - name: Execute health check script
      command: "{{ playbook_dir }}/scripts/health_check.sh"
      register: health_check

    - name: Display raw health check output
      debug:
        var: health_check.stdout_lines

    ## Parse metrics from the health check output
    - name: Parse CPU load
      set_fact:
        cpu_load: "{{ health_check.stdout | regex_search('CPU_LOAD: ([0-9.]+)', '\\1') | first | float }}"
        cpu_status: "{{ health_check.stdout | regex_search('CPU_STATUS: (\\w+)', '\\1') | first }}"

    - name: Parse memory usage
      set_fact:
        mem_usage: "{{ health_check.stdout | regex_search('MEM_USAGE_PCT: ([0-9.]+)', '\\1') | first | float }}"
        mem_status: "{{ health_check.stdout | regex_search('MEM_STATUS: (\\w+)', '\\1') | first }}"

    - name: Parse disk usage
      set_fact:
        disk_usage: "{{ health_check.stdout | regex_search('DISK_USAGE_PCT: (\\d+)', '\\1') | first | int }}"
        disk_status: "{{ health_check.stdout | regex_search('DISK_STATUS: (\\w+)', '\\1') | first }}"

    - name: Parse zombie processes
      set_fact:
        zombie_count: "{{ health_check.stdout | regex_search('ZOMBIE_PROCESSES: (\\d+)', '\\1') | first | int }}"
        zombie_status: "{{ health_check.stdout | regex_search('ZOMBIE_STATUS: (\\w+)', '\\1') | first }}"

    ## Generate a health status summary
    - name: Generate health status summary
      set_fact:
        health_status:
          cpu:
            load: "{{ cpu_load }}"
            status: "{{ cpu_status }}"
          memory:
            usage_percent: "{{ mem_usage }}"
            status: "{{ mem_status }}"
          disk:
            usage_percent: "{{ disk_usage }}"
            status: "{{ disk_status }}"
          processes:
            zombie_count: "{{ zombie_count }}"
            status: "{{ zombie_status }}"

    ## Display health summary
    - name: Display health summary
      debug:
        var: health_status

    ## Check overall system status
    - name: Determine overall system status
      set_fact:
        overall_status: "{{ 'WARNING' if (cpu_status == 'WARNING' or mem_status == 'WARNING' or disk_status == 'WARNING' or zombie_status == 'WARNING') else 'OK' }}"

    - name: Display overall system status
      debug:
        msg: "Overall System Status: {{ overall_status }}"

    ## Take remedial actions if necessary
    - name: Recommend actions for CPU issues
      debug:
        msg: "Action recommended: Check for resource-intensive processes using 'top' or 'htop'"
      when: cpu_status == "WARNING"

    - name: Recommend actions for memory issues
      debug:
        msg: "Action recommended: Free up memory by restarting services or clearing cache"
      when: mem_status == "WARNING"

    - name: Recommend actions for disk issues
      debug:
        msg: "Action recommended: Clean up disk space using 'du -sh /* | sort -hr' to identify large directories"
      when: disk_status == "WARNING"

    - name: Recommend actions for zombie processes
      debug:
        msg: "Action recommended: Identify and restart parent processes of zombies"
      when: zombie_status == "WARNING"

    ## Generate health report file
    - name: Create health report directory
      file:
        path: "{{ playbook_dir }}/reports"
        state: directory

    - name: Get current timestamp
      command: date "+%Y%m%d_%H%M%S"
      register: timestamp

    - name: Create health report file
      copy:
        content: |
          System Health Report - {{ timestamp.stdout }}
          ----------------------------------------------

          CPU:
            Load Average: {{ cpu_load }}
            Status: {{ cpu_status }}

          Memory:
            Usage: {{ mem_usage }}%
            Status: {{ mem_status }}

          Disk:
            Usage: {{ disk_usage }}%
            Status: {{ disk_status }}

          Processes:
            Zombie Count: {{ zombie_count }}
            Status: {{ zombie_status }}

          Overall Status: {{ overall_status }}

          Recommendations:
          {% if cpu_status == "WARNING" %}
          - CPU: Check for resource-intensive processes using 'top' or 'htop'
          {% endif %}
          {% if mem_status == "WARNING" %}
          - Memory: Free up memory by restarting services or clearing cache
          {% endif %}
          {% if disk_status == "WARNING" %}
          - Disk: Clean up disk space using 'du -sh /* | sort -hr' to identify large directories
          {% endif %}
          {% if zombie_status == "WARNING" %}
          - Processes: Identify and restart parent processes of zombies
          {% endif %}
          {% if overall_status == "OK" %}
          - System is healthy. No actions required.
          {% endif %}
        dest: "{{ playbook_dir }}/reports/health_report_{{ timestamp.stdout }}.txt"

    - name: Display report location
      debug:
        msg: "Health report saved to {{ playbook_dir }}/reports/health_report_{{ timestamp.stdout }}.txt"

Dieses umfassende Playbook:

  1. Führt unser Health-Check-Skript aus
  2. Parst die verschiedenen Metriken aus der Skriptausgabe
  3. Erstellt eine strukturierte Zusammenfassung des Systemzustands
  4. Bestimmt den Gesamtzustand des Systems basierend auf den einzelnen Komponentenstatus
  5. Gibt spezifische Empfehlungen für erkannte Probleme
  6. Generiert eine detaillierte Gesundheitsberichtdatei mit Zeitstempel

Ausführen des Health Checks

Führen wir unser System-Health-Check-Playbook aus:

cd ~/project/ansible-output-demo
ansible-playbook -i inventory system_health_check.yml

Sie sollten eine detaillierte Ausgabe sehen, die den Systemzustand zusammen mit allen erforderlichen Verbesserungsempfehlungen anzeigt. Die Ausgabe variiert je nach aktuellem Zustand Ihres Systems.

Überprüfen Sie nach dem Ausführen des Playbooks das Berichtsverzeichnis, um den generierten Gesundheitsbericht anzuzeigen:

ls -l ~/project/ansible-output-demo/reports/

Sie sollten eine Datei mit dem Namen health_report_[timestamp].txt sehen. Zeigen Sie den Inhalt dieser Datei an:

cat ~/project/ansible-output-demo/reports/health_report_*.txt

Zusammenfassung dessen, was wir gelernt haben

In diesem Tutorial haben wir gelernt:

  1. Wie man verschiedene Arten von Ausgaben (stdout, stderr, Rückgabecodes) von Skripten erfasst, die von Ansible ausgeführt werden
  2. Wie man mithilfe von Ansible-Filtern bestimmte Informationen aus der Skriptausgabe parst und extrahiert
  3. Wie man die Skriptausgabe verwendet, um Entscheidungen zu treffen und bedingte Aktionen auszuführen
  4. Wie man eine vollständige Real-World-Lösung implementiert, die die Skriptausgabe für die Systemüberwachung nutzt

Diese Techniken sind leistungsstarke Werkzeuge in Ihrem Ansible-Automatisierungs-Toolkit, mit denen Sie anspruchsvolle, dynamische und reaktionsfähige Automatisierungs-Workflows erstellen können.

Zusammenfassung

In diesem Lab haben wir untersucht, wie man die Ausgabe von Skripten, die über Ansible ausgeführt werden, effektiv erfassen und nutzen kann. Wir begannen mit der grundlegenden Ausgabenerfassung mithilfe des Schlüsselworts register und gingen zu fortgeschritteneren Techniken über, wie z. B. dem Parsen der Ausgabe mit Filtern und dem Treffen von Entscheidungen basierend auf den Skriptergebnissen.

Wichtige Erkenntnisse aus diesem Tutorial sind:

  1. Die Fähigkeit, verschiedene Arten von Ausgaben (stdout, stderr, Rückgabecodes) von Skripten zu erfassen, die von Ansible ausgeführt werden
  2. Techniken zum Parsen und Extrahieren spezifischer Informationen aus der Skriptausgabe
  3. Methoden zur bedingten Ausführung von Aufgaben basierend auf der Skriptausgabe
  4. Ein umfassendes Real-World-Beispiel, das zeigt, wie man mit Ansible eine System-Health-Monitoring-Lösung erstellt

Durch die Beherrschung dieser Techniken können Sie anspruchsvollere, dynamischere und reaktionsfähigere Automatisierungs-Workflows erstellen, die sich an unterschiedliche Bedingungen und Szenarien anpassen können. Diese Fähigkeit ist für ein effektives Infrastrukturmanagement, die Anwendungsbereitstellung und die Systemadministration mit Ansible unerlässlich.

Denken Sie bei der Fortsetzung Ihrer Ansible-Reise daran, dass die Erfassung der Skriptausgabe nur eine von vielen leistungsstarken Funktionen ist, die Ansible bietet. Die Erkundung anderer Ansible-Funktionen wie Rollen, Vorlagen und Vault wird Ihr Automatisierungs-Toolkit weiter verbessern.