Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.

Link zu dieser Vergleichsansicht

Beide Seiten der vorigen Revision Vorhergehende Überarbeitung
Nächste Überarbeitung
Vorhergehende Überarbeitung
linux:ansible:playbook_example_08 [22.09.2022 12:48. ] – [Script starten] djangolinux:ansible:playbook_example_08 [01.06.2024 13:48. ] (aktuell) – [Script starten] django
Zeile 17: Zeile 17:
  
 ==== Lösung ==== ==== Lösung ====
 +<WRAP center round tip 80%>
 +Der ungeduldigen Leser kann auch direkt zur Tat schreiten und das manuelle Anlegen des Verzeichnisses und des Ansible-Scripts überspringen. Mit Folgendem Befehl erledigt man dies sozusagen auf einem Rutsch:
 +
 +<code> $ mkdir ~/ansible ; wget https://gitlab.nausch.org/django/example_8a/-/archive/main/example_8a-main.tar.gz -O - | tar -xz --strip-components=1 -C ~/ansible</code>
 +
 +Anschliessend kann man direkt **[[#script_starten|zur Ausführung schreiten]]**.
 +</WRAP>
 === Script anlegen === === Script anlegen ===
 Zunächst müssen wir manuell einmal das Verzeichnis **''~/ansible/playbooks''** in dem wir unsere Ansible-Playbooks ablegen werden auf unserer Admin-Workstation bzw. dem **A**nsible-**C**ontroll-**N**ode anlegen. Zunächst müssen wir manuell einmal das Verzeichnis **''~/ansible/playbooks''** in dem wir unsere Ansible-Playbooks ablegen werden auf unserer Admin-Workstation bzw. dem **A**nsible-**C**ontroll-**N**ode anlegen.
Zeile 119: Zeile 126:
         - {directory: "library/"}         - {directory: "library/"}
         - {directory: "module_utils/"}         - {directory: "module_utils/"}
 +        - {directory: "playbooks/"}
         - {directory: "inventories/production/group_vars/"}         - {directory: "inventories/production/group_vars/"}
         - {directory: "inventories/production/host_vars/"}         - {directory: "inventories/production/host_vars/"}
Zeile 220: Zeile 228:
 ok: [localhost] => (item={'directory': 'library/'}) ok: [localhost] => (item={'directory': 'library/'})
 ok: [localhost] => (item={'directory': 'module_utils/'}) ok: [localhost] => (item={'directory': 'module_utils/'})
 +ok: [localhost] => (item={'directory': 'playbooks/'})
 ok: [localhost] => (item={'directory': 'inventories/production/group_vars/'}) ok: [localhost] => (item={'directory': 'inventories/production/group_vars/'})
 ok: [localhost] => (item={'directory': 'inventories/production/host_vars/'}) ok: [localhost] => (item={'directory': 'inventories/production/host_vars/'})
Zeile 272: Zeile 281:
  
  
-===== Aufgabenstellung 2 - "erweiterte" Grund-/Basis-Installation für Ansible-Vault =====+===== Aufgabenstellung 2 - "erweiterte" Grund-/Basis-Installation für Ansible-Vault unter Arch Linux=====
  
 <WRAP center round info 80%> <WRAP center round info 80%>
-Mit Hinblick auf das all umspannende Thema **Sicherheit in der IT** ist eines unserer Hauotaugenmerke, dass schützenswerte Informationen nicht mehr als plain-text in unserer  Ansible-Entwicklungsumgebnung ungeschützt herumliegen.  +Mit Hinblick auf das all umspannende Thema **Sicherheit in der IT** ist eines unserer Hauptaugenmerk, dass schützenswerte Informationen nicht mehr als plain-text in unserer  Ansible-Entwicklungsumgebung ungeschützt herumliegen.  
-Folgende Sicherheitsvorkehrungen wollen wir unseren Admins an die Hand geben: +Folgende Sicherheitsvorkehrungen wollen wir unseren Admins für die Arbeit mit **[[https://www.ansible.com/|Ansible]]** unter **[[https://archlinux.org/|Arch Linux]]** an die Hand geben: 
-  - Die Anmeldung an remote Hosts erfolgt mit Hilfe der **SSH** ausschließlich mit Schl+üsseln, auf keinen Fall über Passworte. Anmeldung als **root** sind grundsätzlich unterbunden, auch die Anmeldung mit Hilfe eines User-Keys als root ist ebensowenig gestattet! Der Admin muss den SSH-Privat-Key besitzen und von dessen Passphrase Kenntnis haben. Wird ein **Nitrokey Start** USB-Schlüssel verwendet, kann bei Bedarf auch der **[[suse:nitrokey:start#nitrokey_start_und_secure_shell|SSH-Key bei Verwendung der SSH]]** benutzt werden. Die Zusätzliche Eingabe einer Passphrase erübrigt sich dadurch auch hier, wenn der SSH-Key auf dem Kryptostick verwendet wird!+  - Die Anmeldung an remote Hosts erfolgt mit Hilfe der **SSH** ausschliesslich mit Schlüsseln, auf keinen Fall über Passworte. Anmeldung als **root** sind grundsätzlich unterbunden, auch die Anmeldung mit Hilfe eines User-Keys als **''root''** ist ebenso wenig gestattet! Der Admin muss den SSH-Private-Key besitzen und von dessen Passphrase Kenntnis haben. Wird ein **Nitrokey Start** USB-Schlüssel verwendet, kann bei Bedarf auch der **[[suse:nitrokey:start#nitrokey_start_und_secure_shell|SSH-Key bei Verwendung der SSH]]** benutzt werden. Die Zusätzliche Eingabe einer Passphrase erübrigt sich dadurch auch hier, wenn der SSH-Key auf dem Kryptostick verwendet wird!
   - Der Administrator soll beim Aufruf der Playbooks **__nur noch__** den PGP-Schlüssel durch Eingabe der zugehörigen Passphrase entsperren. Das Passwort für die Rechteerweiterung wird von Ansible aus dem Vault gelesen, genau so wie das **''become_password''** zur Rechteerweiterung.    - Der Administrator soll beim Aufruf der Playbooks **__nur noch__** den PGP-Schlüssel durch Eingabe der zugehörigen Passphrase entsperren. Das Passwort für die Rechteerweiterung wird von Ansible aus dem Vault gelesen, genau so wie das **''become_password''** zur Rechteerweiterung. 
  
-Wir wollen vertrauliche Informationen in unseren Playbooks bzw. im Inventory ausschließlich via **Ansible-Vault** vorhalten, da diese als krypted **AES256** Daten abgelegt und somit auch jederzeit in einem verteiltem Versionskontrollsystem wie **[[ https://git-scm.com/|git]]** vorgehalten werden können. Durch Nutzung des Passwort-Manager **''pass''** wird die Handhabung soweit vereinfacht, so dass der Admin auch ohne grosse Not mehrmals hintereinander Ansible-Playbooks ausführen kann, ohne sich durch zigfache Eingabe von Passworten sich selbst das Leben allzu schwer zu machen!+Wir wollen vertrauliche Informationen in unseren Playbooks bzw. im Inventory ausschliesslich via **Ansible-Vault** vorhalten, da diese als krypted **AES256** Daten abgelegt und somit auch jederzeit in einem verteiltem Versionskontrollsystem wie **[[ https://git-scm.com/|git]]** vorgehalten werden können. Durch Nutzung des Passwort-Manager **''pass''** wird die Handhabung soweit vereinfacht, so dass der Admin auch ohne grosse Not mehrmals hintereinander Ansible-Playbooks ausführen kann, ohne sich durch zigfache Eingabe von Passworten sich selbst das Leben allzu schwer zu machen!
  
 Aus Sicht von **IT-Security** haben wir somit einen erheblicher Zugewinn an Sicherheit. Die Akzeptanzschwelle ist durch Minimierung von mehrfachen Eingaben diverser Passworte durchaus niedrig, so dass für den Admin durchaus ein Mehrwert bei der täglichen administrativen Tätigkeit ausgemacht werden kann. Aus Sicht von **IT-Security** haben wir somit einen erheblicher Zugewinn an Sicherheit. Die Akzeptanzschwelle ist durch Minimierung von mehrfachen Eingaben diverser Passworte durchaus niedrig, so dass für den Admin durchaus ein Mehrwert bei der täglichen administrativen Tätigkeit ausgemacht werden kann.
 </WRAP> </WRAP>
  
-Damit wir nun diesen Vorüberlegungen gerecht werden können, benötigen wir eine vordefinierte Grundinstallation und Konfiguration der Ansible-Umgebung für unsere(n) Admin(s).  Damit diese Grund-Konfiguration unserer Ansible-Umgebung nicht von Hand erfolgen muss, greifen wir auf das Playbook **''ansible_grundconfig_v2.yml''** zurück. +Damit wir nun diesen Vorüberlegungen gerecht werden können, benötigen wir eine vordefinierte Grundinstallation und Konfiguration der Ansible-Umgebung für unsere(n) Admin(s) unter Arch Linux. Damit diese Grund-Konfiguration unserer Ansible-Umgebung nicht von Hand erfolgen muss, greifen wir auf das Playbook **''ansible_grundconfig_v2.yml''** zurück. 
  
-Mit Hilfe dieses Playbooks können alle erforderlichen Konfigurationsschritte reproduzierbar und beliebig oft abgesetzt werden. Bei Bedarf ist als also jederzeit ohne grossen Aufwand möglich den Ansible-Controll-Node neu aufzusetzen und das System für spätere Playbook-Rollouts vorzubereiten, den Host also auch initial frisch zu versorgen.+Mit Hilfe dieses Playbooks können alle erforderlichen Konfigurationsschritte reproduzierbar und beliebig oft abgesetzt werden. Bei Bedarf ist als also jederzeit ohne grossen Aufwand möglich den Ansible-Controll-Node unter **Arch Linux** neu aufzusetzen und das System für spätere Playbook-Rollouts vorzubereiten, den Host also auch initial frisch zu versorgen.
  
 Folgende Schritte sollen von dem playbook abgearbeitet werden: Folgende Schritte sollen von dem playbook abgearbeitet werden:
Zeile 295: Zeile 304:
   - Ansible Directory Layout anlegen und mit Dummy-Inhalten versorgen.   - Ansible Directory Layout anlegen und mit Dummy-Inhalten versorgen.
   - Installation und Konfiguration des Passwortmanagers **''pass''**.   - Installation und Konfiguration des Passwortmanagers **''pass''**.
-  - Hinterlegen des Ansible Become Passworetes in einem Ansible-Vault.+  - Hinterlegen des Ansible Become Passwortes in einem Ansible-Vault
 +  - Für die kompakte Ausgabe der Ansible Rückmeldungen soll der **[[playbook_example_12#ansible_stdout_compact_logger|Ansible Stdout Compact Logger]]** genutzt werden.
  
 Somit erreichen wir später bequem unser gestecktes Ziel unsere Zeit als Admin effizient zu nutzen und in einer sicheren Umgebung uns zu bewegen.  Somit erreichen wir später bequem unser gestecktes Ziel unsere Zeit als Admin effizient zu nutzen und in einer sicheren Umgebung uns zu bewegen. 
  
 ==== Lösung ==== ==== Lösung ====
 +<WRAP center round tip 90%>
 +Der ungeduldigen Leser kann auch direkt zur Tat schreiten und das manuelle Anlegen des Verzeichnisses und des Ansible-Scripts überspringen. Mit Folgendem Befehl erledigt man dies sozusagen auf einem Rutsch:
 +
 +<code> $ mkdir -p ~/devel/ansible ; wget https://gitlab.nausch.org/django/example_8b/-/archive/main/example_8b-main.tar.gz -O - | tar -xz --strip-components=1 -C ~/devel/ansible</code>
 +
 +Anschliessend kann man, nachdem man die Variablen wie z.B. **''admin_mail''** an die individuellen Bedürfnisse angepasst hat, dann auch gleich direkt **[[#script_starten1|zur Ausführung schreiten]]**.
 +</WRAP>
 === Script anlegen === === Script anlegen ===
 <WRAP center round important 60%> <WRAP center round important 60%>
Zeile 306: Zeile 323:
 </WRAP> </WRAP>
  
-Als erstes legen wir manuell einmal das Verzeichnis **''~/ansible/playbooks''**, in dem wir unsere Ansible-Playbooks ablegen werden auf unserer Admin-Workstation bzw. dem **A**nsible-**C**ontroll-**N**ode anlegen, sofern wir das noch nicht erstellt hatten. +Als erstes legen wir manuell einmal das Verzeichnis **''~/devel/ansible/playbooks''**, in dem wir unsere Ansible-Playbooks ablegen werden auf unserer Admin-Workstation bzw. dem **A**nsible-**C**ontroll-**N**ode anlegen, sofern wir das noch nicht erstellt hatten. 
-   $ mkdir -p ~/ansible/playbooks+   $ mkdir -p ~/devel/ansible/playbooks
  
 Hier legen wir nun unser Ansible-Playbook/-Script **''ansible_grundconfig_v2.yml''** ab, mit dessen Hilfe wir unsere Ansible-Umgebung individuell einrichten und konfigurieren wollen.   Hier legen wir nun unser Ansible-Playbook/-Script **''ansible_grundconfig_v2.yml''** ab, mit dessen Hilfe wir unsere Ansible-Umgebung individuell einrichten und konfigurieren wollen.  
    $ vim ~/ansible/playbooks/ansible_grundconfig_v2.yml    $ vim ~/ansible/playbooks/ansible_grundconfig_v2.yml
  
-<file c++ ~/ansible/playbooks/ansible_grundconfig_v2.yml>--- # YAML Start +{{ghhttps://gitlab.nausch.org/django/example_8b/-/blob/main/playbooks/ansible_grundconfig_v2.yml }}
-    # Ansible Playbook zum initialen Einrichten der Ansible-Umgebung +
-    # +
-    # Aufruf aus dem entsprechenden Arbeits-Verzeichnis via: +
-    # ansible-playbook playbooks/ansible_grundconfig_v2.ym -K +
- +
-- name: ansible_grundconfig_v2.yml +
-  gather_facts: true +
-  hosts: localhost +
-  become: true +
-  vars: +
-    ansible_working_dir: ansible +
-    ansible_config: /etc/ansible/ansible.cfg +
-    admin_user: "{{ lookup('env','USER') }}" +
-    admin_mail: django@nausch.org +
-  vars_prompt: +
-    - name: pass_secret +
-      prompt: "Enter password for password-store?" +
-    - name: pass_secret_2nd +
-      prompt: "Retype password for password-store?" +
-    - name: become_secret +
-      prompt: "Enter become-password for sudo?" +
-    - name: become_secret_2nd +
-      prompt: "Retype become-password for sudo?" +
- +
-  tasks: +
-    - name: "Playbooklauf abbrechen sofern die beiden eigegebenen Passwörter nicht übereinstimmen!" +
-      fail: +
-        msg: "Error: the entered password-store passwords do not match." +
-      when: +
-        - pass_secret != pass_secret_2nd +
- +
-    - name: "Playbooklauf abbrechen sofern die beiden eigegebenen Passwörter nicht übereinstimmen!" +
-      fail: +
-        msg: "Error: the entered become-passwords for sudo do not match." +
-      when: +
-        - become_secret != become_secret_2nd +
- +
-    - name: "Ansible Konfigurationsdatei {{ ansible_config }} vorhanden?" +
-      ansible.builtin.stat: +
-        path: '{{ ansible_config }}' +
-      register: check_ansible_config +
- +
-    - name: "Fehlerhinweis im Fehlerfall ausgeben" +
-      ansible.builtin.fail: +
-        msg: "Ansible Konfigurationsdatei {{ ansible_config }} NICHT gefunden!" +
-      when: check_ansible_config.stat.exists != 1 +
- +
-    - name: "Ansible Konfigurationsverzeichnis in das User/Admin-Verzeichnis kopieren" +
-      ansible.builtin.copy: +
-        dest: '/home/{{ admin_user }}/.ansible.cfg' +
-        group: '{{ admin_user }}' +
-        owner: '{{ admin_user }}' +
-        src: '{{ ansible_config }}' +
-        mode: '0640' +
- +
-    name: "Ansible Konfiguration anpassen" +
-      ansible.builtin.lineinfile: +
-        line: "{{ item.line }}" +
-        path: "/home/{{ admin_user }}/.ansible.cfg" +
-        regexp: "{{ item.regexp }}" +
-        state: present +
-      with_items: +
-        - { +
-          regexp: "^\\[defaults\\]", +
-          line: "[defaults]\n# Generated by Ansible on {{ ansible_date_time.date }}, do not edit manually!\n\ +
-          # default:\ninterpreter_python = auto_silent" +
-        } +
-        - { +
-          regexp: "^\\#inventory\ \ \ \ \ \ =\ /etc/ansible/hosts", +
-          line: "# Generated by Ansible on {{ ansible_date_time.date }}, do not edit manually!\n\ +
-          # default: #inventory      = /etc/ansible/hosts\n\ +
-          inventory       = /home/{{ admin_user }}/ansible/inventories/production" +
-        } +
-        - { +
-          regexp: "^\\#roles_path\ \ \ \ =\ /etc/ansible/roles", +
-          line: "# Generated by Ansible on {{ ansible_date_time.date }}, do not edit manually!\n\ +
-          # default: #roles_path    = /etc/ansible/roles\n\ +
-          roles_path    = ~/ansible/roles" +
-        } +
-        - { +
-          regexp: "^\\#vault_password_file\ =\ /path/to/vault_password_file", +
-          line: "# Generated by Ansible on {{ ansible_date_time.date }}, do not edit manually!\n\ +
-          # default: #vault_password_file = /path/to/vault_password_file\n\ +
-          vault_password_file = ~/bin/ansible_vault_password" +
-        } +
- +
-    - name: "Ansible Directory Layout anlegen" +
-      ansible.builtin.file: +
-        path: '/home/{{ admin_user }}/{{ ansible_working_dir }}/{{ item.directory }}' +
-        state: directory +
-        owner: '{{ admin_user }}' +
-        group: '{{ admin_user }}' +
-        mode: '0755' +
-      with_items: +
-        - {directory: "filter_plugins/"+
-        - {directory: "library/"+
-        - {directory: "module_utils/"+
-        - {directory: "inventories/production/group_vars/"+
-        - {directory: "inventories/production/host_vars/"+
-        - {directory: "inventories/staging/group_vars/"+
-        - {directory: "inventories/staging/host_vars/"+
-        - {directory: "roles/common/defaults/"+
-        - {directory: "roles/common/files/"+
-        - {directory: "roles/common/handlers/"+
-        - {directory: "roles/common/library/"+
-        - {directory: "roles/common/lookup_plugins/"+
-        - {directory: "roles/common/meta/"+
-        - {directory: "roles/common/module_utils/"+
-        - {directory: "roles/common/tasks/"+
-        - {directory: "roles/common/templates/"+
-        - {directory: "roles/common/vars/"+
- +
-    - name: "Ansible Directory Layout mit dummy-files main.yml befüllen" +
-      ansible.builtin.file: +
-        path: '/home/{{ admin_user }}/{{ ansible_working_dir }}/{{ item.file }}' +
-        state: touch +
-        owner: '{{ admin_user }}' +
-        group: '{{ admin_user }}' +
-        mode: '0640' +
-      with_items: +
-        - {file: "filter_plugins/main.yml"} +
-        - {file: "library/main.yml"} +
-        - {file: "module_utils/main.yml"+
-        - {file: "inventories/production/hosts"+
-        - {file: "inventories/production/group_vars/main.yml"+
-        - {file: "inventories/production/host_vars/main.yml"+
-        - {file: "inventories/staging/hosts"+
-        - {file: "inventories/staging/group_vars/main.yml"+
-        - {file: "inventories/staging/host_vars/main.yml"+
-        - {file: "roles/common/defaults/main.yml"+
-        - {file: "roles/common/files/main.yml"+
-        - {file: "roles/common/handlers/main.yml"+
-        - {file: "roles/common/library/main.yml"+
-        - {file: "roles/common/lookup_plugins/main.yml"+
-        - {file: "roles/common/meta/main.yml"+
-        - {file: "roles/common/module_utils/main.yml"+
-        - {file: "roles/common/tasks/main.yml"+
-        - {file: "roles/common/templates/main.yml"+
-        - {file: "roles/common/vars/main.yml"+
- +
-    - name: "Passwort-Manager pass installieren" +
-      ansible.builtin.package: +
-        name: pass +
-        update_cache: true +
-        state: latest +
- +
-    - name: "Verzeichnis ~/bin anlegen" +
-      ansible.builtin.file: +
-        path: '/home/{{ admin_user }}/bin' +
-        group: '{{ admin_user }}' +
-        owner: '{{ admin_user }}' +
-        state: directory +
-        mode: '0750' +
- +
-    - name: "vault-Wrapperscript anlegen" +
-      ansible.builtin.copy: +
-        dest: '/home/{{ admin_user }}/bin/ansible_vault_password' +
-        content: | +
-          #!/bin/bash +
-          # Ansible generated, do not edit manually! +
-          pass show ansible-vault-password +
-        owner: '{{ admin_user }}' +
-        group: '{{ admin_user }}' +
-        mode: '0750' +
- +
-    - name: "Sicherstellen dass das pass Store-Verzeichnis nicht existiert" +
-      ansible.builtin.file: +
-        path: '/home/{{ admin_user }}/.password-store' +
-        state: absent +
- +
-    - name: "Pass-Store Passwort ablegen" +
-      become_user: django +
-      become: true +
-      shell: | +
-        set -o pipefail && pass init '{{ admin_mail }}' && /usr/bin/echo '{{ pass_secret }}' | pass insert -ef ansible-vault-password +
-      changed_when: false +
-      args: +
-        executable: /bin/bash +
- +
-    - name: "Sicherstellen dass das File für das verschlüsselte become-password noch nicht existiert" +
-      ansible.builtin.file: +
-        path: '/home/{{ admin_user }}/ansible/inventories/production/group_vars/all/vault.yml' +
-        state: absent +
- +
-    - name: "Ansible Become Password für sudo Rechteerweiterung anlegen" +
-      ansible.builtin.copy: +
-        dest: '/home/{{ admin_user }}/ansible/inventories/production/group_vars/all/vault.yml' +
-        content: | +
-          ansible_become_pass: {{ become_secret }} +
-        owner: '{{ admin_user }}' +
-        group: '{{ admin_user }}' +
-        mode: '0640' +
- +
-    - name: "Ansible Become Password mit ansible-vault verschlüsseln" +
-      become_user: django +
-      become: true +
-      shell: | +
-        ansible-vault encrypt /home/{{ admin_user }}/ansible/inventories/production/group_vars/all/vault.yml +
-      changed_when: false +
- +
-... # YML Ende</file>+
  
 <WRAP center round important 60%> <WRAP center round important 60%>
 **Wichtig:** \\ **Wichtig:** \\
-Die Variable **''admin_mail''** passen wir natürlich noch unseren Gegebenheiten nach an, denn das Beispiel im Script wird sicherlich nicht für jedermann|frau zutreffen! 8-)+Die Variablen wie z.B. **''admin_mail''** passen wir natürlich noch unseren Gegebenheiten nach an, denn das Beispiel im Script wird sicherlich nicht für jedermann|frau zutreffen! 8-)
 </WRAP> </WRAP>
  
  
 === Script Beschreibung === === Script Beschreibung ===
-Mit Hilfe des Playbooks werden alle wesentlichen Konfigurationsoptionen definiert, die im Kapitel **[[first#grund-_konfiguration|(Grund-)Konfiguration - (Grund-)Konfiguration]]** detailliert beschrieben und besprochen wurden. Die Details zur spezifischen **Ansible-Vault** Konfiguration finden sich im Kapitel **[[playbook_example_07#ansible-vault_in_verbindung_mit_ansible-playbook|Ansible - erweitertes Konfigurationsbeispiel 7: Ansible Vault - ansible-vault in Verbindung mit ansible-playbook]]**.+Mit Hilfe des Playbooks werden für unseren Admin-User auf unserem Arch-Linux Host alle wesentlichen Konfigurationsoptionen definiert, die im Kapitel **[[first#grund-_konfiguration|(Grund-)Konfiguration - (Grund-)Konfiguration]]** detailliert beschrieben und besprochen wurden. Die Details zur spezifischen **Ansible-Vault** Konfiguration finden sich im Kapitel **[[playbook_example_07#ansible-vault_in_verbindung_mit_ansible-playbook|Ansible - erweitertes Konfigurationsbeispiel 7: Ansible Vault - ansible-vault in Verbindung mit ansible-playbook]]**.
  
 Nacheinander werden folgende Punkte abgearbeitet: Nacheinander werden folgende Punkte abgearbeitet:
   - Ermitteln des angemeldeten (Admin-)Usernamens **''admin_user''**, der für die weitere Programmlauf benötigt wird.   - Ermitteln des angemeldeten (Admin-)Usernamens **''admin_user''**, der für die weitere Programmlauf benötigt wird.
   - Abfrage des Passwortes für den **Password-Store** und des **''ansible_become_password''**, damit dies bei der weiteren Abarbeitung des Ansible-Playbooks entsprechend verschlüsselt in einer **vault**-Datei sicher abgelegt werden kann.   - Abfrage des Passwortes für den **Password-Store** und des **''ansible_become_password''**, damit dies bei der weiteren Abarbeitung des Ansible-Playbooks entsprechend verschlüsselt in einer **vault**-Datei sicher abgelegt werden kann.
-  - Prüfen, ob die Konfigurationsdatei **''/etc/ansible.cfg''** vorhanden ist und ggf. das Playbook geordnet abbrechen falls dies nicht der Fall sein sollte. +  - Generieren der Ansible Konfigurationsdatei **''/etc/ansible.cfg''** mit Hilfe von **''ansible-config init --disabled > ~/.ansible.cfg''**
-  - Kopieren der Ansible Konfigurationsdatei **''/etc/ansible.cfg''** nach **''~/.ansible.cfg''**.+
   - Setzen der Ansible-Konfigurationsoptionen   - Setzen der Ansible-Konfigurationsoptionen
     * **''interpreter_python = auto_silent''**     * **''interpreter_python = auto_silent''**
Zeile 535: Zeile 350:
     * **''vault_password_file = ~/bin/ansible_vault_password''**     * **''vault_password_file = ~/bin/ansible_vault_password''**
   - Ansible Directory Layout anlegen und anschliessend   - Ansible Directory Layout anlegen und anschliessend
-  - Ansible Directory Layout mit dummy-files main.yml befüllen.+  - Ansible Directory Layout mit dummy-files **''.gitkeep''** befüllen.
   - Installation des Passwort-Managers **''pass''**   - Installation des Passwort-Managers **''pass''**
   - vault-Wrapperscript im **''bin''** Verzeichnis des Admins ablegen und ggf. das zugehörige Verzeichnis anlegen.   - vault-Wrapperscript im **''bin''** Verzeichnis des Admins ablegen und ggf. das zugehörige Verzeichnis anlegen.
-  - Store-Passwort f+r **''pass''** im zugehörigen Verzeichnis ablegen, dabei ggf. ein bereits existierendes **pass**-Verzeichnis löschen.+  - Store-Passwort für **''pass''** im zugehörigen Verzeichnis ablegen, dabei ggf. ein bereits existierendes **pass**-Verzeichnis löschen.
   - Im Inventory das **''become_password''** unter **''group_vars/all''** ablegen und dabei eine bereits existierende vault-Datei vorher entfernen.   - Im Inventory das **''become_password''** unter **''group_vars/all''** ablegen und dabei eine bereits existierende vault-Datei vorher entfernen.
   - Ansible-Vault Datei, die zuvor angelegt wurde, mit dem Ansible-Vault-Passwort sicher verschlüsseln.    - Ansible-Vault Datei, die zuvor angelegt wurde, mit dem Ansible-Vault-Passwort sicher verschlüsseln. 
 +  - Im Inventory die Definitionen zu privilege_escalation anlegen und auch hier ggf. ein bereits existierende Konfigurationsdatei vorher löschen.
 +  - Installation und Konfiguration des Ansible Stdout Compact Logger unter Arch Linux
 +    * **''stdout_callback=anstomlog''**
 +    * **''callback_plugins   = ~/.ansible/plugins/callback"''**
 +
  
 === Script starten === === Script starten ===
 Das Ansible-Playbook lässt sich wie folgt auf dem Ansible-Controll-Host bzw. der Admin-Workstation aufrufen: Das Ansible-Playbook lässt sich wie folgt auf dem Ansible-Controll-Host bzw. der Admin-Workstation aufrufen:
  
-   $ ansible-playbook ~/ansible/playbooks/ansible_grundconfig_v2.yml -K +   $ ansible-playbook ~/devel/ansible/playbooks/ansible_grundconfig_v2.yml -K
- +
-<html> +
-<pre class="code"> +
-<font style="color: rgb(0, 0, 0)">BECOME password: </font> +
-<font style="color: rgb(170, 127, 166)"><b>[WARNING]: No inventory was parsed, only implicit localhost is available +
-[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'</b></font> +
-<font style="color: rgb(0, 0, 0)">Enter password for password-store?:  +
-Retype password for password-store?:  +
-Enter become-password for sudo?:  +
-Retype become-password for sudo?:  +
- +
-PLAY [ansible_grundconfig_v2.yml] ************************************************************************************************* +
- +
-TASK [Gathering Facts] ************************************************************************************************************</font> +
-<font style="color: rgb(25, 100, 5)">ok: [localhost]</font> +
-<font style="color: rgb(0, 0, 0)"> +
-TASK [Playbooklauf abbrechen sofern die beiden eigegebenen Passwörter nicht übereinstimmen!] **************************************</font> +
-<font style="color: rgb(43, 100, 164)">skipping: [localhost]</font> +
-<font style="color: rgb(0, 0, 0)"> +
-TASK [Playbooklauf abbrechen sofern die beiden eigegebenen Passwörter nicht übereinstimmen!] **************************************</font> +
-<font style="color: rgb(43, 100, 164)">skipping: [localhost]</font> +
-<font style="color: rgb(0, 0, 0)"> +
-TASK [Ansible Konfigurationsdatei /etc/ansible/ansible.cfg vorhanden?] ************************************************************</font> +
-<font style="color: rgb(25, 100, 5)">ok: [localhost]</font> +
-<font style="color: rgb(0, 0, 0)"> +
-TASK [Fehlerhinweis im Fehlerfall ausgeben] ***************************************************************************************</font> +
-<font style="color: rgb(43, 100, 164)">skipping: [localhost]</font> +
-<font style="color: rgb(0, 0, 0)"> +
-TASK [Ansible Konfigurationsverzeichnis in das User/Admin-Verzeichnis kopieren] ***************************************************</font> +
-<font style="color: rgb(196, 160, 0)">changed: [localhost]</font> +
-<font style="color: rgb(0, 0, 0)"> +
-TASK [Ansible Konfiguration anpassen] *********************************************************************************************</font> +
-<font style="color: rgb(196, 160, 0)">changed: [localhost] => (item={'regexp': '^\\[defaults\\]', 'line': '[defaults]\n# Generated by Ansible on 2022-09-22, do not edit manually!\n# default:\ninterpreter_python = auto_silent'}) +
-changed: [localhost] => (item={'regexp': '^\\#inventory      = /etc/ansible/hosts', 'line': '# Generated by Ansible on 2022-09-22, do not edit manually!\n# default: #inventory      = /etc/ansible/hosts\ninventory       = /home/django/ansible/inventories/production'}) +
-changed: [localhost] => (item={'regexp': '^\\#roles_path    = /etc/ansible/roles', 'line': '# Generated by Ansible on 2022-09-22, do not edit manually!\n# default: #roles_path    = /etc/ansible/roles\nroles_path    = ~/ansible/roles'}) +
-changed: [localhost] => (item={'regexp': '^\\#vault_password_file = /path/to/vault_password_file', 'line': '# Generated by Ansible on 2022-09-22, do not edit manually!\n# default: #vault_password_file = /path/to/vault_password_file\nvault_password_file = ~/bin/ansible_vault_password'})</font> +
-<font style="color: rgb(0, 0, 0)"> +
-TASK [Ansible Directory Layout anlegen] *******************************************************************************************</font> +
-<font style="color: rgb(25, 100, 5)">ok: [localhost] => (item={'directory': 'filter_plugins/'}) +
-ok: [localhost] => (item={'directory': 'library/'}) +
-ok: [localhost] => (item={'directory': 'module_utils/'}) +
-ok: [localhost] => (item={'directory': 'inventories/production/group_vars/'}) +
-ok: [localhost] => (item={'directory': 'inventories/production/host_vars/'}) +
-ok: [localhost] => (item={'directory': 'inventories/staging/group_vars/'}) +
-ok: [localhost] => (item={'directory': 'inventories/staging/host_vars/'}) +
-ok: [localhost] => (item={'directory': 'roles/common/defaults/'}) +
-ok: [localhost] => (item={'directory': 'roles/common/files/'}) +
-ok: [localhost] => (item={'directory': 'roles/common/handlers/'}) +
-ok: [localhost] => (item={'directory': 'roles/common/library/'}) +
-ok: [localhost] => (item={'directory': 'roles/common/lookup_plugins/'}) +
-ok: [localhost] => (item={'directory': 'roles/common/meta/'}) +
-ok: [localhost] => (item={'directory': 'roles/common/module_utils/'}) +
-ok: [localhost] => (item={'directory': 'roles/common/tasks/'}) +
-ok: [localhost] => (item={'directory': 'roles/common/templates/'}) +
-ok: [localhost] => (item={'directory': 'roles/common/vars/'})</font> +
-<font style="color: rgb(0, 0, 0)"> +
-TASK [Ansible Directory Layout mit dummy-files main.yml befüllen] ***************************************************************</font> +
-<font style="color: rgb(196, 160, 0)">changed: [localhost] => (item={'file': 'filter_plugins/main.yml'}) +
-changed: [localhost] => (item={'file': 'library/main.yml'}) +
-changed: [localhost] => (item={'file': 'module_utils/main.yml'}) +
-changed: [localhost] => (item={'file': 'inventories/production/hosts'}) +
-changed: [localhost] => (item={'file': 'inventories/production/group_vars/main.yml'}) +
-changed: [localhost] => (item={'file': 'inventories/production/host_vars/main.yml'}) +
-changed: [localhost] => (item={'file': 'inventories/staging/hosts'}) +
-changed: [localhost] => (item={'file': 'inventories/staging/group_vars/main.yml'}) +
-changed: [localhost] => (item={'file': 'inventories/staging/host_vars/main.yml'}) +
-changed: [localhost] => (item={'file': 'roles/common/defaults/main.yml'}) +
-changed: [localhost] => (item={'file': 'roles/common/files/main.yml'}) +
-changed: [localhost] => (item={'file': 'roles/common/handlers/main.yml'}) +
-changed: [localhost] => (item={'file': 'roles/common/library/main.yml'}) +
-changed: [localhost] => (item={'file': 'roles/common/lookup_plugins/main.yml'}) +
-changed: [localhost] => (item={'file': 'roles/common/meta/main.yml'}) +
-changed: [localhost] => (item={'file': 'roles/common/module_utils/main.yml'}) +
-changed: [localhost] => (item={'file': 'roles/common/tasks/main.yml'}) +
-changed: [localhost] => (item={'file': 'roles/common/templates/main.yml'}) +
-changed: [localhost] => (item={'file': 'roles/common/vars/main.yml'})</font> +
-<font style="color: rgb(0, 0, 0)"> +
-TASK [Passwort-Manager pass installieren] ***********************************************************************************</font> +
-<font style="color: rgb(25, 100, 5)">ok: [localhost]</font> +
-<font style="color: rgb(0, 0, 0)"> +
-TASK [Verzeichnis ~/bin anlegen] ********************************************************************************************</font> +
-<font style="color: rgb(25, 100, 5)">ok: [localhost]</font> +
-<font style="color: rgb(0, 0, 0)"> +
-TASK [vault-Wrapperscript anlegen] ******************************************************************************************</font> +
-<font style="color: rgb(25, 100, 5)">ok: [localhost]</font> +
-<font style="color: rgb(0, 0, 0)"> +
-TASK [Sicherstellen dass das pass Store-Verzeichnis nicht existiert] ********************************************************</font> +
-<font style="color: rgb(196, 160, 0)">changed: [localhost]</font> +
-<font style="color: rgb(0, 0, 0)"> +
-TASK [Pass-Store Passwort ablegen] ******************************************************************************************</font> +
-<font style="color: rgb(25, 100, 5)">ok: [localhost]</font> +
-<font style="color: rgb(0, 0, 0)"> +
-TASK [Sicherstellen dass das File für das verschlüsselte become-password noch nicht existiert] ******************************</font> +
-<font style="color: rgb(25, 100, 5)">ok: [localhost]</font> +
-<font style="color: rgb(0, 0, 0)"> +
-TASK [Ansible Become Password für sudo Rechteerweiterung anlegen] ***********************************************************</font> +
-<font style="color: rgb(196, 160, 0)">changed: [localhost]</font> +
-<font style="color: rgb(0, 0, 0)"> +
-TASK [Ansible Become Password mit ansible-vault verschlüsseln] **************************************************************</font> +
-<font style="color: rgb(25, 100, 5)">ok: [localhost]</font> +
-<font style="color: rgb(0, 0, 0)"> +
-PLAY RECAP ********************************************************************************************************************</font> +
-<font style="color: rgb(196, 160, 0)">localhost</font><font style="color: rgb(0, 0, 0)">                  : </font><font style="color: rgb(25, 100, 5)">ok=14    </font><font style="color: rgb(196, 160, 0)">changed=5    </font><font style="color: rgb(0, 0, 0)">unreachable=0    failed=0    </font><font style="color: rgb(43, 100, 164)">skipped=3    </font><font style="color: rgb(0, 0, 0)">rescued=0    ignored=0</font> +
- +
-</pre> +
-</html>+
  
 {{ :linux:ansible:ansible-krypto-stick.png?nolink&200|Bild: Ansible NitroKey Start}}Beim Aufruf eines Ansible-Playbooks liest das Programm **''ansible-playbook''** alle benötigten Dateien ein. Zum Abarbeiten benötigt Ansible natürlich die temporär entschlüsselten Informationen. Damit Ansible nun die verschlüsselten Informationen herankommt, benötigt Ansible natürlich vorübergehend das Vault-Passwort/-Passphrase, welches sich nun selbst verschlüsselt in einem Ansible-Vault befindet. Durch den Passwortmanager **''pass''** und unserem PGP-Schlüssel kommen wir nun direkt zu dem **Ansible Vault Passwort**. Wir brauchen also nur einmal das für den PGP zugehörige Passwort oder im Falle der Verwendung eines Security-Hardware-Devices wie eines **[[https://shop.nitrokey.com/de_DE/shop/product/nksa-nitrokey-start-6|Nitrokey Start]]**. {{ :linux:ansible:ansible-krypto-stick.png?nolink&200|Bild: Ansible NitroKey Start}}Beim Aufruf eines Ansible-Playbooks liest das Programm **''ansible-playbook''** alle benötigten Dateien ein. Zum Abarbeiten benötigt Ansible natürlich die temporär entschlüsselten Informationen. Damit Ansible nun die verschlüsselten Informationen herankommt, benötigt Ansible natürlich vorübergehend das Vault-Passwort/-Passphrase, welches sich nun selbst verschlüsselt in einem Ansible-Vault befindet. Durch den Passwortmanager **''pass''** und unserem PGP-Schlüssel kommen wir nun direkt zu dem **Ansible Vault Passwort**. Wir brauchen also nur einmal das für den PGP zugehörige Passwort oder im Falle der Verwendung eines Security-Hardware-Devices wie eines **[[https://shop.nitrokey.com/de_DE/shop/product/nksa-nitrokey-start-6|Nitrokey Start]]**.
Zeile 660: Zeile 374:
 Nach der Abfrage des **''PGP-Passwortes''** bzw. der **PIN** bei Verwendung eines **Nitrokey Start** wird dann sofort das Playbook ausgeführt. Eine zusätzliche Eingabe eines **''become_password''** ist nunmehr nicht mehr nötig. Nach der Abfrage des **''PGP-Passwortes''** bzw. der **PIN** bei Verwendung eines **Nitrokey Start** wird dann sofort das Playbook ausgeführt. Eine zusätzliche Eingabe eines **''become_password''** ist nunmehr nicht mehr nötig.
  
 +===== Fazit und Ausblick =====
 +<WRAP center round info 60%>
 +Wir haben nun Dank der beiden gezeigten Ansible-Playbooks zur Konfiguration unserer Ansible-Umgebung die Möglichkeit, jederzeit bei Bedarf einen weiteren Admin zu befähigen bzw. eine bestehende Umgebung erneut auszurollen. Somit können wir nun mit **Ansible-Vault** vertrauliche Informationen in unseren Playbooks bzw. im Inventory ablegen. Diese werden als krypted **AES256** Daten abgelegt und können dadurch auch jederzeit in einem verteiltem Versionskontrollsystem wie **[[ https://git-scm.com/|git]]** vorgehalten werden. Durch Nutzung des Passwort-Manager **''pass''** wird die Handhabung soweit vereinfacht, so dass der Admin auch ohne grosse Not mehrmals hintereinander Ansible-Playbooks ausführen kann, ohne sich durch zigfache Eingabe von Passworten sich selbst das Leben allzu schwer zu machen!
 +</WRAP>
  
 +====== Links ======
 +  * **[[detail|zurück zum Kapitel "Ansible - Erweiterte Konfigurationsbeispiele"]] <= **
 +  * **=> [[playbook_example_09|weiter zum Kapitel "Ansible - Erweiterte Konfigurationsbeispiel: Inventory]]**
 +  * **[[start|Zurück zur "Ansible"-Übersicht]]**
 +  * **[[wiki:start|Zurück zu >>Projekte und Themenkapitel<<]]**
 +  * **[[http://dokuwiki.nausch.org/doku.php/|Zurück zur Startseite]]**
  • linux/ansible/playbook_example_08.1663850885.txt.gz
  • Zuletzt geändert: 22.09.2022 12:48.
  • von django