Ansible / Teil 1 – Installation und Einrichtung (Ubuntu-Server)
In einem früheren Beitrag bin ich auf die Möglichkeit eingegangen, Linux Maschinen von zentraler Stelle aus zu verwalten. Der Beitrag behandelte das Tool Puppet. Wie dort bereits erwähnt, gibt es neben Puppet noch weitere Möglichkeiten. Eine davon ist Ansible, worum es auch in diesem Beitrag gehen soll.
Auch wenn Puppet einen guten Ruf genießt, ist es mir persönlich durch die Zertifikats-Authentifizierungs-Klamotte zu frimelig. Die Schwäche liegt für mich im besonderen dabei in der Neugenerierung dieser Zertifikate, falls ein Client mal abgesoffen ist. Als Alternative stelle ich heute also meinen momentanen Favoriten in der Linux Administration „Ansible“ vor.
Unsere Servergrundlage wird ein Ubuntu Server 20.04 sein.
Installation
Installieren lässt sich Ansible über die offiziellen Paketquellen:
sudo apt-get install ansible
Und schon hätten wir Ansible installiert, nur wie geht es weiter? Und wie funktioniert Ansible überhaupt?
Einrichtung eines Clients
Im Gegensatz zu Puppet verzichtet Ansible gänzlich auf eine Agenten-Software. Die angeschlossenen Clients kommunizieren mit Hilfe von SSH-Keys mit dem Ansible-Server.
Vorneweg sei gesagt, dass es sicher bessere Best-Practice Lösungen gibt als die hier vorgestellte. Ein Ansible Funktionsbenutzer mit entsprechenden sudo-Rechten stellt wohl die bessere Variante dar. Der einfachheithalber werde ich hier dennoch den Zugriff über den root-Benutzer beschreiben.
Wir erzeugen uns zunächst ein entsprechendes Schlüsselpaar um uns als root auf die jeweiligen Maschinen anmelden zu können. Von unserem Ansible-Server aus melden wir uns also also root an und geben folgenden Befehl ein:
sudo su -
ssh-keygen -f ~/.ssh/id_rsa
Der folgende Eingabeprompt für das Passwort wird zweimal ohne Eingabe quittiert.
Es wurden nun im Home-Verzeichnis des root-Benutzers (sofern als root angemeldet) ein SSH-Key Schlüsselpaar (~/.ssh/id_rsa = private und ~/.ssh/id_rsa.pub = public) erzeugt. Den Public-Key können wir mit der Welt (oder auch mit unseren Clients) teilen, den Private-Key sollten wir tunlichst nicht vom Fleck bewegen oder laut vorlesen.
So kommt der Public-Key auf die Zielmaschine:
ssh-copy-id -i ~/.ssh/id_rsa.pub root@xubuntu-vm
Dummerweise erlaubt Ubuntu standardmäßig keine root-Logins, denn genau diesem User müssen wir den Public-Key geben. Wenn nichts hilft, kopiert euch einfach dessen Inhalt auf die Zielmaschine in die Datei:
/root/.ssh/authorized_keys
Legt sie an, falls die Datei nicht vorhanden ist und sorgt dafür, dass nur der Benutzer root Besitzer von ihr ist und darauf zugreifen darf:
sudo mkdir -p /root/.ssh/
sudo chown root:root /root/.ssh/authorized_keys
sudo chmod 400 /root/.ssh/authorized_keys
Der Hauptordner in dem Ansible schaltet und waltet, befindet sich unter /etc/ansible/. Dieser besteht anfangs noch aus nur 2 Dateien:
/etc/ansible/ansible.cfg -> Hauptkonfigurationsdatei
/etc/ansible/hosts -> Inventar für die Clients
Werfen wir als erstes einen Blick in das Inventar hinein.
sudo nano /etc/ansible/hosts
Die vielen auskommentierten Zeilen geben bereits einen ersten Überblick, wie die Erfassung der Clients aussehen kann. Eckige Klammern [ ] läuten eine neue Gruppe ein, alles darunter eingefügte sind ihre Mitglieder. Legen wir nun also die Gruppe „ubuntu-clients“ an und geben dieser den Client „xubuntu-vm“ mit.
Sämtliche Clients dieser Gruppe können zukünftig über den Gruppennamen xubuntu-clients angesteuert werden.
Ob die Verbindung funktioniert, testet man am besten direkt mit Ansible selbst aus:
sudo ansible -m ping xubuntu-vm
Da uns der Ping Befehl nun aber auf kurz oder lang zu eintönig wird, legen wir unser erstes sogenanntes „Playbook“ an. Playbooks sind Ansibles Antwort auf Puppets Manifeste, oder anders ausgedrückt, schlicht eine Funktionsanweisung oder ein Satz von Funktionsanweisungen.
Hierzu legen wir uns zugunsten der Übersicht einen Unterordner innerhalb von /etc/ansible/ an.
mkdir -p /etc/ansible/playbooks
In diesem Ordner legen wir eine neue Datei „apt_update.yml“ an (ja, es muss mal wieder das yaml-Format herhalten). Der Name suggeriert es ja bereits. Es handelt sich um ein Playbook für automatische Updates auf Ubuntu Seite.
nano /etc/ansible/playbooks/apt_update.yml
Folgender Inhalt wird dort eingefügt:
---
- hosts: ubuntu-clients
ignore_errors: yes
ignore_unreachable: yes
tasks:
- name: Update apt repositories and cache
apt: update_cache=yes force_apt_get=yes cache_valid_time=3600
- name: Update all apt packages
apt: upgrade=dist force_apt_get=yes
- name: Remove dependencies that are no longer required
apt:
autoremove: yes
Achtet auf die korrekte Einrückung, sonst gibt’s von Ansible hinterher was auf die Pfoten.
Hier eine kurze Erklärung der Syntax im Schnelldurchlauf:
Jede Ansible yaml-Datei wird mit drei — eingeläutet. Es folgt die Definition der Hosts (die Angabe einzelner Maschinen ist auch möglich) und Hostgruppen. Mehrfachangaben sind möglich und werden mit Kommata getrennt. „ignore_errors“ und „ignore_unreachable“ verhindert, dass der Ansible Durchlauf bei Problemen hängenbleibt und weiterläuft.
Unter „tasks“ wird mit dem integrieten Ansible Modul apt zunächst der APT-Cache aktualisiert und im nächsten Block ein Update der Pakete durchgeführt (Die einzelnen Blöcke werden hintereinander ausgeführt). Abschließend werden alle Pakete, die durch fehlende Abhängigkeiten überflüssig geworden sind, gelöscht.
Wir sind jetzt bereit unseren ersten Ansible(-Playbook) Durchlauf zu starten. DIesmal nicht etwa mit „ansible“ sondern mit „ansible-playbook“:
sudo ansible-playbook /etc/ansible/playbooks/apt_update.yml
Läuft alles gut, sollte folgende Ausgabe erscheinen:
Möglicherweise wird nachgefragt, ob dem Host-Key des angefragten Clients vertraut werden kann, falls dieser noch nicht in den known_hosts vorhanden ist. Möchtet ihr diese Nachfrage zukünftig für weitere Maschinen unterbinden, geht ihr in die Hauptkonfigurationsdatei „/etc/ansible/ansible.cfg“ und kommentert dort die Zeile „host_key_checking = False“ aus.
Super, damit hätten wir den Grundstein für Ansible gelegt.
Im nächsten Teil kümmern wir uns um eine grafische Übersicht der in Ansible erfassten Clients. Außerdem möchte ich eine Methode vorstellen, wie sich automatisiert ein Inventar gebaut werden kann.