Habt ihr auch Aufgaben die sich ständig wiederholen? Wäre es nicht schön, wenn man diese jemand anderen machen lassen könnte? Als Informatiker - kein Problem!
"Informatiker sind Faul" ist ein Spruch, den ich bereits zu Zeiten meiner Ausbildung gehört habe. Das ist aber keinesfalls beleidigend gemeint, sondern ganz im Gegenteil. Wenn sich in der IT Aufgaben häufen, die viel Zeit fressen oder sich oft wiederholen (im schlimmsten Fall sogar beides) dann dauert es nicht lange bis sich ein Informatiker ein Skript zusammenbastelt. Ein Skript ist ein kleines Computerprogramm, das Aufgaben automatisch erledigt. Man schreibt es einmal, lehnt sich zurück und der Computer übernimmt die Arbeit. Klingt gut, nicht wahr?
Was sind das aber für Aufgaben, die von einem Skript übernommen werden können? Wie läuft so eine Automatisierung ab? Veranschaulichen wir das doch einmal anhand eines Beispiels, das in der IT-Welt alltäglich ist: die Installation einer komplexen Software. Wie zum Beispiel Opencast.
Opencast ist eine kostenlose Software zur Aufzeichnung und Verwaltung von Videos, die besonders an Universitäten beliebt ist. Folgendes Szenario: Eine Universität bittet uns, den elan e.V., Opencast auf ihren Servern zu installieren. Für uns eine ganz typische Situation. Die Server sind bereit und wir können loslegen. Wie sieht so eine Installation nun aus?
Einmal nach "Opencast" im Internet suchen, herunterladen und mit Doppelklick installieren? Ganz so einfach ist es leider nicht. Spielen wir es also einmal grob durch:
Zunächst müssen wir uns mit dem Server verbinden. Das passiert üblicherweise über ein Terminal. Falls du einem Informatiker schonmal über die Schulter geschaut hast, kennst du vielleicht das schwarze Fenster, in das man Befehle tippt. Dort führen wir also den Befehl aus und übergeben dabei die Adresse vom Server.
Sobald die Verbindung steht, kann es losgehen: Wie bei anderer Software auch, müssen wir Opencast herunterladen und installieren. Nur nutzen wir an dieser Stelle jetzt das Terminal. Dazu tippen wir Textbefehle ein, um Dateien zu verschieben, zu editieren und die Software herunterzuladen. Mit einem weiteren Befehl können wir Opencast dann installieren. Opencast hat einige Abhängigkeiten. Das bedeutet, wir müssen noch mehr Software herunterladen, wie beispielsweise Java, Opensearch und eine Datenbank. Also tippen wir weitere Befehle ein, laden die Abhängigkeiten herunter und installieren sie. Vielleicht möchten wir auch Tobira nutzen? Das ist ein Videoportal, das speziell für Opencast entwickelt wurde. Dieses installieren wir also vielleicht auch. Wenn wir damit durch sind, kommt der komplizierte Teil: Die Konfiguration.
Opencast bietet eine ganze Menge an Konfigurationsmöglichkeiten. Jede Universität hat ihre eigene Infrastruktur und möchte ihr Opencast darauf maßschneidern. Welches LMS benutzt die Universität? Moodle, Ilias oder Stud.IP? Wo landen die Video Dateien, die Opencast aufzeichnet? Möchte die Universität eigene Opencast Workflows haben? Auch wenn die Konfigurationsoptionen vielfältig sind, folgt die Konfiguration einem einheitlichen Prinzip: Wir müssen Dateien an bestimmte Speicherorte verschieben und anschließend bearbeiten.
Neben Opencast haben wir noch andere Software installiert, die ebenfalls konfiguriert werden muss. Um hier einmal ein paar Stichworte zu nennen: Datenbank, Reverse Proxy, Whisper, Monitoring und so weiter. Wenn wir auch diese konfiguriert haben, stellen wir fest, dass wir ja zunächst nur einen der Server fertig gemacht haben. Fehlen also noch die anderen. Opencast ist nämlich ein verteiltes System, dass auf mehreren Servern gleichzeitig läuft. Jeder Server in so einem Verbund hat spezifische Aufgaben und wird somit auch unterschiedlich konfiguriert.
Wenn wir also auch die anderen Server fertig gemacht haben, können wir Opencast auf den verschiedenen Servern einmal hochfahren und prüfen, ob soweit alles läuft.
"Software wird mit der Zeit schlecht". Diesen Satz hatte ich vor kurzem das erste Mal von einem Kollegen gehört und finde, er beschreibt den folgenden Sachverhalt sehr schön: Selbst wenn Opencast nun installiert ist und läuft, so wird jedoch irgendwann die Zeit kommen, in der man es updaten möchte. Für Opencast gibt es jedes halbe Jahr eine neue Version. Neuere Versionen beinhalten neben Features und Optimierungen auch die Behebung von Fehlern und das Schließen von Sicherheitslücken. Wenn man also auf dem neusten Stand bleiben möchte, so muss man einige der Installationsschritte jedes halbe Jahr wiederholen.
Ganz schön viel Arbeit und nun stelle man sich vor, man betreut nicht nur eine Universität, sondern eine ganze Reihe davon. Diese Arbeit per Hand zu machen, möchte ich behaupten, ist so gut wie unmöglich. Außerdem wird an dieser Stelle vielleicht auch ein anderes Problem ersichtlich. Bei den Mengen an Servern und spezifischen Konfigurationen, wer soll sich das alles merken? Wir brauchen also eine Lösung, um die Installation und die Konfiguration zu automatisieren und auch zu dokumentieren.
Zum Glück gab es mal ein paar "faule Informatiker", die da etwas gebastelt haben. Es nennt sich Ansible und es ist viel mehr als nur ein simples kleines Skript.
Mit Ansible lässt sich das Ganze, was wir vorher händisch machen mussten, automatisieren. Man erstellt ein Ansible Projekt und darin Ansible Skripte. Danach kann man sich mit einem einzigen Textbefehl mit den Servern automatisch verbinden, lädt dort Software herunter, installiert sie, transferiert Dateien und bearbeitet diese. Und es hat noch einige Vorteile mehr, auf die ich noch zu sprechen komme. Zunächst jedoch der grobe Aufbau so eines Ansible Projekts.
Wenn man mit Ansible loslegen möchte, erstellt man zunächst ein Ansible Projekt. Darin definiert man verschiedene Komponenten. Bei uns im elan e.V. sieht das meist wie folgt aus:
Bei unserem Opencast Beispiel stellte uns eine Universität mehrere Server zur Verfügung. Wir hatten uns mit den Servern verbunden und dort Konfigurationsdateien verschoben und editiert. Mit Ansible tragen wir die Serveradressen nun in ein sogenanntes Inventory ein. Das Inventory ist letztlich eine einfache Liste, wobei wir die Server darin noch gruppieren. Diese Gruppen benennen wir. Für Opencast erstellen wir meistens drei davon: Admin, Presentation und Worker. Ein Server wird zur Admin Gruppe hinzugefügt und ein Server der Presentation Gruppe. Die restlichen Server der Worker Gruppe. Je nach Anforderungen würden wir zusätzliche Gruppen erstellen und Server hinzufügen. Für das Videoportal Tobira beispielsweise erstellen wir auch eine extra Gruppe namens Tobira und fügen den Server hinzu, wo das Videoportal später installiert wird.
[admin]
admin.opencast.uni-einhorn.de
[presentation]
video.opencast.uni-einhorn.de
[worker]
worker1.opencast.uni-einhorn.de
worker2.opencast.uni-einhorn.de
worker3.opencast.uni-einhorn.de
[Tobira]
videoportal.uni-einhorn.de
Neben dem Inventory gibt es dann die Rollen, von denen wir beliebig viele erstellen können. In einer Rolle definieren wir, wie wir etwas installieren und konfigurieren. Damit niemand durcheinander kommt, benennen wir die Rollen entsprechend. Eine Rolle könnte beispielsweise Database heißen. Diese Rolle lädt die Datenbank herunter und installiert sie. Eine andere könnte Opencast heißen. Diese Rolle lädt entsprechend Opencast herunter und installiert es.
Eine Rolle hat mehrere Unterverzeichnisse. Im Verzeichnis Tasks beschreiben wir konkret die einzelnen Operationen. Also quasi das, was wir vorher alles händisch getan haben. Lade Opencast runter, installiere Opencast, transferiere Konfiguration X in Verzeichnis Y und so weiter.
Im Files Verzeichnis hinterlegen wir alle Dateien, die wir zu den Server übertragen wollen. Also zum Beispiel die ganzen Konfigurationsdateien. Alternativ gibt es aber auch Templates. Es kommt oft vor, dass wir ein und dieselbe Konfigurationsdatei auf verschiedene Server übertragen müssen, diese sich aber nur um eine einzige Textzeile unterscheiden. Auf dem einen Server steht z.B. "Admin" und auf dem anderen Server "Worker". In so einem Fall können wir ein Template nutzen und setzen Platzhalter ein. Ansible füllt die Platzhalter dann dynamisch mit den korrekten Wert, bevor die Dateien an ihren Bestimmungsort übertragen werden.
In einem Playbook kommen nun Inventory und Rollen zusammen. Hier beschreiben wir, welche Rollen auf welchen Servern ausgeführt werden. Zum Beispiel: Führe die Rolle Opencast auf allen Servern aus. Führe die Rollen Opensearch und Database für die Gruppe Admin aus. Führe die Rolle Tobira für die Gruppe Tobira aus. Auf diese Weise werden alle Operationen, die wir händisch machen mussten, automatisch auf den Servern abgearbeitet. Die Playbooks helfen uns also dabei, feingranular zu entscheiden, auf welchen Servern welche Operationen durchgeführt werden sollen.
Wenn wir einmal unsere Ansible Skripte fertig geschrieben haben, können wir uns zurück lehnen und mit einem Knopfdruck voll automatisiert die ganze Software ausrollen. Naja, zumindest bis zum nächsten Update. Ansible bietet aber noch weitere Vorteile. Manche davon helfen z.B. auch bei solchen Update Prozessen.
Wenn wir Ansible ausführen, gibt es uns Informationen im Terminal aus. Wir können live mitverfolgen, welche Änderungen Ansible auf den Servern vornimmt. Außerdem merkt Ansible, wenn man Operationen bereits ausgeführt hat. Es macht im Normalfall nichts doppelt. Sprich, wenn wir Ansible ein zweites oder drittes mal ausführen, wird im besten Fall keine Änderung mehr vorgenommen. Ansible gibt dann Meldungen im Sinne von "Bereits erledigt" aus.
Um Ansible Skripte zu testen, können wir auch Probeläufe durchführen. Wir können ein Playbook ausführen und den speziellen Parameter --check angeben. Auf diese Weise wird Ansible scheinbar ganz normal ausgeführt und gibt uns die üblichen Informationen aus. Nur treten in diesem Fall nicht wirklich die Änderungen in Kraft. Wenn wir beispielsweise ein Software Update durchführen müssen, würden wir Konfigurationsdateien anpassen, hinzufügen und generell ein wenig an den Skripten herumschrauben. Die Skripte können wir dann mit Probeläufen testen. Mit diesen können wir aber nur prüfen, ob die Skripte fehlerfrei ausgeführt werden können.
Wenn die Skripte fehlerfrei funktionieren, müssen wir danach die aktualisierte Software auf den Servern prüfen. Dabei wäre es ungünstig, wenn wir die Änderungen direkt auf ein Produktivsystem ausrollen würden. Wir müssen unsere Änderungen also irgendwie anders testen können. Das geht zum Glück wunderbar über ein zweites Inventory. Es ist üblich, dass uns Universitäten neben den Produktivservern auch Testserver zur Verfügung stellen. Wir können ganz einfach ein zweites Inventory erstellen und die Testserver dort auflisten und gruppieren, wie wir es zuvor getan haben. Das Inventory sieht quasi identisch aus. Es unterscheiden sich nur die Serveradressen. Wir können nun unser Playbook ausführen und geben als Ziel die Testserver an, statt den Produktivservern.
Ansible erleichtert uns das Leben aber auch noch an anderen Stellen. Da wir im Projekt alle Server angeben müssen und den genauen Ablauf definieren, dient es uns auch gleichzeitig als Dokumentation. Wie waren noch gleich die Server Adressen? Einfach das Ansible Projekt öffnen und im Inventory nachsehen. Welche Version von Software X habe ich nochmal installiert? Einfach im entsprechenden Task prüfen.
Mit Ansible machen wir den größten Teil der Arbeit nur einmal. Wir listen im Ansible Projekt die Server auf. Wir erstellen Rollen und definieren, welche Operationen ausgeführt werden. Wir beschreiben, was heruntergeladen und installiert wird. Wir beschreiben, welche Dateien an welche Orte kopiert und editiert werden. Schlussendlich können wir dann mit einem einzigen Befehl ein komplettes und komplexes System ausrollen. Wir können es zudem wieder und wieder tun. Egal ob wir weitere Inventories hinzufügen wollen oder wenn ein System spinnt oder gar abstürzt. Mit Ansible können wir im Nu den Zustand wiederherstellen.
Übrigens gibt es Rollen, die sich von Ansible Projekt zu Ansible Projekt nicht großartig unterscheiden. Und wenn sich Dinge wiederholen oder doppeln, wisst ihr was die faulen Informatiker tun. Sie basteln sich wieder was zusammen. In diesem Fall nennt es sich Ansible-Galaxy. Dort können wir Rollen hochladen, die wir für mehrere Projekte verwenden möchten. Unsere Ansible-Galaxy Rollen sind übrigens hier zu finden: https://galaxy.ansible.com/ui/standalone/namespaces/8850/
