Ansible – Linux Update Status abfragen

Stell dir vor, du könntest mit einem einfachen Skript die Patchstände hunderter Linux-Server abrufen und übersichtlich in einer Tabelle darstellen. Klingt praktisch, oder? Mit diesem kleinen Ansible-Playbook/Skript ist genau das möglich. Es überprüft auf Debian-basierten Linux-Systemen die Anzahl der ausstehenden Updates und sendet die Ergebnisse per E-Mail in tabellarischer Form. So kannst du schnell feststellen, ob ein Server vergessen wurde oder ob die automatisierten Updates reibungslos funktionieren.
Das Skript gibt den Servernamen und die ausstehenden Updates in zahlen aus.

---
- name: Check update status and send email
  hosts: all
  become: yes
  vars:
    mailserver: dein-mailserver
    mail_sender: ansible@example.com
    mail_recipient: admin@example.com

  pre_tasks:
    # Ensure the temporary file for storing update statuses is empty and exists
    - name: Ensure /tmp/all_update_status.txt is empty and exists
      copy:
        content: ""
        dest: /tmp/all_update_status.txt
      delegate_to: localhost
      run_once: true

  tasks:
    # Update the APT cache
    - name: Update the apt cache
      apt:
        update_cache: yes

    # Check for available updates on Debian systems
    - name: Check for available updates on Debian
      shell: apt list --upgradable 2>/dev/null | grep -v 'Listing...'
      register: update_output

    # Ensure update_output.stdout_lines is defined to avoid errors
    - name: Ensure update_output.stdout_lines is defined
      set_fact:
        update_lines: "{{ update_output.stdout_lines | default([]) }}"

    # Format the update status for the current host
    - name: Format update status
      set_fact:
        host_update_status: |
          <tr>
            <td>{{ inventory_hostname }}</td>
            <td>{{ update_lines | length }}</td>
          </tr>
      delegate_to: localhost

    # Add the formatted update status to the consolidated list
    - name: Add host update status to list
      lineinfile:
        path: /tmp/all_update_status.txt
        line: "{{ host_update_status }}"
      delegate_to: localhost

- name: Send consolidated update status email
  hosts: localhost
  gather_facts: no
  vars:
    msmtp_config_path: "/root/.msmtprc"  # Path to the msmtp configuration file
    mail_sender: ansible@example.com
    mail_recipient: admin@example.com
  tasks:
    # Read all update statuses from the temporary file
    - name: Read all update statuses
      command: cat /tmp/all_update_status.txt
      register: all_update_status_content

    # Send the update status email using msmtp
    - name: Send update status email with msmtp
      shell: |
        echo -e "From: {{ mail_sender }}\nTo: {{ mail_recipient }}\nSubject: Debian Update Status\nMIME-Version: 1.0\nContent-Type: text/html\n\n<table border='1'><tr><th>Hostname</th><th>Ausstehende Updates</th></tr>{{ all_update_status_content.stdout }}</table>" | msmtp --file={{ msmtp_config_path }} "{{ mail_recipient }}"
      register: msmtp_result
      ignore_errors: yes

Was das Ansible Skript tut:

  1. Vorbereitende Aufgaben:
    • Das Skript stellt sicher, dass die Datei /tmp/all_update_status.txt auf dem lokalen Rechner existiert und leer ist.
  2. Hauptaufgaben:
    • APT-Cache aktualisieren: Der Cache für Paketlisten wird aktualisiert, um die neuesten Informationen über verfügbare Updates zu erhalten.
    • Verfügbare Updates prüfen: Auf jedem Host werden die verfügbaren Updates abgefragt.
    • Update-Status formatieren: Die Anzahl der ausstehenden Updates wird für jeden Host in eine HTML-Tabellenzeile formatiert.
    • Update-Status sammeln: Diese Tabellenzeilen werden in der temporären Datei /tmp/all_update_status.txt auf dem lokalen Rechner gesammelt.
  3. E-Mail-Versand:
    • Status lesen: Die gesammelten Update-Status werden aus der temporären Datei gelesen.
    • E-Mail senden: Eine E-Mail mit den Update-Informationen wird unter Verwendung von msmtp versendet.

Ausstehende Updates mit Benennung

Möchtest du das das Ansible Playbook nicht nur die Anzahl der Ausstehenden Updates sondern auch die Namen der ausstehenden Updates ausgibt kannst du dieses Skript verwenden.

---
- name: Überprüfe Update-Status und sende E-Mail
  hosts: all
  become: yes
  vars:
    mailserver: dein_mail_server  # Mailserver-Name
    mail_sender: sender@example.com  # Absender-E-Mail-Adresse
    mail_recipient: recipient@example.com  # Empfänger-E-Mail-Adresse

  pre_tasks:
    - name: Sicherstellen, dass /tmp/all_update_status.txt leer ist und existiert
      copy:
        content: ""
        dest: /tmp/all_update_status.txt
      delegate_to: localhost
      run_once: true

  tasks:
    - name: Aktualisiere den apt-Cache
      apt:
        update_cache: yes

    - name: Verfügbarkeit von Updates auf Debian prüfen
      shell: apt list --upgradable 2>/dev/null | grep -v 'Listing...'
      register: update_output

    - name: Sicherstellen, dass update_output.stdout_lines definiert ist
      set_fact:
        update_lines: "{{ update_output.stdout_lines | default([]) }}"

    - name: Update-Status formatieren
      set_fact:
        host_update_status: |
          <tr>
            <td>{{ inventory_hostname }}</td>
            <td>{{ update_lines | length }}</td>
            <td>
              {% for line in update_lines %}
                {{ line }}<br/>
              {% endfor %}
            </td>
          </tr>
      delegate_to: localhost

    - name: Host-Update-Status zur Liste hinzufügen
      lineinfile:
        path: /tmp/all_update_status.txt
        line: "{{ host_update_status }}"
      delegate_to: localhost

- name: Konsolidierten Update-Status per E-Mail senden
  hosts: localhost
  gather_facts: no
  vars:
    msmtp_config_path: "/root/.msmtprc"  # Pfad zur msmtp-Konfigurationsdatei
    mail_sender: sender@example.com  # Absender-E-Mail-Adresse
    mail_recipient: recipient@example.com  # Empfänger-E-Mail-Adresse
  tasks:
    - name: Alle Update-Status lesen
      command: cat /tmp/all_update_status.txt
      register: all_update_status_content

    - name: Update-Status-E-Mail mit msmtp senden
      shell: |
        echo -e "From: {{ mail_sender }}\nTo: {{ mail_recipient }}\nSubject: Debian Update Status\nMIME-Version: 1.0\nContent-Type: text/html\n\n<table border='1'><tr><th>Hostname</th><th>Anzahl der Updates</th><th>Update-Namen</th></tr>{{ all_update_status_content.stdout }}</table>" | msmtp --file={{ msmtp_config_path }} "{{ mail_recipient }}"
      register: msmtp_result
      ignore_errors: yes

Weitere Ansible Playbooks

🤞 1x pro Monat unsere News, Tipps und Tutorials gebündelt direkt in dein Postfach!

Wir senden keinen Spam! Erfahre mehr in unserer Datenschutzerklärung.


Kommentare

4 Antworten zu „Ansible – Linux Update Status abfragen“

  1. Avatar von Kevin

    Hallo Jonathan,

    vielen Dank für deine schnelle Rückmeldung! Das habe ich schon versucht mit folgender Zeile: „localhost ansible_host:127.0.0.1“, allerdings greift das nicht. Muss ich das einfach nur als Gruppe anlegen, mit [localhost] ?

    1. Avatar von Kevin

      Hallo Jonathan,

      ich habe den Fehler gefunden. Bei meinem Test habe ich ein –limit „Gruppe“ als Filter angegeben. Den localhost habe ich im Inventory aber ans Ende geschrieben und deswegen hat er den auch nicht ausgelesen. Klappt jetzt einwandfrei. Vielen vielen Dank!

  2. Avatar von Kevin

    Hallo!

    Zunächst einmal danke für Ihren hervorragenden Blogbeitrag. Bei mir überspringt das Skript immer den letzten Abschnitt „Send consolidated update status email“ mit „skipping: no hosts matched“.

    Wenn ich jedoch mit einem „cat /tmp/all_update_statuses.txt“ die entsprechende Datei aufrufe, sehe ich einen Eintrag (habe es zunächst nur mit einem Server getestet) der in etwa so aussieht:

    server1
    3

    Die Datei enthält also einen Eintrag, trotzdem wird übersprungen. Haben Sie noch einen Tipp für mich?

    Vielen Dank!

    1. Hi Kevin,
      du musst den Ansible Server selbst in der Host-Liste angeben. Dies erfolgt durch Hinzufügen von localhost zur Inventardatei und durch Verweisen auf diese Gruppe im Playbook. Auf diese Weise kann Ansible Aufgaben auf localhost (dem Server selbst) ausführen und der letzte Abschnitt wird nicht mehr übersprungen 🙂

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.