Dies ist eine alte Version des Dokuments!
Ansible - erweitertes Konfigurationsbeispiel: Ansible "Basic" mit Hilfe von Ansible einrichten
Im Eingangskapitel Grundlagen haben wir uns mit der Installation bereits befasst. Mit den Hintergrundinformationen haben wir uns auch schon in den beiden Kapiteln Playbooks und YAML - was ist das? eingehend beschäftigt, sowie erste Erfahrungen mit Playbooks gesammelt.
Aufgabenstellung
Für die Grundkonfiguration in der Basisausführung der Ansible-Umgebung, wie wir Sie im Kapitel Erste Schritte Rund um Ansible - (Grund-)Konfiguration Eingangs kennengelernt hatten, benötigen wir eine vordefinierte Grundinstallation und Konfiguration. Damit diese Erstkonfiguration unserer Ansible-Umgebung nicht von Hand erfolgen muss, greifen wir auf das Playbook ansible_grundconfig.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.
Folgende Schritte sollen von dem playbook abgearbeitet werden:
- Kopieren der Ansible-Konfigurationsdatei /etc/ansible/ansible.cfg in das
$HOME
-Verzeichnis des Admin-Users. - Anpassen, sprich konfigurieren der individuellen Ansible Umgebung.
- Ansible Directory Layout anlegen und mit Dummy-Inhalten versorgen.
Schliesslich wollen wir unsere Zeit als Admin ja auch sinnvoll nutzen und mit möglichst geringen Aufwand zu Ziel kommen.
Lösung
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 Ansible-Controll-Node anlegen.
$ mkdir -p ~/ansible/playbooks
Hier legen wir nun unser Ansible-Playbook/-Script ansible_grundconfig_v1.yml
ab, mit dessen Hilfe wir unsere Ansible-Umgebung individuell einrichten und konfigurieren wollen.
$ vim ~/ansible/playbooks/ansible_grundconfig_v1.yml
- ~/ansible/playbooks/ansible_grundconfig_v1.yml
--- # YAML Start # Ansible Playbook zum initialen Einrichten der Ansible-Umgebung # # Aufruf aus dem entsprechenden Arbeits-Verzeichnis via: # ansible-playbook playbooks/ansible_grundconfig_v1.yml -K - name: ansible_grundconfig_v1.yml gather_facts: true hosts: localhost become: true vars: ansible_working_dir: ansible ansible_config: /etc/ansible/ansible.cfg admin_user: "{{ lookup('env','USER') }}" tasks: - 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: "^\\#become=True", line: "# Generated by Ansible on {{ ansible_date_time.date }}, do not edit manually!\n\ # default: #become=True\n\ become=True" } - { regexp: "^\\#become_method=sudo", line: "# Generated by Ansible on {{ ansible_date_time.date }}, do not edit manually!\n\ # default: #become_method=sudo\n\ become_method=sudo" } - { regexp: "^\\#become_user=root", line: "# Generated by Ansible on {{ ansible_date_time.date }}, do not edit manually!\n\ # default: #become_user=root\n\ become_user=root" } - { regexp: "^\\#become_ask_pass=False", line: "# Generated by Ansible on {{ ansible_date_time.date }}, do not edit manually!\n\ # default: #become_ask_pass=False\n\ become_ask_pass=True" } - { 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" } - 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"} ... # YML Ende
Script Beschreibung
Mit Hilfe des Playbooks werden alle wesentlichen Konfigurationsoptionen definiert, die im Kapitel (Grund-)Konfiguration - (Grund-)Konfiguration detailliert beschrieben und besprochen wurden. Nacheinander werden folgende Punkte abgearbeitet:
- Ermitteln des angemeldeten (Admin-)Usernamens
admin_user
, der für die weitere Programmlauf benötigt wird. - Prüfen, ob die Konfigurationsdatei
/etc/ansible.cfg
vorhanden ist und ggf. das Playbook geordnet abbrechen falls dies nicht der Fall sein sollte. - Kopieren der Ansible Konfigurationsdatei
/etc/ansible.cfg
nach~/.ansible.cfg
. - Setzen der Ansible-Konfigurationsoptionen
interpreter_python = auto_silent
inventory = /home/{{ admin_user }}/ansible/inventories/production
become=True
become_method=sudo
become_user=root
become_ask_pass=True
roles_path = ~/ansible/roles
- Ansible Directory Layout anlegen und anschliessend
- Ansible Directory Layout mit dummy-files main.yml befüllen.
Script starten
Das Ansible-Playbook lässt sich wie folgt auf dem Ansible-Controll-Host bzw. der Admin-Workstation aufrufen:
$ ansible-playbook ~/ansible/playbooks/ansible_grundconfig_v1.yml -K
BECOME password: [WARNING]: Unable to parse /home/django/ansible/inventories/production as an inventory source [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' PLAY [ansible_grundconfig_v1.yml] ************************************************************************************************* TASK [Gathering Facts] ************************************************************************************************************ ok: [localhost] TASK [Ansible Konfigurationsdatei /etc/ansible/ansible.cfg vorhanden?] ************************************************************ ok: [localhost] TASK [Fehlerhinweis im Fehlerfall ausgeben] *************************************************************************************** skipping: [localhost] TASK [Ansible Konfigurationsverzeichnis in das User/Admin-Verzeichnis kopieren] *************************************************** changed: [localhost] TASK [Ansible Konfiguration anpassen] ********************************************************************************************* 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': '^\\#become=True', 'line': '# Generated by Ansible on 2022-09-22, do not edit manually!\n# default: #become=True\nbecome=True'})changed: [localhost] => (item={'regexp': '^\\#become_method=sudo', 'line': '# Generated by Ansible on 2022-09-22, do not edit manually!\n# default: #become_method=sudo\n become_method=sudo'}) changed: [localhost] => (item={'regexp': '^\\#become_user=root', 'line': '# Generated by Ansible on 2022-09-22, do not edit manually!\n# default: #become_user=root\nbecome_user=root'}) changed: [localhost] => (item={'regexp': '^\\#become_ask_pass=False', 'line': '# Generated by Ansible on 2022-09-22, do not edit manually!\n# default: #become_ask_pass=False\nbecome_ask_pass=True'}) 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'}) TASK [Ansible Directory Layout anlegen] ******************************************************************************************* 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/'}) TASK [Ansible Directory Layout mit dummy-files main.yml befüllen] *************************************************************** 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'}) PLAY RECAP ******************************************************************************************************************** localhost : ok=6 changed=3 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0