Nachdem wir ja nun auch alle möglichen Dienstleistungen rund um Ansible anbieten, dachte ich mir, es kann nicht schaden, es mir auch mal zu Gemüte zu führen. Kurzum: Ich bin bisher begeistert davon, wie einfach man damit auch komplexe Aufgaben lösen kann und werde sicherlich mein Wissen in dieser Richtung noch vertiefen.
Meine ersten Gehversuche haben mir dann auch gleich geholfen, ein Problem zu lösen, das mich schon länger geplagt hat. IT’ler neigen ja dazu, auch selber eine umfangereiche Infrastruktur zu betreiben und dabei wird der Aufwand üblicherweise mit der Zeit nicht weniger. Ich habe durchaus einige ähnliche Systeme im Einsatz und kann getrost sagen, wenn ich bei ein paar repräsentativen Systemen geprüft habe, ob ich anstehende Updates sofort einspielen oder lieber warten sollte, kann ich sie für die restlichen Rechner auch gleich machen. Aber wie, ohne ständig von System zu System hüpfen zu müssen. Es gibt dafür natürlich Lösungen, aber die meisten, die ich gefunden habe, brauchen einfach deutlich zu viele Ressourcen und rentieren sich auch für meine mittlere zweistellige Anzahl an Rechnern nicht.
Also habe ich versucht, das Problem mit Ansible zu erschlagen und war auch in erstaunlich kurzer Zeit fertig. Inzwischen weiss ich, dass meine Lösung nicht sonderlich elegant ist und man noch einiges daran verbessern kann, aber ich denke, sie ist eingängig und deshalb möchte ich sie hier vorstellen.
Zuerst lege ich mir die Datei ~/ansible/hosts
an, in der sämtliche Hosts namentlich aufgelistet werden. Ich habe sie anonymisiert und stark gekürzt, um den Blogartikel nicht unnötig in die Länge zu ziehen. z.B. ist hier nur ein NAT mit Hosts dargestellt, in meiner „echten“ Liste sind es mehr, was „händische“ Updates nicht einfacher macht.
[centos:children] centos6 centos7 [debian:children] debian-jessie raspbian-stretch debian-stretch [centos6] odin.example.com kvasir.example.com [centos7] balder.example.com heimdall.example.com tyr.example.com [raspbian-stretch] rerun.asgard.example.com [debian-jessie] gullveig.example.com [debian-stretch] freyr.example.com [solaris11] surtur.asgard.example.com [special-centos] loki.asgard.example.com [asgard] loki.asgard.example.com rerun.asgard.example.com surtur.asgard.example.com
Zuerst werden hier Gruppen definiert, die andere Gruppen zusammenfassen. So sind die Gruppen centos6
und centos7
Teil von centos
und alle Hosts in den Untergruppen auch gleichzeitig Mitglied in den Übergruppen. Bei genauem Hinsehen erkennt man auch, dass loki.asgard.example.com
Mitglied in zwei Gruppen ist, was durchaus so beabsichtigt ist.
Das folgende Playbook ( ~/ansible/playbooks/update-all.yml
) kann nun (fast) alle Systeme auf einen Schlag aktualisieren. Wenn mir also mein Icinga 2 meldet, dass Updates anstehen, suche ich mir einen repräsentativen Host jeder Gruppe aus und prüfe, welche Updates anstehen. Denke ich, dass ich sie gefahrlos einspielen kann, starte ich das folgende Playbook.
--- - hosts: centos*:!special-centos remote_user: alice become: yes tasks: - name: update everything yum: name: "*" state: latest exclude: "owncloud*" - hosts: special-centos remote_user: alice become: yes tasks: - name: update everything yum: name: "*" state: latest skip_broken: yes - hosts: debian*:raspbian* remote_user : alice become: yes tasks: - name: install dmidecode apt: name: dmidecode update_cache: yes - name: update package cache apt: update_cache: yes - name: upgrade packages apt: upgrade: dist force: yes - name: autoremove dependencies apt: autoremove: yes
Das erste Play verbindet sich zu allen centos Hosts, die nicht Teil der Gruppe centos-special
sind und führt das Modul yum
aus, das mit der Option latest
alle Pakete aktualisiert. Explizit ausgeklammert ist dabei owncloud
, da hier immer Nacharbeiten nötig sind. Dabei nutzt Ansible den User alice
, für den ein SSH Key hinterlegt ist und wird per sudo
zu root
. Das muss natürlich vorher erlaubt werden, wobei Ansible auch ermöglicht, für sudo Passwörter mitzugeben. Ist dieses Play durchgelaufen, sind alle CentOS Maschinen, ausser loki
aktualisiert. Dabei handelt es sich um eine „gewachsene Speziallösung“ auf der diverse Pakete aus Drittrepositories installiert sind, die inzwischen in defekten Abhängigkeiten festhängen. Hier wird das yum
Modul also mit der skip_broken
Option aufgerufen, das diese verbogenen Pakete ausklammert.
Das Paket deltarpm
um Gebrauch von deltarpms zu machen, habe ich über ein anderes Playbook installiert, könnte man aber prinzipiell auch noch hier vor den ersten Plays aufnehmen.
Nach den CentOS Hosts kommen die Debian Maschinen an die Reihe. Hier wird erst dmidecode
installiert, das für den reibungslosen Ablauf nötig ist und z.B. bei raspbian nicht gleich installiert war. Ist das Paket bereits installiert, überspringt Ansible diesen Schritt nach einer Prüfung. Die Tasks für Debian haben alle das Update des package cache deaktiviert, was den Ablauf sehr beschleunigt. Der erste Task führt dieses Update durch und das reicht für alle weiteren. Zum Schluss werden noch nicht mehr benötigte Dependencies entfernt.
Damit Ansible sich auch in das NAT „asgard“ verbinden kann, habe ich entsprechende Optionen in ~/ansible/hosts/group_vars/asgard
hinterlegt.
ansible_ssh_common_args: '-o ProxyCommand="ssh -W %h:%p -q asgard.example.com" -o ConnectTimeout=800s' ntp_server: 192.168.74.19
Damit wird festgelegt, dass ansible sich zu allen diesen Hosts über einen Jumphost verbinden muss. Dabei gibt der Name der Datei an, für welche Gruppe von Hosts die darin enthaltenen Optionen gelten. Die Adresse des NTP Servers hat keinen Einfluss auf dieses Playbook, soll aber zeigen, dass man hier auch einfach andere Variablen setzen kann.
Der Solaris Host bleibt hier aussen vor, da es dafür noch kein fertiges Modul für Updates gibt. Hier greife ich ggf. noch händisch ein.
Inzwischen weiss ich, dass man die verwendeten Module auch einfach abhängig vom Fact des Betriebssystems machen kann und noch den einen oder anderen Kniff. Aber in der aktuellen Version ist das Playbook wohl besser verständlich.
Wer mehr über Ansible wissen will, sollte unbedingt mal in einer unserer Schulungen vorbeischauen.
0 Kommentare