Im Eingangskapitel Grundlagen haben wir uns mit der Installation bereits befasst. Auch haben wir uns schon in den beiden Kapiteln Playbooks und YAML - was ist das? eingehend mit den Hintergrundinformationen beschäftigt, so dass wir uns nun mit unsere Playbooks beschäftigen können.
Bei unserem ersten Playbook-Beispiel wollen wir mit Hilfe von Ansible einen Benutzer auf unserem Zielsystem automatisiert anlegen. Bevor wir unser erstes Script schreiben, wechseln wir in unser zuvor angelegtes Zielverzeichnis:
$ cd ~/ansible
Hier legen wir nun unser erstes Script ab.
$ vim 01_create-user.yml
--- - hosts: centos8 become: true vars: sudoers: ansible createguid: '1010' createuser: 'ruben' createusername: 'Ruben Nausch' createpassword: 'M31nP4p4157d3r4113r83573!' tasks: - name: Make sure we have a group '{{ createuser }}' for our new admin-user '{{ createuser }}' group: name: '{{ createuser }}' gid: '{{ createguid }}' state: present - name: Add the user '{{ createuser }}' with a specific uid and a primary group of '{{ createuser }}' user: name: '{{ createuser }}' comment: '{{ createusername }}' uid: '{{ createguid }}' group: '{{ createuser }}' state: present - name: Initial password generation for user '{{ createuser }}' shell: usermod -p $(echo '{{ createpassword }}' | openssl passwd -1 -stdin) {{ createuser }} ...
Doch Achtung: Es zeigt sehr anschaulich, dass es keine gute Idee sein kann, Passworte und ähnliches direkt in einem Playbook und/oder Inventory unverschlüsselt vor zuhalten - kann doch so jeder, der Zugriff auf das Playbook/Inventory hat, unberechtigter Weise Kenntnis von vertraulichen Informationen erlangen!
Wie wir dieses Thema elegant und sicher lösen können und auch werden, betrachten wir eingehend in dem Ansible - erweitertes Konfigurationsbeispiel 7: Ansible Vault.
Die einzelnen Zeilen haben dabei folgende Funktionen und Aufgaben. Zeile:
---
: Start-Ziele einer jeden YAML-Datei- hosts: centos8
: Das Script soll auf allen Systemen, die in unserer Inventory-Datei die Eigenschaft CentOS 8 zugewiesen bekommen haben.become: true
: Wir benötigen eine Rechteerweiterung zu root-Rechten, damit wir einen neuen Nutzer auf dem Zielsystem anlegen können.vars:
Wir möchten unser Script so gestalten, dass dies später für ggf. weiter Nutzer möglichst einfach zu verwenden ist. Daher verwenden wir hier Variablen.sudoers: ansible
Nutzer auf dem Zielsystem, der für die Administrationsaufgaben benutzt werden soll.createguid: '1010
' Variable die der UID bzw. der GID unseres Nutzers 'ruben' zugewiesen werden soll.createuser: 'ruben
' Variable mit dem Nutzernamen 'ruben'createusername: 'Ruben Nausch
' Variable mit dem vollen Namen des Benutzers 'ruben'createpassword: 'M31nP4p4157d3r4113r8357
' Variable mit dem initialen Klartextpasswortes der Benutzers 'ruben'tasks
Schlüsselwort mit den nachfolgenden Aufgaben, die mit dem Playbook dann abgearbeitet werden sollen.name
: Beschreibender Text(Make sure we have a group 'ruben' for our new admin-user 'ruben'), der später beim Aufruf von ansible-playbooks
ausgegeben werden soll.group:
Ansible Module group welches zum Anlegen, verändern und auch Löschen von Gruppen herangezogen werden kann. name
: Beschreibender Text(Add the user 'ruben' with a specific uid and a primary group of 'ruben'), der später beim Aufruf von ansible-playbooks
ausgegeben werden soll.user:
Ansible Module user welches zum Anlegen, verändern und auch Löschen von Benutzern herangezogen werden kann. name
: Beschreibender Text(Initial password generation for user 'ruben'), der später beim Aufruf von ansible-playbooks
ausgegeben werden soll.shell:
Ansible Module shell welches zum Ausführen von Shell-Befehlen auf dem Zielsystem verwendet werden kann. Hiermit setzen wir das Passwort unseres gerade angelegten Users 'ruben'....
Endekennzeichen der YML-DateiNun wollen wir unser ersten Playbook ausführen, um auf dem Zielhost den gewünschten Benutzer anzulegen; hierzu rufen wir unser Script wie folgt auf:
$ ansible-playbook -v 01_create-user.yml --limit=demo
Da wir den User erst einmal nur auf dem Host demo anlegen wollen,
schränken wir beim Aufruf des Playbooks die Ausführung mit dem Parameter limit=
entsprechend ein.
Using /etc/ansible/ansible.cfg as config file BECOME password: PLAY [centos8] **************************************************************************************************************************************** TASK [Gathering Facts] **************************************************************************************************************************************** ok: [www8.dmz.nausch.org]
TASK [Make sure we have a group 'ruben' for our new admin-user 'ruben'] **************************************************************** changed: [www8.dmz.nausch.org] => {"changed": true, "gid": 1010, "name": "ruben", "state": "present", "system": false}
TASK [Add the user 'ruben' with a specific uid and a primary group of 'ruben'] ********************************************************* changed: [www8.dmz.nausch.org] => {"changed": true, "comment": "Ruben Nausch", "create_home": true, "group": 1010, "home": "/home/ruben", "name": "ruben", "shell": "/bin/bash", "state": "present", "stderr": "Creating mailbox file: File exists\n", "stderr_lines": ["Creating mailbox file: File exists"], "system": false, "uid": 1010}
TASK [Initial password generation for user 'ruben'] ************************************************************************************ changed: [www8.dmz.nausch.org] => {"changed": true, "cmd": "usermod -p $(echo 'M31nP4p4157d3r4113r83573!' | openssl passwd -1 -stdin) ruben", "delta": "0:00:00.375778", "end": "2020-01-04 20:00:16.435753", "rc": 0, "start": "2020-01-04 20:00:16.059975", "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": []} PLAY RECAP *************************************************************************************************************************************** www8.dmz.nausch.org : ok=4 changed=3 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Bei jedem Ansible-Playbook werden beim Ausführen zu aller erst die sog. Facts durch Ansible gesammelt.
Anschliessend werden die einzelnen Tasks (Aufgaben) der Reihe nach abgearbeitet. In der Zeile nach TASK wird dann die Beschreibung ausgegeben, die wir im YAML-Script nach dem Schlüsselwort name:
angegeben hatten.
Bei der Ausgabe werden Stati mit einer entsprechneden Farbe hinterlegt:
Eine Zusammenfasssung für jeden Host wir am ende unter dem Kennzeichen PLAY RECAP nochmals zusammengefasst.
Auf dem Zielhost werden die Aktivitäten des Ansible-Playbooks entsprechend protokolliert.
# less /var/log/secure
Jan 4 19:59:51 vml000090 sshd[11916]: Postponed publickey for ansible from 10.0.0.27 port 50940 ssh2 [preauth] Jan 4 19:59:51 vml000090 sshd[11916]: Accepted publickey for ansible from 10.0.0.27 port 50940 ssh2: ED25519 SHA256:jTZQUDbCqZaV648fKVBfx3L4+tBMWL+z+iUCBY3kKMQ Jan 4 19:59:51 vml000090 systemd[11920]: pam_unix(systemd-user:session): session opened for user ansible by (uid=0) Jan 4 19:59:51 vml000090 sshd[11916]: pam_unix(sshd:session): session opened for user ansible by (uid=0) Jan 4 19:59:58 vml000090 sudo[12053]: ansible : TTY=pts/1 ; PWD=/home/ansible ; USER=root ; COMMAND=/bin/sh -c echo BECOME-SUCCESS-lxiprplnioypvfmjjylwxvdjapibaahs ; /usr/libexec/platform-python /home/ansible/.ansible/tmp/ansible-tmp-1578164696.339052-252470145168513/AnsiballZ_setup.py Jan 4 19:59:58 vml000090 sudo[12053]: pam_systemd(sudo:session): Cannot create session: Already running in a session or user slice Jan 4 19:59:58 vml000090 sudo[12053]: pam_unix(sudo:session): session opened for user root by ansible(uid=0) Jan 4 20:00:06 vml000090 sudo[12053]: pam_unix(sudo:session): session closed for user root Jan 4 20:00:12 vml000090 sudo[12213]: ansible : TTY=pts/1 ; PWD=/home/ansible ; USER=root ; COMMAND=/bin/sh -c echo BECOME-SUCCESS-dkoativjxmvilrtomekhdjnqzyyyuqqr ; /usr/libexec/platform-python /home/ansible/.ansible/tmp/ansible-tmp-1578164713.323935-211226042197181/AnsiballZ_group.py Jan 4 20:00:12 vml000090 sudo[12213]: pam_systemd(sudo:session): Cannot create session: Already running in a session or user slice Jan 4 20:00:12 vml000090 sudo[12213]: pam_unix(sudo:session): session opened for user root by ansible(uid=0) Jan 4 20:00:12 vml000090 groupadd[12222]: group added to /etc/group: name=ruben, GID=1010 Jan 4 20:00:12 vml000090 groupadd[12222]: group added to /etc/gshadow: name=ruben Jan 4 20:00:12 vml000090 groupadd[12222]: new group: name=ruben, GID=1010 Jan 4 20:00:12 vml000090 sudo[12213]: pam_unix(sudo:session): session closed for user root Jan 4 20:00:14 vml000090 sudo[12330]: ansible : TTY=pts/1 ; PWD=/home/ansible ; USER=root ; COMMAND=/bin/sh -c echo BECOME-SUCCESS-qrempbbpxxpgsigefdvnuctemlnerdpu ; /usr/libexec/platform-python /home/ansible/.ansible/tmp/ansible-tmp-1578164719.7395723-99484507541654/AnsiballZ_user.py Jan 4 20:00:14 vml000090 sudo[12330]: pam_systemd(sudo:session): Cannot create session: Already running in a session or user slice Jan 4 20:00:14 vml000090 sudo[12330]: pam_unix(sudo:session): session opened for user root by ansible(uid=0) Jan 4 20:00:14 vml000090 useradd[12339]: new user: name=ruben, UID=1010, GID=1010, home=/home/ruben, shell=/bin/bash Jan 4 20:00:14 vml000090 sudo[12330]: pam_unix(sudo:session): session closed for user root Jan 4 20:00:15 vml000090 sudo[12448]: ansible : TTY=pts/1 ; PWD=/home/ansible ; USER=root ; COMMAND=/bin/sh -c echo BECOME-SUCCESS-guzlsexqnsjzxvmqkxlzyfmeywwkmtxf ; /usr/libexec/platform-python /home/ansible/.ansible/tmp/ansible-tmp-1578164721.6724513-118758141371611/AnsiballZ_command.py Jan 4 20:00:15 vml000090 sudo[12448]: pam_systemd(sudo:session): Cannot create session: Already running in a session or user slice Jan 4 20:00:15 vml000090 sudo[12448]: pam_unix(sudo:session): session opened for user root by ansible(uid=0) Jan 4 20:00:16 vml000090 usermod[12455]: change user 'ruben' password Jan 4 20:00:16 vml000090 sudo[12448]: pam_unix(sudo:session): session closed for user root