Wer Linux Server im Einsatz hat weiß, dass auch diese Systeme regelmäßig auf einen aktuellen Stand aktualisiert werden müssen. Das ist besonders aus Sicherheitsgründen ratsam, regelmäßig durchzuführen. Egal ob es sich hierbei um RedHat, Suse, Debian oder beliebige andere Distributionen handelt, alle haben hier ihre eigenen Mechanismen zur Paketverwaltung. Wenn es sich um eine größere Anzahl an Servern handelt, macht es wenig Sinn, diese manuell einzeln zu aktualisieren. Automatisierte Updates, die eigenständig im Hintergrund laufen, sind eher auch nicht zu empfehlen, da im Problemfall dann erstmal nicht ersichtlich ist, wo und warum etwas nicht funktioniert hat.
Eine praktische Möglichkeit sind Systemupdates per Ansible auszurollen. Ansible sollte im Optimalfall sowieso schon zur Konfiguration der Systeme im Einsatz sein. Dabei ist es meiner Meinung nach egal, ob es sich um ein Homelab, eine kleine oder eine Enterprise Infrastruktur handelt. Ansible Automatisierung macht immer Sinn, um seine Systeme damit zu verwalten. Es ist einfach, praktisch, Ressourcen schonend und es gibt eine enorm große Community.
Im Folgenden wird gezeigt, wie sich mit einer kleinen simplen Ansible Rolle eine beliebige Anzahl von Debian Systemen aktualisieren lässt. Selbstverständlich kann Ansible auch mit diversen unterschiedlichen Distributionen gleichzeitig umgehen und eine Fallunterscheidung je nach Distribution durchführen. Der Einfachheit halber, wird in diesem Fall jedoch nur Debian berücksichtigt.
Die Ansible Rolle soll folgende Aufgaben erledigen.
- Paketinformationen aktualisieren, um über neue Paketversionen Bescheid zu wissen
- Alle bereits installierten Pakete aktualisieren, ohne dabei auf eine neue Major Version zu wechseln
- Prüfen ob ein Reboot erforderlich ist
- System neu starten, wenn es wirklich erforderlich ist
- Paket Cache bereinigen und alte Pakete aus dem Cache entfernen
- Nicht mehr benötigte Pakete und Abhängigkeiten samt Konfiguration entfernen
Die Rolle „debian_update“ hat folgende Struktur:

Im Ordner „Inventory“ werden die Hosts definiert, auf denen Playbooks bzw. Rollen ausgeführt werden sollen. Hier kann es natürlich viele unterschiedliche Konfigurationen je nach Anforderung geben. Der Ordner Playbooks kann einzelne kleine Plays für spezielle Aktionen oder Aufrufplaybooks für ganze Rollen enthalten. In diesem Fall wird hierüber die Rolle „Debian Update“ aufgerufen. Im Ordner „Roles“ werden die ganzen einzelnen Rollen hinterlegt. Die Rolle hat je nach Umfang weitere Unterordner. In diesem speziellen Fall reichen „Defaults“, „Handlers“ und „Tasks“ aus. In den Defaults werden alle Standardwerte für Variablen definiert, die innerhalb der Rolle verwendet werden, damit die Rolle nutzbar ist. Einzelne Werte hierin können über die „group_vars“ oder „host_vars“ aus dem Inventory überschrieben werden, falls erforderlich. Die Handlers sind für Aktionen sinnvoll, die ggf. mehrfach ausgeführt werden müssen, ohne sie jedesmal explizit in den Tasks mit aufzunehmen. Das kann ein Task zum Neustarten des Systems oder als weiteres Beispiel zum Neustarten eines systemd Daemons sein. Somit lassen sich Redundanzen von Tasks vermeiden. Die Tasks beinhalten dann die tatsächlichen Aktionen, die ausgeführt werden sollen. In diesem Beispiel also ein Debian System auf den aktuellen Stand zu bringen.
Die komplette Ansible Rolle ist in einem meiner GitHub Repos zu finden.
Aufgerufen kann die Ansible Rolle dann wie folgt:
ansible-playbook -i ./ansible/inventory/hosts.yml ./ansible/playbooks/role_debian_update.yml
Ansible geht dann alle Systeme aus dem angegebenen Inventory durch und führt nur die erforderlichen Schritte durch. Hierbei ist es wichtig, die Inventory Struktur sinnvoll zu planen, um nicht alle Systeme auf einmal zu aktualisieren. Es könnte passieren, dass die Systeme genau das tun, was von ihnen verlangt wird und neu starten. Hier ist eine gute Staging Strategie sinnvoll. Im Optimalfall wird das zugleich über eine geeignete CI/CD Pipeline realisiert. Dies werde ich in einem der nächsten Beiträge näher erklären.