# Ansible Workshop - [Vorbereitung](#vorbereitung) - [Beispieldateien kopieren](#beispieldateien-kopieren) - [Funktionstest des Inventars](#funktionstest-des-inventars) - [Installieren einer notwendigen Collection](#installieren-einer-notwendigen-collection) - [Das Playbooks Verzeichnis](#das-playbooks-verzeichnis) - [Ausrollen des Automatisierungs-Users](#ausrollen-des-automatisierungs-users) - [Anpingen aller Hosts](#anpingen-aller-hosts) - [Workshop 1](#workshop-1) ## Vorbereitung ### Beispieldateien kopieren Check dieses Repostitory mit git aus und wechsel in das Verzeichnis ``` git clone https://git.serverwg.de/fager/ansible-workshop.git cd ansible-workshop ``` Kopiere das Beispielinventar: ``` cp -r inventory/demo inventory/myinv ``` Kopiere die Beispiel ansible.cfg: ``` cp ansible.cfg.dist ansible.cfg ``` Passe die Konfiguration an Dein Inventar an: ``` [defaults] inventroy = ./inventory/myinv ... ``` Für die Demos werden 3 VMs benötigt. Diese müssen bereits existieren und sind nicht Bestandteil des Workshops. Im Beispiel-Inventar sind drei Server vorgesehen: - server1.example.com - server2.example.com - server3.example.com Die Servernamen werden an verschiedenen Stellen im Inventar verwendet und referenziert. Es ist daher empfehlenswert, die Servernamen zuerst so zu belassen und im Inventar die IP der Systeme anzupassen. Dafür öffnest Du die Dateien `inventory/myinv/host_vars/server[1-3].example.com.yml` und passt die Host-Konfiguration an die IP Deiner VMs an: ``` --- ansible_host = 192.0.2.10 ``` ### Funktionstest des Inventars Alle Befehle in diesem Workshop beziehen sich auf das Verzeichnis `ansible-workshop`. Die Ansible-Befehle suchen im aktuellen Verzeichnis nach einer `ansible.cfg` und verwenden diese dann als Ihre Konfiguration. Ob das Inventar sauber eingelesen wird, lässt sich durch `ansible-inventory` testen. ``` $ ansible-inventory --graph @all: |--@ungrouped: |--@loadbalancer: | |--server1.example.com |--@webserver: | |--server2.example.com | |--server3.example.com ``` Ebenso können zum Testen einmal alle Variablen für einen Host abgefragt werden. ``` $ ansible-inventory --host server1.example.com { "ansible_host": "192.0.2.10", "automation_keys": [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMj6DlLhdnhknWeC4Zz48P7pzTH6JNFUTcOaxm/8V9fa fager@t530fedo" ], "automation_user": "ansible" } ``` ### Installieren einer notwendigen Collection ``` ansible-galaxy collection install ansible.posix ``` ## Das Playbooks Verzeichnis Im Playbooks-Verzeichnis werden alle Playbooks zu diesem Projekt gespeichert. Es sind zwei Playbooks bereits als Beispiel enthalten: - `playbooks/prepare_automation_user.yml`: Richtet den Automatisierungsuser ein - `playbooks/ping.yml`: pingt alle Hosts im Inventar an ### Ausrollen des Automatisierungs-Users Wir gehen davon aus, dass auf dem Zielsystem ein ssh-Server läuft und es einen Benutzer auf dem System gibt, der sich per sudo zu root machen kann. Für die Automatisierung benötigen wir einen Benutzer, bei dem die Anmeldung über einen ssh-Key möglich ist und der sich ohne sudo-Passwort root-Rechte verschaffen kann. Dies erledigt das Playbook `playbooks/prepare_automation_user.yml` für uns. Das Playbook richtet den User ein, der im Inventar in der Variable `automation_user` hinterlegt ist. Dabei werden die ssh Public-Keys bei dem User hinterlegt, die in der Variable `automation_keys` hinterlegt sind. Außerdem richtet das Playbook die sudo-Rules ein, die eine passwortlose Verwendung von sudo zulassen. Im Inventar ist in der Datei `group_vars/all.yml` bereits ein Beispiel-Key hinterlegt. In diese Liste werden einfach die weiteren ssh-Public Keys mit aufgenommen, die für die Automatisierung mit verwendet werden sollen. Der Server muss bereits über einen Zugang verfügungen, über den man sich per ssh verbinden und dann mit sudo root werden kann. Dies kann aber auf verschiedene Weise erfolgen. - Für die ssh-Verbindung wird ein anderer Benutzername verwendet (`-u`) - Für die ssh-Verbindung wird ein Passwort abgefragt (`-k`) - Beim Aufruf von sudo wird ein Passwort abgefragt (`-K`) Je nachdem, welche Situation vorliegt, werden dem Playbook für die Ersteinrichtung des automatisierungs-Users die Parameter mitgegeben: ``` ansible-playbook -k -K -u ./playbooks/prepare_automation_user.yml ``` **ACHTUNG:** Wenn im Inventar bereits `ansible_user` konfiguriert ist, ist dies höherwertig als der `-u` schalter und es wird versucht, die Verbindung bereits mit dem Automatisierungsuser aufzubauen. Dies kann man überschreiben, indem man mit `-e ansible_user=` mitgibt. Nachdem der User angelegt wurde, kann in `group_vars/all.yml` die Zeile mit `ansible_user` auskommentiert und der Automatisierungs-User dort eingetragen werden. Ansible verwendet ab jetzt grundsätzlich diesen User für die Verbindung. ### Anpingen aller Hosts Nachdem der Automatisierungs-User eingerichtet ist, können alle Hosts testweise einmal angepingt werden. ``` ansible -m ping all ``` Ansible baut dadurch die ssh-Verbindung auf und testet einmal, ob ein Python auf dem System vorhanden ist. Wenn das klappt, wird ein "pong" zurück gegeben. Mit einem `-b` kann man auch die Funktion des passwortlosen sudo-Aufrufs testen. Ein weiterer Test kann mit dem Command-Modul erfolgen. Mit `-a` wird das auszuführende Kommando mitgegeben. Mit dem `id -a` kann man sehr schön die Auswirkungen des `-b` beobachten. Mit `-b` sollten die Daten für root ausgegeben werden. Ohne das `-b` werden die Daten des Automatisierungs-Users ausgegeben. ``` ansible -m command -a "id -a" all ``` ## Workshop 1 In diesem Teil werden zwei Rollen entwickelt. - die Rolle `nginx` installiert den nginx auf den Webservern. - die Rolle `haproxy` konfiguriert den Proxy auf dem Loadbalancer. Aufgaben: 1. Erstellt die Rolle `nginx`. Diese soll: - nginx installieren - ggf. den nginx starten - eine index.html im DocumentRoot plazieren, die den `inventory_hostname` als Inhalt hat. 2. Erstellt die Rolle `haproxy`. Diese soll: - haproxy installieren - eine Konfigdatei basierend auf einem Template generieren - die Server, die in der Webserver-Gruppe sind, automatisch im Backend konfigurieren Das Grundgerüst für die beiden Rollen ist bereits im Verzeichnis [roles/](./roles/) enthalten. In der README.md der jeweiligen Rolle sind weitere Hinweise enthalten. Für den haproxy gibt es in [docs/haproxy.md](./docs/haproxy.md) ein Beispiel für eine Grundkonfiguration.