Vollkommen zu Recht hat sich Ansible einen hervorragenden Ruf als Werkzeug zum Konfigurationsmanagement erstritten. Dank Playbooks geraten Updates fast zum Kinderspiel.
Niemand patcht gern Server – zumindest kenne ich keine Person, die das von sich behauptet. Und ich möchte betonen, dass ich von Linux-Maschinen spreche. Wenn ich mich umsehe, dann gehören Windows-Nutzer und -Nutzerinnen allzu oft zu den größten Verweigerern, was System-Updates angeht. Vor diesem Hintergrund verwundert es kaum, dass Redmond inzwischen Zwangsaktualisierungen verteilt. Grundsätzlich sind es nicht einmal die Patches selbst, die bei den Betroffenen Magendruck, Sodbrennen und Kopfschmerzen hervorrufen. Die tatsächliche Ursache dafür liegt vielmehr in den dadurch entstehenden Downtimes. Wie viele Tassen Kaffee dauert dieses Update denn?
Security-Patches gelten heute unumstritten als zwingend notwendig, mindestens bei Systemen an vorderster Front wie Webservern, Firewalls, Load Balancern, Mailservern und so weiter. Doch auch im Winter 2025 höre ich immer noch Stimmen, die (sinngemäß) sagen: “Da muss man aber die Kirche im Dorf lassen. Diese Maschinen sind ja aus dem Internet gar nicht zu erreichen und stehen ganz hinten im LAN.”
Eine Weile mag das gut gehen, bis ganz hinten im LAN jemand auf die Idee kommt, den schicken USB-Stick, der vorhin im Raucherbereich lag, am Firmen-PC einzustecken. Oder den scheinbar völlig harmlosen E-Mail-Anhang zu öffnen – immerhin hat die Firma ja eine sündhaft teure, State-of-the-Art-Endpoint-Security-Lösung beschafft. In solchen Fällen nutzt dann der schönste, güldene Karton im Regal nichts. Wer hat stark segmentierte Netze im Backoffice? Wessen LAN-Buchsen sind mit MAC-Filtern versehen? Wer deaktiviert USB-Ports oder schließt gar die Computer in Metallkäfige ein? Der Gedanke daran, dass Anwender Malware in die Herzkammern des Unternehmens einschleppen, dürfte manchem Admin flugs die Schweißperlen auf die Stirn treiben.
Vor dem Hintergrund solcher Horrorszenarien schadet es nicht, sich mit ganz realen und scheinbar banalen Dingen auseinanderzusetzen. Dazu gehört unter anderem das Thema massenhafter Aktualisierungen. Es spielt besonders dann eine wichtige Rolle, wenn man eben nicht über mächtige, aber unter Umständen teure Tools verfügt wie den Suse Manager [1] oder Uyuni [2]. In einem solchen Fall lohnt sich ein Blick auf Ansible [3].
Inventory
Der Einstieg in Ansible beginnt stets mit dem Inventory. Das gilt unabhängig davon, ob Sie mit bestehender Infrastruktur einsteigen oder auf der sprichwörtlichen grünen Wiese stehen.
Das Ansible-Inventar enthält im Idealfall irgendwann alle Hosts. Ich spreche bewusst nicht von allen relevanten Hosts. Wer sich näher mit dieser Form der Automatisierung beschäftigt, erkennt, dass dabei eher irrelevante Systeme keine Mehrarbeit bedeuten. Eine typische Inventory-Datei (Listing 1) sieht manchmal relativ simpel aus. Sie lässt sich sowohl in YAML [4] strukturieren als auch im INI-Format. Das hat letztlich keinen Einfluss auf das Ergebnis. Für den vorliegenden Artikel habe ich mich für YAML entschieden.
Listing 1
Inventory-Datei
---
servers:
children:
debian_servers:
hosts:
# Pi-hole
pihole:
ansible_ssh_private_key_file: /home/treuss/.ssh/pihole
ansible_user: thomas
# Gitea
raspi03:
ansible_ssh_private_key_file: /home/treuss/.ssh/raspi03
ansible_user: thomas
# Backup
raspi06:
ansible_ssh_private_key_file: /home/treuss/.ssh/raspi06
ansible_user: thomas
dns_servers:
hosts:
# Pi-hole
pihole:
ansible_ssh_private_key_file: /home/treuss/.ssh/pihole
ansible_user: thomas
Wie in Listing 1 nachzuvollziehen, definiere ich in einem Inventory meine Hosts. Den schematischen Aufbau entnehmen Sie bitte Abbildung 1. Im konkreten Fall handelt es sich um das Inventory »servers.yml«. Wie der Dateiname bereits andeutet, befinden sich darin nur Server. Auf welche Weise Sie Ihre Hosts untergliedern, bleibt Ihnen selbst überlassen. Ich unterscheide im Beispiel zwischen »debian_servers« (Zeile 4) und »dns_servers« (Zeile 18) – aus gutem Grund: Zwar betreibe ich bis dato ausschließlich Debian-Server, möchte mir andererseits aber die Möglichkeit offenhalten, zum Beispiel eine Maschine auf Suse- oder Gentoo-Basis aufzubauen.

Abbildung 1: Der schematische Aufbau eines Ansible-Inventorys zeigt alle enthaltenen Hosts sowie die Verbindungen.
Die Gliederung nach (Layer-7-)Diensten hat ebenfalls ihre Gründe. Als Adblocker kommt Pi-hole [5] zum Einsatz. Es verfügt über eine eigene Update-Verwaltung, die außerhalb des Paketmanagers der Distribution existiert. Möchte ich Pi-hole aktualisieren, komme ich dementsprechend mit dem Aufruf »apt update && apt upgrade« nicht weiter.
Zu jedem Host habe ich zwei Variablen definiert: »ansible_user« spezifiziert, welchen User Ansible für den Login auf dem Zielsystem verwenden soll; »ansible_ssh_private_key_file« legt fest, dass der SSH-Login mit einem privaten Schlüssel stattfinden soll.
Playbooks
Neben dem Inventory machen Sie in der Ansible-Welt mit weiteren Dateien Bekanntschaft: den Playbooks. Während das Inventory den Gegenstand der Operation bestimmt, also das Subjekt, definieren Playbooks, was geschehen soll, also das Prädikat.
Das Playbook-Beispiel aus Listing 2 folgt ähnlich wie das Inventory einem relativ simplen Aufbau. In der zweiten Zeile benenne ich das Playbook. Die dritte Zeile kümmert sich darum, dass Ansible die folgenden Tasks nur auf Debian-Servern ausführt.
Listing 2
Ansible-Playbook zum Aktualisieren von Debian-Systemen
---
- name: Debian-Server patchen
hosts: debian_servers
tasks:
- name: Alle Debian-Server per apt aktualisieren
ansible.builtin.apt:
force_apt_get: yes
upgrade: dist
become: yes
become-method: sudo
Erfahrungsgemäß erweist sich das YAML-Format für Einsteiger selten als selbsterklärend. Für einen tieferen Einblick verweise ich auf die Dokumentation [5]. Für unsere Zwecke genügen einige kurze Informationen: Mit einem Minuszeichen beginnende Zeilen interpretiert Ansible als Listenelemente. Zeilen der Form »key: value« entsprechen den Schlüssel-Wert-Paaren eines Dictionarys beziehungsweise einer Hash Table. Im Gegensatz zu alteingesessenen Formaten wie XML oder JSON kommt es bei YAML sehr wohl auf Whitespace an. Wie bei Python entscheidet die Tiefe der Einrückung darüber, zu welchem Element eine Zeile gehört. Mit diesen wenigen Syntaxelementen lassen sich komplizierte Strukturen aufbauen.
Im vorliegenden Playbook namens Debian-Server patchen werden nun alle Hosts im Inventory angesprochen, die zur Hostgruppe debian_servers gehören. Auf jeden dieser Hosts wendet Ansible den oder die spezifizierten tasks an. Im Beispiel ist das nur ein einzelner Task »ansible.builtin.apt«, der den Namen Alle Debian-Server per apt aktualisieren trägt. Dabei lässt »ansible.builtin« schon erahnen, dass es sich um etwas handelt, was aus dem Standard-Repertoire des Tools stammt: das eingebaute Modul apt.
Linux-Nutzer müssen sich also nicht mühsam die relevanten Werkzeuge für ihr Betriebssystem zusammensuchen. Ansible bringt von Haus aus enorm viel mit. Der Schalter »force_apt_get« erzwingt, dass Apt die Paketquellen erneut aktualisiert. Der Schalter »upgrade« weist Apt an, die vorliegenden Updates zu installieren. Abschließend gebe ich Ansible über die Parameter »–become« und »–become-method« zu verstehen, dass ein Kontextwechsel auf root erforderlich ist, den »sudo« abdeckt.
Hat alles seine Richtigkeit und passen die Einrückungen in den YAML-Dateien, baut sich beim Aufruf der Codezeile aus Listing 3 nach und nach die Ausgabe aus Abbildung 2 auf. Zunächst ermittelt Ansible stets die sogenannten Facts aller Hosts. Dazu zählen umfangreiche Informationen, unter anderem sämtliche IP-Adressen, Hostnamen und vieles mehr.
Listing 3
Playbook-Aufruf
$ ansible-playbook --inventory \ inventory/servers.yml \ --ask-become-pass \ debian_patch.yml

Abbildung 2: Haben sich keine Fehler in der YAML-Datei eingeschlichen, beispielsweise bei den Einrückungen, führt Ansible das Playbook erfolgreich aus.
Im relevanten Task Alle Debian-Server per apt aktualisieren quittiert Ansible die beiden Hosts »raspi03« und »raspi06« lediglich mit einem »ok«. Das bedeutet, dass keine Updates per Apt zur Verfügung standen und Ansible folglich nichts unternehmen musste. Es gab offenbar keinen Change wie im Fall von Pi-hole. Ein Change meint im Ansible-Sprachgebrauch nichts anderes, als dass eine Abweichung vom Sollzustand auftrat, den das Tool jedoch wiederherstellen konnte.
Der Schalter »–ask-become-pass« gibt an, dass die Software das Passwort für den Kontextwechsel auf Root vom Benutzer interaktiv abfragen soll. Für derlei Fälle hat Ansible erneut passende Werkzeuge parat: die Vaults. Mit ihrer Hilfe lassen Sie Playbooks auch ohne Passwortabfragen laufen.
Bei Ansible handelt es sich um ein Werkzeug zum Konfigurationsmanagement. Letztlich gebe ich mit dem Inventory und später noch einigen anderen Dateien einen Sollzustand vor, den die eingesetzten Ansible-Module im Rahmen von Playbooks herzustellen versuchen. Demnach befinden sich Debian-Systeme bereits im Sollzustand, sobald Apt keine aktualisierbaren Pakete findet. Im Fall der Hosts »raspi03« und »raspi06« habe ich beim Setup »unattended-upgrades« aktiviert. Beide Systeme aktualisieren sich regelmäßig automatisch, deswegen existierten beim Aufruf aus Abbildung 2 keine einzuspielenden Aktualisierungen.
Weiterdenken
Doch mit den System-Updates ist noch lange nicht sämtliche Arbeit erledigt. Wer selbst Server betreibt, weiß, dass es nicht immer klappt, benötigte Software aus dem Paketfundus der Lieblingsdistribution heranzuziehen. Typische Beispiele wären zum Beispiel Owncloud, Nextcloud, Gitea, Mastodon und wie in meinem Fall Pi-hole. Selbstverständlich möchte ich stets über die aktuelle Version der Software mit den neuesten Ad-Listen verfügen, die URLs von Werbetreibenden enthalten. Dementsprechend liegt es geradezu auf der Hand, zum Aktualisieren von Pi-hole [5] ein eigenes Playbook zu schreiben.
Letztlich genügen mir dazu gerade einmal zwei Kommandos. Zum einen dient der Aufruf »sudo pihole updatePihole« dazu, ein Update der Software selbst vorzunehmen. Zum Anderen aktualisiert der Befehl »sudo pihole updateGravity« die Listen der Werbetreibenden. Beide Kommandos erfordern Root-Rechte, zu erkennen an »sudo«. Dementsprechend braucht es an dieser Stelle erneut den Parameter »become«.
In Listing 4 sehen Sie die beiden Aufrufe als zwei Tasks definiert. Zur Erinnerung: Die Bindestriche deuten Listenelemente an, weswegen sich beliebig viele Tasks aneinanderreihen lassen. Im vorliegenden Playbook erhält Ansible nun den Auftrag, auf allen »dns_servers« (dritte Zeile) die beiden Befehle auszuführen. Ich verwende hier das Ansible-Builtin »command« (Zeilen 6 und 9), das ohne umfangreiche Konfiguration Shell-Kommandos aufruft.
Listing 4
Pi-hole aktualisieren
---
- name: Pi-hole-Server aktualisieren
hosts: dns_servers
tasks:
- name: Pi-hole-Software aktualisieren
ansible.builtin.command: pihole updatePihole
become: yes
- name: Gravity aktualisieren (AdLists)
ansible.builtin.command: pihole UpdateGravity
become: yes
Bitte behalten Sie im Hinterkopf: Ansible interpretiert einen Task genau dann als geglückt, wenn der Return-Code (RC) eines Programms oder Shell-Skripts gleich null ist. Erfahrene Shell-Nutzer müssen sich also nicht umstellen, die Logik bleibt dieselbe.
Abbildung 3 zeigt die Ausgabe des Playbooks. Auf den ersten Blick lässt sich beobachten, dass Ansible unabhängig von den jeweiligen Tasks stets dieselbe, aufgeräumt wirkende Ausgabe verwendet: Zum Abschluss gibt es pro betroffenem Host eine Zeile aus. Sie enthält die Anzahl der erfolgreichen Tasks (»ok«), die Anzahl der Changes (also der Abweichungen vom Sollzustand) und so weiter.

Abbildung 3: Ansible hat Pi-hole per Playbook aktualisiert. Im Beispiel schloss das Werkzeug drei Tasks erfolgreich ab.
Fazit
Was auf den ersten Blick stark übertrieben erscheinen mag, nämlich Ansible für derart einfache Aufgaben einzusetzen, verschafft Ihnen bei näherem Hinsehen gewaltige Vorteile: Nicht nur lassen sich so im Handumdrehen ganze Serverlandschaften auf den aktuellen Stand bringen, Sie sehen zusätzlich auch, auf welchen Hosts das automatische Update per »unattended-upgrades« unter Umständen sinnvoll sein könnte. Die automatische Aktualisierung eigener Dienste – in meinem Fall Pi-hole – sorgt dafür, dass ich den Prozess sogar dokumentiert habe. Ein ordentlich geschriebenes Playbook erklärt eindeutig, welche Schritte es zu machen gilt – besonders nützlich bei Anwendungen, die man eben nicht regelmäßig auf den neuesten Stand bringt.
Ansible vermag schon bei täglichen Aufgaben gute Hilfe zu leisten. Doch seine wahren Trümpfe spielt das Werkzeug erst aus, wenn es Ihnen die immense Arbeit der Installation neuer Systeme abnimmt. Ich spreche hier von Servern mit mehreren SCSI-Controllern für eine Vielzahl von Logical-Volume-Datenträgern, mit verteilten Datenbanken und Applikationsservern. Selbst mit gut gepflegten Templates (Vorlagen) stecken hinter dem Aufbau solcher Systeme viele Stunden überaus fehlerträchtiger Arbeit, stets mit dem Risiko, irgendwelche Details zu vergessen. Ich werde im Rahmen meiner Kolumne Admin-as-a-Service in Linux-Magazin sicher noch einmal darauf zurückkommen. (csi)
Infos
- Suse Manager: https://www.suse.com/de-de/solutions/manager/
- Uyuni: https://www.uyuni-project.org
- Ansible-Dokumentation: https://docs.ansible.com
- YAML-Syntax: https://docs.ansible.com/ansible/latest/reference_appendices/YAMLSyntax.html
- Pi-hole-Dokumentation: https://docs.pi-hole.net/core/pihole-command/





