Teil 5 der Artikelserie über die Automatisierung mit Ansible.
Vorwort
In Teil 5 der Artikelserie über die Automatisierung mit Ansible anhand des Beispiels “Patch Deployment auf Windows” erstellen wir unser Inventar, testen die Verbindung mit unseren Hosts und verfassen unser erstes Playbook.
Das Inventar
Ansible kann gleichzeitig gegen (bzw. mit) mehrere Systeme in Deiner Infrastruktur arbeiten. Damit es das kann, ist eine Inventar-Datei notwendig, aus welchem sich Ansible die notwendigen Informationen (FQDN, Gruppenzugehörigkeit, eventuell Variablen) holt.
Erstelle bitte im Git-Repo eine Datei namens “inventory” und bearbeite sie:
Für unser Beispiel bilden wir eine Host-Gruppe namens “windows”, welche alle unsere Windows Server Hosts enthält:
Moment mal. Du wirst Dich nun sicher fragen, ob das nicht zu kurzfristig gedacht ist? Richtig! Nicht alle Windows-Server sollten gleichzeitig aktualisiert und potentiell neu gestartet werden… Ändern wir also unser Inventar geringfügig:
Wir haben nun je eine Gruppe für die WSUS-Server, die generischen Server und die ADC’s erstellt. Die ADC’s sind in zwei Gruppen unterteilt, damit niemals alle gleichzeitig bearbeitet werden.
Zusätzlich haben wir eine Gruppe erstellt, welche die anderen Gruppen zusammenfasst. Beachte den :children-Zusatz im Gruppenname, damit signalisieren wir Ansible, dass es sich um eine Gruppe von Gruppen handelt.
Nun müssen wir Ansible noch sagen, wie wir auf die Hosts zugreifen möchten.
Dazu fügen wir den folgenden Abschnitt in die Inventardatei ein:
[windows:vars] ansible_port=5986 ansible_connection=winrm ansible_winrm_server_cert_validation=ignore ansible_winrm_operation_timeout_sec=60 ansible_winrm_read_timeout_sec=70 ansible_become=false
Mit diesem Abschnitt definierst Du, dass Du mit den Hosts in der Gruppe “windows” mit WinRM über Port 5986 kommunizieren möchtest, dass Du das Serverzertifikat ignorieren möchtest (Achtung: Das ist ein Sicherheitsproblem, ich werde in einem späteren Kapitel noch darauf eingehen), definierst einige Timeouts und sagst, dass Ansible “become” (bsp. sudo unter Linux, runas unter Windows) nicht nutzen soll.
Verbindung testen
Nun können wir erstmals die Verbindung zwischen dem Ansible-Host und den Windows-Servern testen. Dazu ziehst Du Dir ein neues Kerberos-Ticket, falls es abgelaufen ist (Siehe Teil 4):
Auf geht’s, lassen wir Ansible die Windows-Hosts “pingen” (wir benutzen das Ansible-Modul ping, nicht ICMP echo request). Bitte setze folgendes Kommando ab:
ansible -i inventory windows -m win_ping \ -u {{ windows_upn }} -k
Die Parameder bewirken folgendes:
- -i inventory: Diese Inventar-Datei wird verwendet.
- windows: Auf diese Hostgruppe wird der Befehl angewendet.
- -m win_ping: Führe das Modul “win_ping” aus.
- -u {{ windows_upn }}: Benutze diesen Benutzernamen, muss mit dem Kerberos-Anmeldenahmen übereinstimmen.
- -k: frage nach dem Kennwort
Enttäuschend, nicht wahr? In Teil 4 habe ich leider einen kleinen Fehler eingebaut – die von Ubuntu angebotene python-winrm-Version ist leider zu alt. Wir entfernen diese, installieren die notwendigen python- und kerberos-dev Pakete und “pip”, den python package manager:
sudo apt remove python-winrm sudo apt install python-pip gcc python-dev libkrb5-dev
Nun können wir mit pip pywinrm und requests-kerberos installieren:
sudo pip install pywinrm requests-kerberos
Mal sehen, ob Ansible jetzt mit den Windows-Servern kommunizieren kann:
Ta-Da!
Das erste Playbook
Wir erstellen nun unser erstes Playbook. Erstelle bitte eine neue Datei und editiere diese:
nano -w windows-updates-search.yml
Unser erstes Playbook sieht so aus:
--- - hosts: Windows tasks: - name: search for windows updates win_updates: category_names: - Application - Connectors - CriticalUpdates - DefinitionUpdates - DeveloperKits - FeaturePacks - Guidance - SecurityUpdates - ServicePacks - Tools - UpdateRollups - Updates reboot: no state: searched register: win_updates - name: print variable debug: msg: '{{ win_updates }}'
Lass uns das Playbook Zeilenweise durchgehen:
01 --- 02 - hosts: windows 03 tasks: 04 - name: search for windows updates 05 win_updates: 06 category_names: 07 - Application 08 - Connectors 09 - CriticalUpdates 10 - DefinitionUpdates 11 - DeveloperKits 12 - FeaturePacks 13 - Guidance 14 - SecurityUpdates 15 - ServicePacks 16 - Tools 17 - UpdateRollups 18 - Updates 19 reboot: no 20 state: searched 21 register: win_updates 22 - name: print variable 23 debug: 24 msg: '{{ win_updates }}'
- Präambel.
- Auf diese Hostgruppe wird werden die nachfolgenden Tasks angewendet. Es ist möglich, einen Host, eine Gruppe, mehrere Hosts, mehrere Gruppen oder ein Gemisch anzugeben.
- Diese Zeile zeigt an, dass nun die einzelnen Tasks der Hosts innerhalb dieses Playbooks folgen.
- Name des Tasks. Das Minus oder der Bindestrich zeigt, dass es sich um eine geordnete Liste mehrerer Objekte, in diesem Fall Tasks, handelt.
- Das in diesem Task verwendete Ansible-Modul, hier “win_updates”.
- Parameter “category_names” des Modules.
- bis 18. Wird befüllt mit der Liste [u’Application’,u’Connectors’,u’CriticalUpdates’,u’DefinitionUpdates’,u’DeveloperKits’,u’FeaturePacks’,u’Guidance’,u’SecurityUpdates’,u’ServicePacks’,u’Tools’,u’UpdateRollups’,u’Updates’]. Der Einfachheit halber nehmen wir für den Moment einfach alle Update-Kategorien. Dies werden wir in einem späteren Kapitel anpassen.
- Wir setzen den Parameter “reboot” des Moduls aus “no”, der Server soll nicht automatisch neu starten.
- Wir setzen den Parameter “status” des Moduls aus “searched”, der Server soll nur nach Updates suchen.
- Mit dieser Zeile sorgen wir dafür, dass die Ausgabe des Moduls in die Variable “win_updates” registriert. Im zweiten Task möchten wir den Inhalt dieser Variable ausgeben. Beachte bitte, dass es sich hier nicht um ein Parameter des Moduls handelt, sondern um eine Option des Tasks, daher ist das Schlüsselwort auf der Höhe der Taskdefinition eingerückt.
- Eine neue Taskbeschreibung beginnt. Wir setzen den Namen auf “print variable”
- Für diesen Task benutzen wir das Modul “debug” …
- … und setzen den Parameter “msg” auf “‘{{ win_updates }}'”. Du siehst, dass Du die Variabel mit {{ }} umschliessen musst, und den ganzen Ausdruck in Hochkommata oder Anführungszeichen setzen musst.
Der Einrückungsstil eines Playbooks entspricht dem von Python. Es soll für den Interpreter als auch für den Menschen gut verständlich sein. Falls Du von einer anderen Programmiersprache kommst, wirst Du damit Mühe haben, glaub mir. Ich arbeite seit bald zwei Jahren mit Ansible und habe immer noch hin- und wieder Mühe damit. 15 Jahre Perl/C/C++/PHP/C-Gartenzaun gewinnen gegen 2 Jahre Ansible :-).
Weitere Informationen zum Playbook findest Du in der offiziellen Dokumentation. Sie ist ziemlich gut, schau’ mal rein!
Jetzt ist es an der Zeit, das Playbook zu testen:
ansible-playbook -i inventory -u {{ windows_upn }} \ -k windows-updates-search.yml
Damit sind wir am Ende des 5. Teil. Weiter geht’s demnächst mit dem Patch Deployment.
PS: Falls Du Dich nun fragst, warum hier unterbreche: Ganz einfach – der WSUS in meinem Lab liefert keine Patches aus, ich muss erst dieses Problem lösen 🙂