Komplexe Ansible Playbooks auf RHEL strukturieren

AnsibleAnsibleBeginner
Jetzt üben

💡 Dieser Artikel wurde von AI-Assistenten übersetzt. Um die englische Version anzuzeigen, können Sie hier klicken

Einleitung

In diesem Lab lernen Sie wesentliche Techniken zur Strukturierung komplexer Ansible Playbooks auf RHEL, um eine besser verwaltbare, skalierbare und wiederverwendbare Automatisierung zu erstellen. Sie werden von grundlegenden Konzepten zu fortgeschrittenen Organisationsstrategien übergehen und sich darauf konzentrieren, wie Sie präzise steuern, auf welchen Hosts Ihre Automatisierung ausgeführt wird und wie Sie große Playbooks in logische, modulare Komponenten aufteilen.

Sie beginnen mit der Beherrschung der Host-Auswahl, indem Sie grundlegende Gruppennamen, Wildcards, Ausschlüsse und logische Operatoren verwenden, um bestimmte Knoten in Ihrem Inventar anzusprechen. Als Nächstes erkunden Sie die Modularisierung, indem Sie Tasks mit include_tasks und import_tasks in separate Dateien refaktorieren. Schließlich lernen Sie, einen vollständigen Workflow mit mehreren Playbooks mit import_playbook zu erstellen, der in der Ausführung und Überprüfung Ihres vollständig strukturierten und modularisierten Ansible-Projekts gipfelt.

Auswahl von Hosts mit Basis- und Wildcard-Mustern

In diesem Schritt lernen Sie die Grundlagen der gezielten Ansprache spezifischer Hosts in Ihrer Ansible-Automatisierung. Der Kern davon ist die Ansible-Inventardatei, die die von Ihnen verwalteten Server auflistet, und die hosts-Direktive in einem Playbook, die angibt, gegen welche dieser Server eine Reihe von Tasks ausgeführt werden soll. Wir beginnen mit der Installation von Ansible, der Erstellung eines grundlegenden Inventars und Playbooks und untersuchen dann, wie Hosts mithilfe von Gruppennamen und Wildcard-Mustern ausgewählt werden.

Zuerst stellen wir sicher, dass Ansible in Ihrer Umgebung installiert ist. Ansible ist nicht standardmäßig installiert, daher müssen Sie es mit dem DNF-Paketmanager installieren. Das Paket ansible-core stellt die wesentlichen Ansible-Befehlszeilentools bereit, einschließlich ansible-playbook. Führen Sie den folgenden Befehl aus:

sudo dnf install -y ansible-core

Sie sollten eine Ausgabe ähnlich dieser sehen:

...
Installed:
  ansible-core-2.16.x-x.el9.x86_64
  ...
Complete!

Als Nächstes erstellen wir ein dediziertes Verzeichnis für diese Übung, um unsere Dateien organisiert zu halten. Alle nachfolgenden Aktionen in diesem Schritt finden innerhalb dieses neuen Verzeichnisses statt:

mkdir -p ~/project/ansible_patterns
cd ~/project/ansible_patterns

Erstellen Sie nun eine Inventardatei. Ein Inventar ist eine Textdatei, die die Hosts und Host-Gruppen definiert, auf denen Ansible-Befehle, Module und Tasks ausgeführt werden. Wir verwenden das INI-Format aufgrund seiner Einfachheit.

Verwenden Sie den nano-Editor, um eine Datei namens inventory zu erstellen:

nano inventory

Fügen Sie den folgenden Inhalt in die Datei inventory ein. Dies definiert zwei Gruppen, webservers und dbservers, die jeweils zwei Hosts enthalten:

[webservers]
web1.example.com
web2.example.com

[dbservers]
db1.lab.net
db2.lab.net

Speichern Sie die Datei und beenden Sie nano, indem Sie Strg+X, dann Y und Enter drücken.

Mit unserem vorbereiteten Inventar erstellen wir nun ein einfaches Playbook. Dieses Playbook verwendet das Modul ansible.builtin.debug, um eine Nachricht auszugeben und zu bestätigen, auf welchem Host der Task ausgeführt wird. Dies ist eine großartige Möglichkeit, Host-Muster zu testen, ohne tatsächliche Änderungen am System vorzunehmen.

Erstellen Sie eine neue Datei namens playbook.yml:

nano playbook.yml

Fügen Sie den folgenden YAML-Inhalt hinzu. Anfangs zielt es auf alle Hosts in der Gruppe webservers ab:

---
- name: Test Host Patterns
  hosts: webservers
  gather_facts: false
  tasks:
    - name: Display the inventory hostname
      ansible.builtin.debug:
        msg: "This task is running on {{ inventory_hostname }}"

Speichern und beenden Sie den Editor. Führen Sie nun das Playbook mit ansible-playbook aus. Das Flag -i gibt unsere benutzerdefinierte Inventardatei an:

ansible-playbook playbook.yml -i inventory

Die Ausgabe sollte wie folgt aussehen:

PLAY [Test Host Patterns] ******************************************************

TASK [Display the inventory hostname] ******************************************
ok: [web1.example.com] => {
    "msg": "This task is running on web1.example.com"
}
ok: [web2.example.com] => {
    "msg": "This task is running on web2.example.com"
}

PLAY RECAP *********************************************************************
web1.example.com           : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
web2.example.com           : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

Wie Sie sehen können, wurden nur die Hosts aus der Gruppe webservers angesprochen. Ändern wir nun das Playbook, um einen Wildcard (*) zu verwenden. Wildcards ermöglichen eine flexiblere Mustererkennung.

Bearbeiten Sie playbook.yml und ändern Sie die Zeile hosts zu hosts: "*.lab.net". Denken Sie daran, Muster, die Wildcards enthalten, in Anführungszeichen zu setzen:

---
- name: Test Host Patterns
  hosts: "*.lab.net"
  gather_facts: false
  tasks:
    - name: Display the inventory hostname
      ansible.builtin.debug:
        msg: "This task is running on {{ inventory_hostname }}"

Führen Sie das Playbook erneut aus:

ansible-playbook playbook.yml -i inventory

Sie sollten eine Ausgabe ähnlich dieser sehen:

PLAY [Test Host Patterns] ******************************************************

TASK [Display the inventory hostname] ******************************************
ok: [db1.lab.net] => {
    "msg": "This task is running on db1.lab.net"
}
ok: [db2.lab.net] => {
    "msg": "This task is running on db2.lab.net"
}

PLAY RECAP *********************************************************************
db1.lab.net                : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
db2.lab.net                : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

Dieses Mal wurde das Play nur auf Hosts ausgeführt, deren Namen auf .lab.net enden. Lassen Sie uns schließlich das spezielle Schlüsselwort all verwenden, um jeden im Inventar definierten Host anzusprechen.

Bearbeiten Sie playbook.yml ein letztes Mal und ändern Sie die Zeile hosts zu hosts: all:

---
- name: Test Host Patterns
  hosts: all
  gather_facts: false
  tasks:
    - name: Display the inventory hostname
      ansible.builtin.debug:
        msg: "This task is running on {{ inventory_hostname }}"

Führen Sie das Playbook aus, um das Ergebnis zu sehen:

ansible-playbook playbook.yml -i inventory

Die Ausgabe zeigt, dass alle Hosts angesprochen werden:

PLAY [Test Host Patterns] ******************************************************

TASK [Display the inventory hostname] ******************************************
ok: [web1.example.com] => {
    "msg": "This task is running on web1.example.com"
}
ok: [web2.example.com] => {
    "msg": "This task is running on web2.example.com"
}
ok: [db1.lab.net] => {
    "msg": "This task is running on db1.lab.net"
}
ok: [db2.lab.net] => {
    "msg": "This task is running on db2.lab.net"
}

PLAY RECAP *********************************************************************
db1.lab.net                : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
db2.lab.net                : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
web1.example.com           : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
web2.example.com           : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

Das Playbook wird nun auf allen vier Hosts aus Ihrem Inventar ausgeführt und demonstriert die Leistungsfähigkeit des all-Musters.

Verfeinerung der Host-Auswahl mit Ausschlüssen und logischen Operatoren

In diesem Schritt erweitern Sie Ihre Fähigkeiten zur Host-Auswahl, indem Sie lernen, wie Sie Ausschlüsse und logische Operatoren verwenden. Diese Funktionen ermöglichen eine sehr spezifische Zielauswahl, die für die Verwaltung komplexer Umgebungen unerlässlich ist. Sie lernen, Hosts mithilfe des ! (NICHT)-Operators auszuschließen und Gruppen mithilfe des & (UND)-Operators zu kombinieren. Wir werden weiterhin mit den Dateien inventory und playbook.yml aus dem vorherigen Schritt arbeiten.

Stellen Sie zunächst sicher, dass Sie sich im richtigen Arbeitsverzeichnis befinden:

cd ~/project/ansible_patterns

Um logische Operatoren effektiv zu demonstrieren, müssen wir eine gewisse Überschneidung in unseren Host-Gruppen schaffen. Bearbeiten wir die Datei inventory, um eine neue Gruppe namens production hinzuzufügen, die einen Webserver und einen Datenbankserver enthält:

nano inventory

Fügen Sie die Gruppe [production] und ihre Mitglieder am Ende der Datei hinzu:

[webservers]
web1.example.com
web2.example.com

[dbservers]
db1.lab.net
db2.lab.net

[production]
web1.example.com
db1.lab.net

Speichern Sie die Datei und beenden Sie nano, indem Sie Strg+X, dann Y und Enter drücken.

Üben wir nun den Ausschluss. Der Operator ! (NICHT) ermöglicht es Ihnen, einen Host oder eine Gruppe aus einer Auswahl auszuschließen. Ändern Sie Ihr playbook.yml, um alle Hosts anzusprechen, außer denen in der Gruppe dbservers:

nano playbook.yml

Aktualisieren Sie die Zeile hosts wie unten gezeigt. Das Muster all,!dbservers wählt jeden Host aus und entfernt dann alle, die sich in der Gruppe dbservers befinden:

---
- name: Test Host Patterns
  hosts: all,!dbservers
  gather_facts: false
  tasks:
    - name: Display the inventory hostname
      ansible.builtin.debug:
        msg: "This task is running on {{ inventory_hostname }}"

Speichern und beenden Sie den Editor und führen Sie dann das Playbook aus:

ansible-playbook playbook.yml -i inventory

Sie sollten nur die Webserver angesprochen sehen:

PLAY [Test Host Patterns] ******************************************************

TASK [Display the inventory hostname] ******************************************
ok: [web1.example.com] => {
    "msg": "This task is running on web1.example.com"
}
ok: [web2.example.com] => {
    "msg": "This task is running on web2.example.com"
}

PLAY RECAP *********************************************************************
web1.example.com           : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
web2.example.com           : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

Wie erwartet wurden nur die Hosts aus der Gruppe webservers angesprochen.

Als Nächstes untersuchen wir den logischen UND-Operator. Der Operator & wählt nur die Hosts aus, die in beiden angegebenen Gruppen vorhanden sind (eine Schnittmenge). Ändern wir das Playbook, um Hosts anzusprechen, die sich in der Gruppe webservers UND auch in der Gruppe production befinden:

nano playbook.yml

Ändern Sie die Zeile hosts zu webservers,&production:

---
- name: Test Host Patterns
  hosts: webservers,&production
  gather_facts: false
  tasks:
    - name: Display the inventory hostname
      ansible.builtin.debug:
        msg: "This task is running on {{ inventory_hostname }}"

Speichern und führen Sie das Playbook aus:

ansible-playbook playbook.yml -i inventory

Dieses Mal wird nur die Schnittmenge beider Gruppen angesprochen:

PLAY [Test Host Patterns] ******************************************************

TASK [Display the inventory hostname] ******************************************
ok: [web1.example.com] => {
    "msg": "This task is running on web1.example.com"
}

PLAY RECAP *********************************************************************
web1.example.com           : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

Die Ausgabe zeigt korrekt an, dass nur web1.example.com angesprochen wurde, da es der einzige Host ist, der sowohl Mitglied der Gruppen webservers als auch production ist. Diese Operatoren geben Ihnen die präzise Kontrolle darüber, welche Hosts Ihre Automatisierung beeinflusst.

Modularisierung eines Plays mit include_tasks und import_tasks

In diesem Schritt lernen Sie, wie Sie größere Ansible-Projekte strukturieren, indem Sie sie in kleinere, wiederverwendbare Dateien aufteilen. Wenn Playbooks wachsen, wird es schwierig, alle Tasks in einer einzigen Datei zu verwalten. Ansible bietet hierfür zwei Hauptdirektiven: import_tasks und include_tasks. Beide ermöglichen es Ihnen, Tasks aus einer anderen Datei zu laden.

  • import_tasks ist statisch. Sie wird verarbeitet, wenn das Playbook zum ersten Mal von Ansible analysiert wird. Dies ist am besten für bedingungslose, strukturelle Teile Ihres Plays geeignet.
  • include_tasks ist dynamisch. Sie wird während der Ausführung des Plays verarbeitet. Dies macht sie für die Verwendung mit Schleifen und Bedingungen geeignet.

Wir werden nun unser Playbook refaktorisieren, um beide zu verwenden. Stellen Sie zunächst sicher, dass Sie sich im Projektverzeichnis befinden:

cd ~/project/ansible_patterns

Bevor wir fortfahren, aktualisieren wir die Inventardatei, damit die Hosts für diese Laborumgebung auf localhost zeigen. Dies ermöglicht die erfolgreiche Ausführung des Playbooks:

nano inventory

Ersetzen Sie den Inhalt durch die folgende Konfiguration, die die Beispielhosts localhost zuordnet:

[webservers]
web1.example.com ansible_host=localhost ansible_connection=local
web2.example.com ansible_host=localhost ansible_connection=local

[dbservers]
db1.lab.net ansible_host=localhost ansible_connection=local
db2.lab.net ansible_host=localhost ansible_connection=local

Speichern und beenden Sie den Editor. Diese Konfiguration verwendet ansible_host=localhost, um Verbindungen zur lokalen Maschine umzuleiten, und ansible_connection=local, um SSH-Verbindungsversuche zu vermeiden.

Eine gängige Praxis ist die Speicherung wiederverwendbarer Task-Dateien in einem dedizierten Unterverzeichnis. Erstellen wir eines namens tasks:

mkdir tasks

Nun erstellen wir eine Datei für allgemeine Setup-Tasks, die für viele Server gelten könnten. Hier platzieren wir einen Task zur Installation des httpd-Webserver-Pakets:

nano tasks/web_setup.yml

Fügen Sie den folgenden Inhalt hinzu. Beachten Sie, dass diese Datei nur eine Liste von Tasks ist; sie enthält keine vollständige Play-Struktur (wie hosts: oder name:):

- name: Install the httpd package
  ansible.builtin.dnf:
    name: httpd
    state: present
  become: true

Speichern und beenden Sie nano. Erstellen Sie als Nächstes eine zweite Task-Datei für einen einfachen Verifizierungsschritt:

nano tasks/verify_config.yml

Fügen Sie dieser Datei den folgenden Debug-Task hinzu:

- name: Display a verification message
  ansible.builtin.debug:
    msg: "Configuration tasks applied to {{ inventory_hostname }}"

Speichern und beenden Sie den Editor. Ändern wir nun das Haupt-playbook.yml, um diese neuen Task-Dateien zu verwenden. Wir verwenden import_tasks für das statische Setup und include_tasks für die dynamische Verifizierungsnachricht:

nano playbook.yml

Ersetzen Sie den gesamten Inhalt von playbook.yml durch Folgendes. Dieses Playbook zielt nun auf die Gruppe webservers ab und verwendet die modularen Task-Dateien:

---
- name: Configure Web Servers
  hosts: webservers
  gather_facts: false
  tasks:
    - name: Import web server setup tasks
      import_tasks: tasks/web_setup.yml

    - name: Include verification tasks
      include_tasks: tasks/verify_config.yml

Speichern Sie die Datei und führen Sie das Playbook aus:

ansible-playbook playbook.yml -i inventory

Sie sollten sehen, wie die modularen Tasks ausgeführt werden:

PLAY [Configure Web Servers] ***************************************************

TASK [Import web server setup tasks] *******************************************
imported: /home/labex/project/ansible_patterns/tasks/web_setup.yml

TASK [Install the httpd package] ***********************************************
changed: [web1.example.com]
changed: [web2.example.com]

TASK [Include verification tasks] **********************************************
included: /home/labex/project/ansible_patterns/tasks/verify_config.yml for web1.example.com, web2.example.com

TASK [Display a verification message] ******************************************
ok: [web1.example.com] => {
    "msg": "Configuration tasks applied to web1.example.com"
}
ok: [web2.example.com] => {
    "msg": "Configuration tasks applied to web2.example.com"
}

PLAY RECAP *********************************************************************
web1.example.com           : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
web2.example.com           : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

Beachten Sie, wie die Ausgabe klar anzeigt, wann Tasks aus ihren jeweiligen Dateien importiert und eingeschlossen werden. Dieser modulare Ansatz macht Ihre Automatisierung übersichtlicher und einfacher zu warten.

Komponieren eines Workflows mit import_playbook

In diesem Schritt lernen Sie, ganze Playbooks zu orchestrieren, um einen komplexen Workflow mit import_playbook zu bilden. Während import_tasks und include_tasks zur Wiederverwendung von Task-Listen innerhalb eines einzelnen Plays dienen, operiert import_playbook auf einer höheren Ebene. Es ermöglicht Ihnen, ein Master-Playbook zu erstellen, das andere, in sich geschlossene Playbooks in einer bestimmten Reihenfolge ausführt. Dies ist der Standardweg zur Verwaltung von Automatisierung im großen Maßstab, wie z. B. der Bereitstellung eines gesamten Anwendungsstacks.

Stellen Sie zunächst sicher, dass wir uns im richtigen Verzeichnis befinden und organisieren Sie unser Projekt für diese neue Struktur:

cd ~/project/ansible_patterns

Es ist eine bewährte Methode, einzelne, komponentenbasierte Playbooks in einem dedizierten Unterverzeichnis zu speichern. Erstellen wir ein Verzeichnis namens playbooks:

mkdir playbooks

Verschieben Sie nun das Playbook, das wir im letzten Schritt erstellt haben und das Webserver konfiguriert, in dieses neue Verzeichnis. Es ist auch eine gute Idee, es umzubenennen, um es aussagekräftiger zu machen:

mv playbook.yml playbooks/web_configure.yml

Da wir das Playbook jedoch in ein Unterverzeichnis verschoben haben, müssen wir die relativen Pfade zu den Task-Dateien aktualisieren. Die Task-Dateien befinden sich immer noch im Verzeichnis tasks/ relativ zum Hauptprojektverzeichnis, daher müssen wir die Pfade anpassen:

nano playbooks/web_configure.yml

Aktualisieren Sie die Pfade im Playbook, um ../tasks/ anstelle von tasks/ zu verwenden:

---
- name: Configure Web Servers
  hosts: webservers
  gather_facts: false
  tasks:
    - name: Import web server setup tasks
      import_tasks: ../tasks/web_setup.yml

    - name: Include verification tasks
      include_tasks: ../tasks/verify_config.yml

Speichern und beenden Sie den Editor.

Testen wir das korrigierte Playbook, um sicherzustellen, dass die Pfade korrekt funktionieren:

ansible-playbook playbooks/web_configure.yml -i inventory

Sie sollten sehen, wie das Playbook mit den korrigierten Pfaden erfolgreich ausgeführt wird.

Erstellen Sie als Nächstes ein neues, separates Playbook zur Konfiguration Ihrer Datenbankserver. Dieses Playbook zielt auf die Gruppe dbservers ab und installiert das Paket mariadb:

nano playbooks/db_setup.yml

Fügen Sie den folgenden Inhalt in die Datei ein. Dies ist ein vollständiges, eigenständiges Play:

---
- name: Configure Database Servers
  hosts: dbservers
  gather_facts: false
  tasks:
    - name: Install mariadb package
      ansible.builtin.dnf:
        name: mariadb
        state: present
      become: true

    - name: Display a confirmation message
      ansible.builtin.debug:
        msg: "Database server {{ inventory_hostname }} configured."

Speichern und beenden Sie den Editor. Jetzt haben Sie zwei Komponenten-Playbooks: eines für Webserver und eines für Datenbankserver.

Erstellen Sie schließlich ein übergeordnetes "Haupt"-Playbook. Diese Datei enthält keine Hosts oder Tasks selbst. Ihre einzige Aufgabe ist es, die anderen Playbooks in der richtigen Reihenfolge zu importieren, um den gesamten Workflow zu definieren:

nano main.yml

Fügen Sie den folgenden Inhalt hinzu. Dies erstellt einen Workflow, der zuerst die Webserver konfiguriert und dann die Datenbankserver konfiguriert:

---
- name: Import the web server configuration play
  import_playbook: playbooks/web_configure.yml

- name: Import the database server configuration play
  import_playbook: playbooks/db_setup.yml

Speichern und beenden Sie nano. Sie sind nun bereit, Ihren gesamten Workflow auszuführen, indem Sie das Playbook main.yml ausführen:

ansible-playbook main.yml -i inventory

Die Ausgabe zeigt die beiden separaten Plays, die nacheinander ausgeführt werden, und demonstriert, wie import_playbook effektiv einen größeren Workflow aus kleineren, überschaubaren Teilen zusammensetzt:

PLAY [Configure Web Servers] ***************************************************

TASK [Import web server setup tasks] *******************************************
imported: /home/labex/project/ansible_patterns/playbooks/../tasks/web_setup.yml

TASK [Install the httpd package] ***********************************************
ok: [web1.example.com]
ok: [web2.example.com]

TASK [Include verification tasks] **********************************************
included: /home/labex/project/ansible_patterns/playbooks/../tasks/verify_config.yml for web1.example.com, web2.example.com

TASK [Display a verification message] ******************************************
ok: [web1.example.com] => {
    "msg": "Configuration tasks applied to web1.example.com"
}
ok: [web2.example.com] => {
    "msg": "Configuration tasks applied to web2.example.com"
}

PLAY [Configure Database Servers] **********************************************

TASK [Install mariadb package] *************************************************
changed: [db1.lab.net]
changed: [db2.lab.net]

TASK [Display a confirmation message] ******************************************
ok: [db1.lab.net] => {
    "msg": "Database server db1.lab.net configured."
}
ok: [db2.lab.net] => {
    "msg": "Database server db2.lab.net configured."
}

PLAY RECAP *********************************************************************
db1.lab.net                : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
db2.lab.net                : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
web1.example.com           : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
web2.example.com           : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

Die Ausgabe zeigt deutlich zwei separate Plays, die nacheinander ausgeführt werden, und demonstriert, wie import_playbook effektiv einen größeren Workflow aus kleineren, überschaubaren Teilen zusammensetzt.

Ausführen und Verifizieren des vollständigen modularen Playbooks

In diesem letzten Schritt führen Sie den vollständigen, modularen Workflow aus, den Sie erstellt haben, und lernen vor allem, wie Sie überprüfen können, ob die Automatisierung den gewünschten Zustand auf den Zielsystemen erreicht hat. Ein erfolgreicher Playbook-Lauf ist gut, aber die Bestätigung des Ergebnisses ist für eine zuverlässige Automatisierung unerlässlich.

Stellen Sie zunächst sicher, dass Sie sich im Hauptprojektverzeichnis befinden:

cd ~/project/ansible_patterns

Bevor Sie das endgültige Playbook ausführen, visualisieren wir die vollständige Projektstruktur, die Sie erstellt haben. Der Befehl tree ist hierfür hervorragend geeignet. Wenn er nicht installiert ist, können Sie ihn mit dnf hinzufügen:

sudo dnf install -y tree
tree .

Sie sollten eine Struktur wie diese sehen:

.
├── inventory
├── main.yml
├── playbooks
│   ├── db_setup.yml
│   └── web_configure.yml
└── tasks
    ├── verify_config.yml
    └── web_setup.yml

2 directories, 6 files

Diese Struktur mit einem Haupteinstiegspunkt (main.yml), separaten Playbook-Dateien und wiederverwendbaren Task-Dateien ist eine skalierbare und wartbare Methode zur Verwaltung von Ansible-Projekten.

Führen Sie nun den gesamten Workflow aus, indem Sie Ihr übergeordnetes main.yml-Playbook ausführen:

ansible-playbook main.yml -i inventory

Nachdem das Playbook erfolgreich abgeschlossen wurde, ist der nächste entscheidende Schritt die Verifizierung. Sie müssen bestätigen, dass sich das System im beabsichtigten Zustand befindet. Unser Playbook wurde so konzipiert, dass es das Paket httpd auf Webservern und das Paket mariadb auf Datenbankservern installiert. Da alle Tasks in diesem Labor auf Ihrem lokalen Rechner ausgeführt werden, können wir deren Installation direkt mit dem Befehl rpm überprüfen.

Überprüfen Sie zunächst, ob das Paket httpd als Teil der Webserverkonfiguration installiert wurde:

rpm -q httpd

Sie sollten eine Ausgabe sehen, die die Installation des Pakets bestätigt:

httpd-2.4.xx-x.el9.x86_64

Überprüfen Sie als Nächstes die Installation des mariadb-Pakets aus der Datenbankserverkonfiguration:

rpm -q mariadb

Ebenso sollten Sie eine Bestätigung sehen, dass mariadb installiert ist:

mariadb-10.5.xx-x.el9.x86_64

Das Erscheinen der Paketnamen in der Ausgabe bestätigt, dass Ihr Ansible-Playbook das System wie beabsichtigt erfolgreich konfiguriert hat. Sie haben nun erfolgreich ein modulares Ansible-Projekt von Anfang bis Ende erstellt, ausgeführt und verifiziert.

Zusammenfassung

In diesem Lab haben Sie wesentliche Techniken zur Strukturierung komplexer Ansible-Playbooks unter RHEL gelernt. Sie begannen mit den Grundlagen der Host-Auswahl, indem Sie grundlegende Gruppennamen, Wildcards, Ausschlüsse und logische Operatoren verwendeten, um Knoten, die in einer Inventardatei definiert sind, präzise anzusprechen. Der Fokus verlagerte sich dann auf die Modularisierung, wo Sie übten, große Plays in besser handhabbare und wiederverwendbare Komponenten zu zerlegen, indem Sie sowohl include_tasks für die dynamische Einbindung als auch import_tasks für die statische Einbindung verwendeten.

Aufbauend auf diesen Fähigkeiten lernten Sie, einen vollständigen, mehrstufigen Workflow zu komponieren, indem Sie einzelne Playbooks mit import_playbook miteinander verknüpfen. Der praktische Prozess umfasste die Installation von Ansible, die Erstellung einer Projektstruktur und die schrittweise Refaktorierung eines einfachen Playbooks in eine ausgefeilte, mehrdateiliche Struktur. Das Lab gipfelte in der Ausführung des endgültigen zusammengesetzten Playbooks und der Überprüfung, ob der gesamte automatisierte Workflow erfolgreich gegen die korrekt angesprochenen Hosts lief, was einen organisierten und skalierbaren Ansatz für die Automatisierung demonstrierte.