Ansible Rollen und Collections auf RHEL

AnsibleAnsibleBeginner
Jetzt üben

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

Einleitung

In diesem Labor lernen Sie, wie Sie die Konfiguration eines Red Hat Enterprise Linux (RHEL) Webservers automatisieren, indem Sie die Leistungsfähigkeit und Wiederverwendbarkeit von Ansible Roles und Collections nutzen. Sie werden einen umfassenden Automatisierungs-Workflow erstellen, indem Sie eine benutzerdefinierte Rolle zur Bereitstellung spezifischer Konfigurationen erstellen, eine externe Rolle aus einem Git-Repository als Abhängigkeit integrieren und eine vorgefertigte RHEL System Role aus einer Ansible Collection verwenden, um Systemdienste wie SELinux zu verwalten.

Der Prozess beginnt mit der Erstellung einer standardisierten Rollenstruktur mit ansible-galaxy init. Anschließend definieren und installieren Sie eine Rollenabhängigkeit aus einem Git-Repository mithilfe einer requirements.yml-Datei. Nach der Integration einer RHEL System Role fügen Sie alle drei Rollentypen – benutzerdefiniert, Git-basiert und Collection-basiert – zu einem einzigen Master-Playbook zusammen. Abschließend führen Sie das Playbook aus und überprüfen, ob der Apache-Webserver und die SELinux-Einstellungen korrekt auf dem Ziel-RHEL-Server angewendet wurden, was eine vollständige, modulare Automatisierungslösung demonstriert.

Erstellen einer benutzerdefinierten Ansible-Rolle mit ansible-galaxy init

In diesem Schritt beginnen Sie mit der Erstellung einer standardisierten Verzeichnisstruktur für eine neue Ansible-Rolle mithilfe des Befehls ansible-galaxy init. Ansible-Rollen sind ein grundlegendes Konzept für die Erstellung wiederverwendbarer und organisierter Automatisierungsinhalte. Sie ermöglichen es Ihnen, Tasks, Handler, Variablen und andere Komponenten zu einer in sich geschlossenen, portablen Einheit zu bündeln. Die Verwendung einer Standardstruktur ist eine Best Practice, die Ihre Automatisierung leichter verständlich, verwaltbar und teilbar macht.

Stellen Sie zunächst sicher, dass Sie sich im richtigen Arbeitsverzeichnis befinden. Alle Arbeiten für dieses Labor werden im Verzeichnis ~/project durchgeführt.

cd ~/project

Bevor Sie eine Rolle erstellen, müssen Sie sicherstellen, dass die Ansible-Befehlszeilentools installiert sind. Das Paket ansible-core stellt die wesentlichen Werkzeuge bereit, einschließlich ansible-galaxy.

Installieren Sie ansible-core mit dem Paketmanager dnf. Das Flag -y beantwortet automatisch alle Bestätigungsaufforderungen mit "yes".

sudo dnf install -y ansible-core

Sie sollten eine Ausgabe sehen, die anzeigt, dass das Paket installiert wird und Abhängigkeiten aufgelöst werden.

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

Es ist üblich, alle Projektrollen in einem dedizierten roles-Verzeichnis zu organisieren. Erstellen Sie dieses Verzeichnis jetzt.

mkdir roles

Navigieren Sie nun in das neu erstellte Verzeichnis roles. Hier initialisieren Sie Ihre neue benutzerdefinierte Rolle.

cd roles

Sie verwenden nun den Befehl ansible-galaxy init, um ein Gerüst für eine Rolle namens apache.developer_configs zu erstellen. Dieser Befehl generiert automatisch eine Reihe von Standardverzeichnissen und Dateien und bietet einen sauberen Ausgangspunkt für Ihre Rollenentwicklung.

ansible-galaxy init apache.developer_configs

Nachdem Sie den Befehl ausgeführt haben, sehen Sie eine Bestätigungsmeldung.

- Role apache.developer_configs was created successfully

Um die gerade erstellte Struktur anzuzeigen, können Sie den Befehl ls -R verwenden, der den Inhalt eines Verzeichnisses und all seiner Unterverzeichnisse rekursiv auflistet.

ls -R apache.developer_configs

Die Ausgabe zeigt die Standardverzeichnisstruktur für eine Ansible-Rolle:

apache.developer_configs:
defaults  files  handlers  meta  README.md  tasks  templates  tests  vars

apache.developer_configs/defaults:
main.yml

apache.developer_configs/files:

apache.developer_configs/handlers:
main.yml

apache.developer_configs/meta:
main.yml

apache.developer_configs/tasks:
main.yml

apache.developer_configs/templates:

apache.developer_configs/tests:
inventory  test.yml

apache.developer_configs/vars:
main.yml

Hier ist eine kurze Übersicht über die wichtigsten Verzeichnisse:

  • tasks: Enthält die Hauptliste der Tasks, die von der Rolle ausgeführt werden sollen.
  • handlers: Enthält Handler, das sind Tasks, die nur ausgeführt werden, wenn sie von einem anderen Task benachrichtigt werden.
  • vars: Enthält Variablen für die Rolle.
  • templates: Enthält Dateivorlagen, die die Jinja2-Templating-Engine verwenden.
  • meta: Enthält Metadaten für die Rolle, einschließlich Abhängigkeiten von anderen Rollen.

Sie haben nun erfolgreich die grundlegende Struktur für Ihre benutzerdefinierte Ansible-Rolle erstellt. In den nächsten Schritten werden Sie diese Verzeichnisse mit Inhalten füllen, um einen Webserver zu konfigurieren.

Installieren einer Rollenabhängigkeit aus einem Git-Repository mit requirements.yml

In diesem Schritt lernen Sie, wie Sie Rollenabhängigkeiten aus externen Quellen, wie z. B. einem Git-Repository, verwalten. Dies ist eine gängige Praxis in größeren Ansible-Projekten, bei denen Sie Rollen wiederverwenden, die von der Community oder anderen Teams entwickelt wurden. Ansible verwendet eine Datei, die typischerweise requirements.yml genannt wird, um eine Liste der zu installierenden Rollen zu definieren.

Ihre benutzerdefinierte Rolle, apache.developer_configs, wird von einer grundlegenden Apache-Rolle abhängen, um sicherzustellen, dass der Webserver installiert und ausgeführt wird. Sie werden diese Abhängigkeit definieren und installieren.

Stellen Sie zunächst sicher, dass Sie sich im Hauptprojektverzeichnis befinden. Wenn Sie sich noch im Unterverzeichnis roles aus dem vorherigen Schritt befinden, navigieren Sie zurück zu ~/project.

cd ~/project

Erstellen Sie nun die Datei requirements.yml in Ihrem roles-Verzeichnis. Diese Datei listet alle externen Rollen auf, die Ihr Projekt benötigt. Verwenden Sie den nano-Editor, um die Datei zu erstellen und zu bearbeiten.

nano roles/requirements.yml

Fügen Sie den folgenden Inhalt in die Datei ein. Dieser Eintrag weist ansible-galaxy an, eine bestimmte Version einer Apache-Rolle aus einem öffentlichen Git-Repository herunterzuladen und sie lokal als infra.apache zu bezeichnen.

- name: infra.apache
  src: https://github.com/geerlingguy/ansible-role-apache.git
  scm: git
  version: 3.2.0

Lassen Sie uns diese Definition aufschlüsseln:

  • name: Dies ist der lokale Name für die Rolle. Auch wenn das Quell-Repository einen anderen Namen hat, wird es in ein Verzeichnis namens infra.apache installiert.
  • src: Die Quell-URL des Git-Repositorys.
  • scm: Gibt das Quellcodeverwaltungs-Tool an, in diesem Fall git.
  • version: Der spezifische Git-Branch, Tag oder Commit-Hash, der verwendet werden soll. Das Festlegen einer Version ist entscheidend, um sicherzustellen, dass Ihre Automatisierung stabil und vorhersehbar ist.

Speichern Sie die Datei und beenden Sie nano, indem Sie Ctrl+X, dann Y und schließlich Enter drücken.

Nachdem die Datei requirements.yml vorhanden ist, können Sie nun den Befehl ansible-galaxy install verwenden, um die Rolle herunterzuladen und zu installieren.

  • Das Flag -r verweist auf Ihre Requirements-Datei.
  • Das Flag -p gibt den Pfad an, in dem die Rollen installiert werden sollen.
ansible-galaxy install -r roles/requirements.yml -p roles

Sie sehen eine Ausgabe, die den Download- und Installationsprozess bestätigt.

Starting galaxy role install process
- downloading role 'ansible-role-apache', owned by geerlingguy
- downloading role from https://github.com/geerlingguy/ansible-role-apache/archive/3.2.0.tar.gz
- extracting infra.apache to /home/labex/project/roles/infra.apache
- infra.apache (3.2.0) was installed successfully

Um zu bestätigen, dass die Rolle korrekt installiert wurde, listen Sie den Inhalt des Verzeichnisses roles auf.

ls -l roles

Sie sollten nun das Verzeichnis infra.apache neben der Rolle apache.developer_configs sehen, die Sie zuvor erstellt haben.

total 12
drwxr-xr-x. 9 labex labex 4096 Nov 10 10:10 apache.developer_configs
drwxr-xr-x. 9 labex labex 4096 Nov 10 10:15 infra.apache
-rw-r--r--. 1 labex labex  118 Nov 10 10:12 requirements.yml

Sie haben nun erfolgreich ein externes Git-Repository als Abhängigkeit deklariert und es in Ihr Projekt installiert. Der nächste Schritt ist die Integration dieser Abhängigkeit in die Metadaten Ihrer benutzerdefinierten Rolle.

Integrieren einer RHEL System Role aus einer Ansible Collection

In diesem Schritt arbeiten Sie mit Ansible Collections, dem Standardweg zur Verteilung von Ansible-Inhalten, einschließlich Rollen, Modulen und Plugins. Sie installieren die Community General Collection, die eine Reihe nützlicher Module für die Automatisierung gängiger Verwaltungsaufgaben, einschließlich der SELinux-Verwaltung, bereitstellt.

Für unser Webserver-Szenario müssen wir SELinux korrekt konfigurieren, damit der Apache-Dienst auf nicht standardmäßigen Ports lauschen kann. Die Sammlung community.general enthält SELinux-Module, die sich perfekt für diese Aufgabe eignen.

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

cd ~/project

Es ist eine Best Practice, Collections innerhalb des Projektverzeichnisses zu installieren, um Ihr Projekt in sich geschlossen zu halten. Erstellen Sie ein Verzeichnis namens collections, um sie zu speichern.

mkdir collections

Verwenden Sie nun den Befehl ansible-galaxy collection install, um die erforderlichen Collections zu installieren. Das Flag -p weist den Befehl an, die Collections in das gerade erstellte Verzeichnis collections zu installieren.

ansible-galaxy collection install community.general ansible.posix -p collections

Der Befehl lädt die Collections und ihre Abhängigkeiten herunter. Sie sehen eine Ausgabe, die der folgenden ähnelt:

Starting galaxy collection install process
Process install dependency map
Starting collection install process
Installing 'community.general:11.0.0' to '/home/labex/project/collections/ansible_collections/community/general'
Installing 'ansible.posix:2.0.0' to '/home/labex/project/collections/ansible_collections/ansible/posix'
...
community.general:11.0.0 was installed successfully
ansible.posix:2.0.0 was installed successfully

Um zu überprüfen, ob die Collection nun für Ihr Projekt verfügbar ist, können Sie alle installierten Collections auflisten, indem Sie den Collections-Pfad angeben.

ansible-galaxy collection list -p collections

Die Ausgabe zeigt die installierten Collections und ihre Installationspfade innerhalb Ihres Projekts.

## /home/labex/project/collections/ansible_collections
Collection              Version
----------------------- -------
ansible.posix           2.0.0
community.general       11.0.0

Wenn Sie ein Modul aus einer Collection in einem Playbook verwenden, müssen Sie es mit seinem Fully Qualified Collection Name (FQCN) referenzieren. Für die SELinux-Verwaltung verwenden Sie ansible.posix.selinux für die Verwaltung des SELinux-Status und community.general.seport für die Verwaltung von SELinux-Ports.

Sie haben nun erfolgreich leistungsstarke Collections installiert, die SELinux-Verwaltungsmodule enthalten. Im nächsten Schritt stellen Sie ein Playbook zusammen, das Ihre benutzerdefinierte Rolle, die Rolle aus Git und SELinux-Module aus diesen Collections verwendet, um den Entwicklungsserver vollständig zu konfigurieren.

Zusammenstellen und Ausführen eines Playbooks mit benutzerdefinierten Rollen, Git und Systemrollen

In diesem Schritt bringen Sie alle vorbereiteten Komponenten zusammen: Ihre benutzerdefinierte Rolle, die Abhängigkeit von Git und die RHEL System Role. Sie erstellen ein Haupt-Playbook, das diese Rollen orchestriert, um den Entwicklungsserver vollständig zu konfigurieren.

Betrachten Sie diesen Schritt als das Zusammenfügen einer komplexen Maschine aus verschiedenen Teilen – jede Rolle dient einem bestimmten Zweck, und sie arbeiten zusammen, um eine vollständige Webserver-Umgebung zu schaffen. Lassen Sie uns dies in überschaubare Abschnitte aufteilen:

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

cd ~/project

Bevor wir uns mit der Konfiguration befassen, lassen Sie uns verstehen, was wir erstellen:

  • Ansible-Konfiguration: Legt fest, wie sich Ansible verhält und wo es Dateien findet
  • Inventory: Definiert, welche Server verwaltet werden sollen (in unserem Fall localhost)
  • Variablen: Speichern Daten, die unsere Rollen verwenden werden (Entwicklerinformationen, SELinux-Einstellungen)
  • Benutzerdefinierter Rolleninhalt: Die eigentlichen Tasks, die Entwicklungsumgebungen konfigurieren
  • Haupt-Playbook: Der Orchestrator, der alles in der richtigen Reihenfolge ausführt

1. Erstellen der Ansible-Konfiguration und des Inventars

Die Datei ansible.cfg ist wie eine Konfigurationsdatei, die Ansible mitteilt, wie es sich verhalten soll. Ohne sie müssten Sie Pfade und Optionen in jedem Befehl angeben. Mit ihr weiß Ansible automatisch, wo es Ihre Rollen, Collections und Ihr Inventar findet.

Erstellen Sie die Datei ansible.cfg mit nano. Diese Datei teilt Ansible mit, wo es Ihre Rollen, Collections und Ihr Inventar finden kann.

nano ansible.cfg

Fügen Sie den folgenden Inhalt hinzu. Lassen Sie uns jede Zeile verstehen:

[defaults]
inventory = inventory                 ## Weist Ansible an, eine Datei namens 'inventory' zu verwenden
roles_path = roles                   ## Suche nach Rollen im Verzeichnis 'roles'
collections_paths = collections      ## Suche nach Collections im Verzeichnis 'collections'
host_key_checking = False           ## Überspringe SSH-Schlüsselüberprüfung (nützlich für Laborumgebungen)

[privilege_escalation]
become = True                       ## Verwende automatisch sudo für Tasks, die es benötigen

Was jede Einstellung bewirkt:

  • inventory = inventory: Anstatt jedes Mal -i inventory einzugeben, verwendet Ansible automatisch diese Datei
  • roles_path = roles: Ansible sucht nach Rollen im Verzeichnis roles
  • collections_paths = collections: Ansible findet hier Ihre installierten Collections
  • host_key_checking = False: Verhindert SSH-Schlüsselüberprüfungsfehler in Laborumgebungen
  • become = True: Führt Tasks bei Bedarf automatisch mit erhöhten Rechten aus

Speichern und beenden Sie nano (Drücken Sie Ctrl+X, dann Y, dann Enter).

Die Inventardatei teilt Ansible mit, welche Maschinen verwaltet werden sollen. In unserem Fall konfigurieren wir die lokale Maschine.

nano inventory

Fügen Sie die folgende Zeile hinzu:

localhost ansible_connection=local

Was das bedeutet:

  • localhost: Der Name unseres Zielhosts
  • ansible_connection=local: Anstatt SSH wird eine lokale Verbindung verwendet (da wir dieselbe Maschine verwalten, auf der wir Ansible ausführen)

Speichern und beenden Sie nano.

2. Definieren von Rollenvariablen

Variablen in Ansible sind wie Einstellungen, die Ihre Rollen verwenden können. Anstatt Werte wie Benutzernamen oder Portnummern direkt in Ihre Tasks zu schreiben, definieren Sie diese in Variablendateien. Dies macht Ihre Automatisierung flexibel und wiederverwendbar.

Das Verzeichnis group_vars/all ist ein spezieller Speicherort, an dem Ansible automatisch Variablen für alle Hosts lädt. Jede YAML-Datei in diesem Verzeichnis wird für Ihre Playbooks und Rollen verfügbar.

Erstellen Sie die Verzeichnisstruktur für Variablen, die für alle Hosts gelten:

mkdir -p group_vars/all

Erstellen Sie nun eine Datei, um die Entwicklerinformationen zu definieren. Diese Daten werden von Ihrer benutzerdefinierten Rolle verwendet, um Benutzerkonten und Webkonfigurationen zu erstellen.

nano group_vars/all/developers.yml

Fügen Sie den folgenden Inhalt hinzu:

---
web_developers:
  - username: jdoe ## Erster Entwickler
    port: 9081 ## Benutzerdefinierter Port für die Website dieses Entwicklers
  - username: jdoe2 ## Zweiter Entwickler
    port: 9082 ## Benutzerdefinierter Port für die Website dieses Entwicklers

Was diese Datenstruktur bedeutet:

  • web_developers: Eine Liste, die Entwicklerinformationen enthält
  • Jeder Entwickler hat einen username und einen port
  • Ihre benutzerdefinierte Rolle durchläuft diese Liste, um Konfigurationen für jeden Entwickler zu erstellen

Speichern und beenden.

Erstellen Sie als Nächstes eine Variablendatei für die SELinux-Konfiguration. SELinux (Security-Enhanced Linux) ist ein Sicherheitsmodul, das steuert, was Anwendungen tun können.

nano group_vars/all/selinux.yml

Fügen Sie den folgenden Inhalt hinzu:

---
selinux_state: enforcing ## Setzt SELinux in den enforcing-Modus (höchste Sicherheit)
selinux_ports: ## Liste der Ports, die Apache verwenden darf
  - ports: "9081" ## Port 9081 zulassen
    proto: "tcp" ## Protokoll: TCP
    setype: "http_port_t" ## SELinux-Typ: HTTP-Port
    state: "present" ## Diese Regel hinzufügen
  - ports: "9082" ## Port 9082 zulassen
    proto: "tcp" ## Protokoll: TCP
    setype: "http_port_t" ## SELinux-Typ: HTTP-Port
    state: "present" ## Diese Regel hinzufügen

Verständnis der SELinux-Einstellungen:

  • selinux_state: enforcing: SELinux blockiert aktiv unbefugte Aktionen
  • selinux_ports: Eine Liste von Portkonfigurationen
  • http_port_t: Der SELinux-Typ, der es Apache erlaubt, sich an Ports zu binden
  • Standardmäßig kann Apache nur die Ports 80 und 443 verwenden; wir müssen 9081 und 9082 explizit zulassen

Speichern und beenden.

3. Befüllen der benutzerdefinierten Rolle

Ihre Rolle apache.developer_configs hat derzeit die Verzeichnisstruktur, aber keinen tatsächlichen Inhalt. Wir müssen hinzufügen:

  • Templates: Dateien, die Variablen enthalten können (mit Jinja2-Syntax)
  • Tasks: Die eigentliche Arbeit, die Ansible ausführen wird
  • Handlers: Spezielle Tasks, die nur bei Benachrichtigung ausgeführt werden (z. B. Dienste neu starten)
  • Metadaten: Informationen über Rollenabhängigkeiten

Templates ermöglichen es Ihnen, Konfigurationsdateien zu erstellen, die sich basierend auf Ihren Variablen anpassen. Die Erweiterung .j2 zeigt an, dass es sich um eine Jinja2-Vorlage handelt.

nano roles/apache.developer_configs/templates/developer.conf.j2

Fügen Sie den folgenden Inhalt hinzu:

{% for dev in web_developers %}
Listen {{ dev.port }}
<VirtualHost *:{{ dev.port }}>
    ServerAdmin webmaster@localhost
    DocumentRoot /var/www/{{ dev.username }}

    <Directory /var/www/{{ dev.username }}>
        Options Indexes FollowSymLinks
        AllowOverride None
        Require all granted
    </Directory>
</VirtualHost>
{% endfor %}

Verständnis der Template-Syntax:

  • {% for dev in web_developers %}: Startet eine Schleife durch die Entwicklerliste
  • {{ dev.port }}: Fügt die Portnummer für diesen Entwickler ein
  • {{ dev.username }}: Fügt den Benutzernamen für diesen Entwickler ein
  • {% endfor %}: Beendet die Schleife
  • Das Ergebnis sind separate VirtualHost-Konfigurationen für jeden Entwickler

Was dies erstellt: Für unsere beiden Entwickler generiert diese Vorlage eine Apache-Konfiguration, die:

  1. Apache auf den Ports 9081 und 9082 lauschen lässt
  2. Virtual Hosts erstellt, die Inhalte von /var/www/jdoe und /var/www/jdoe2 bedienen
  3. Angemessene Berechtigungen für jedes Verzeichnis festlegt

Speichern und beenden.

Tasks sind die eigentliche Arbeit, die Ansible ausführt. Jeder Task verwendet ein Ansible-Modul, um etwas Bestimmtes zu erreichen.

nano roles/apache.developer_configs/tasks/main.yml

Fügen Sie den folgenden Inhalt hinzu und lassen Sie uns jeden Task verstehen:

---
## Task 1: Erstellen von Benutzerkonten für jeden Entwickler
- name: Create developer user accounts
  ansible.builtin.user: ## Verwendet das 'user'-Modul
    name: "{{ item.username }}" ## Erstellt Benutzer mit diesem Namen
    state: present ## Stellt sicher, dass der Benutzer existiert
  loop: "{{ web_developers }}" ## Führt dies für jeden Entwickler in der Liste aus

## Task 2: Erstellen von Webverzeichnissen für jeden Entwickler
- name: Create developer web root directories
  ansible.builtin.file: ## Verwendet das 'file'-Modul
    path: "/var/www/{{ item.username }}" ## Erstellt dieses Verzeichnis
    state: directory ## Stellt sicher, dass es ein Verzeichnis ist
    owner: "{{ item.username }}" ## Setzt den Besitzer
    group: "{{ item.username }}" ## Setzt die Gruppe
    mode: "0755" ## Setzt Berechtigungen (rwxr-xr-x)
  loop: "{{ web_developers }}"

## Task 3: Erstellen einer Beispielwebseite für jeden Entwickler
- name: Create a sample index.html for each developer
  ansible.builtin.copy: ## Verwendet das 'copy'-Modul
    content: "Welcome to {{ item.username }}'s dev space\n" ## Dateiinhalt
    dest: "/var/www/{{ item.username }}/index.html" ## Wo die Datei abgelegt werden soll
    owner: "{{ item.username }}" ## Dateibesitzer
    group: "{{ item.username }}" ## Dateigruppe
    mode: "0644" ## Dateiberechtigungen (rw-r--r--)
  loop: "{{ web_developers }}"

## Task 4: Bereitstellen der Apache-Konfigurationsdatei
- name: Deploy developer apache configs
  ansible.builtin.template: ## Verwendet das 'template'-Modul
    src: developer.conf.j2 ## Quelldatei der Vorlage
    dest: /etc/httpd/conf.d/developer.conf ## Ziel auf dem Server
    mode: "0644" ## Dateiberechtigungen
  notify: restart apache ## Löst den restart-Handler aus, wenn dies geändert wird

Verständnis wichtiger Konzepte:

  • loop: Wiederholt den Task für jedes Element in der Liste
  • {{ item.username }}: Bezieht sich auf den Benutzernamen des aktuellen Elements in der Schleife
  • notify: restart apache: Wenn dieser Task Änderungen vornimmt, löst er einen Handler namens "restart apache" aus
  • Dateiberechtigungen: 0755 bedeutet, dass der Besitzer lesen/schreiben/ausführen kann, andere lesen/ausführen können; 0644 bedeutet, dass der Besitzer lesen/schreiben kann, andere nur lesen können

Speichern und beenden.

Handler sind spezielle Tasks, die nur ausgeführt werden, wenn sie von anderen Tasks benachrichtigt werden. Sie werden typischerweise für Aktionen wie das Neustarten von Diensten verwendet.

nano roles/apache.developer_configs/handlers/main.yml

Fügen Sie den folgenden Inhalt hinzu:

---
- name: restart apache ## Dieser Name muss mit der 'notify:'-Anweisung übereinstimmen
  ansible.builtin.service: ## Verwendet das 'service'-Modul
    name: httpd ## Der Dienstname (Apache heißt auf RHEL 'httpd')
    state: restarted ## Startet den Dienst neu

Warum Handler verwenden?

  • Effizienz: Der Dienst wird nur neu gestartet, wenn sich die Konfiguration tatsächlich geändert hat
  • Reihenfolge: Alle Tasks werden zuerst ausgeführt, dann alle Handler am Ende
  • Idempotenz: Mehrere Tasks können denselben Handler benachrichtigen, aber er wird nur einmal ausgeführt

Speichern und beenden.

Schließlich müssen wir Ansible mitteilen, dass unsere benutzerdefinierte Rolle von der zuvor installierten Rolle infra.apache abhängt.

nano roles/apache.developer_configs/meta/main.yml

Ersetzen Sie den Inhalt der Datei durch:

---
dependencies:
  - role: infra.apache ## Diese Rolle muss vor unserer benutzerdefinierten Rolle ausgeführt werden

Was dies bewirkt:

  • Wenn Ansible apache.developer_configs ausführt, wird automatisch zuerst infra.apache ausgeführt
  • Dies stellt sicher, dass Apache installiert ist und konfiguriert wird, bevor wir unsere benutzerdefinierten Konfigurationen hinzufügen
  • Abhängigkeiten werden in der Reihenfolge ausgeführt, in der sie aufgelistet sind

Speichern und beenden.

4. Zusammenstellen und Ausführen des Haupt-Playbooks

Ein Playbook ist wie ein Rezept, das Ansible sagt, was es tun soll und in welcher Reihenfolge. Unser Playbook wird:

  1. SELinux-Einstellungen konfigurieren (pre_tasks)
  2. Unsere Rollen ausführen (einschließlich der Abhängigkeitskette)

Erstellen Sie die Haupt-Playbook-Datei:

nano web_dev_server.yml

Fügen Sie den folgenden Inhalt mit detaillierten Erklärungen hinzu:

---
- name: Configure Dev Web Server ## Name des Playbooks
  hosts: localhost ## Ausführen auf localhost
  pre_tasks: ## Tasks, die vor den Rollen ausgeführt werden
    ## Task 1: SELinux-Modus konfigurieren
    - name: Set SELinux to enforcing mode
      ansible.posix.selinux: ## Modul aus der Collection ansible.posix
        policy: targeted ## Verwendet die SELinux-Richtlinie 'targeted'
        state: "{{ selinux_state }}" ## Verwendet die von uns definierte Variable
      when: selinux_state is defined ## Nur ausführen, wenn die Variable definiert ist

    ## Task 2: SELinux-Ports konfigurieren
    - name: Configure SELinux ports for Apache
      community.general.seport: ## Modul aus der Collection community.general
        ports: "{{ item.ports }}" ## Portnummer
        proto: "{{ item.proto }}" ## Protokoll (tcp)
        setype: "{{ item.setype }}" ## SELinux-Typ (http_port_t)
        state: "{{ item.state }}" ## present oder absent
      loop: "{{ selinux_ports }}" ## Schleife durch unsere Portliste
      when: selinux_ports is defined ## Nur ausführen, wenn die Variable definiert ist

  roles: ## Auszuführende Rollen
    - apache.developer_configs ## Unsere benutzerdefinierte Rolle (die infra.apache auslöst)

Verständnis der Ausführungsreihenfolge:

  1. pre_tasks: Die SELinux-Konfiguration wird zuerst ausgeführt
  2. roles: Zuerst werden die Rollenabhängigkeiten ausgeführt (infra.apache), dann unsere benutzerdefinierte Rolle
  3. handlers: Alle benachrichtigten Handler werden zuletzt ausgeführt

Warum diese Reihenfolge wichtig ist:

  • SELinux muss konfiguriert sein, bevor Apache versucht, sich an benutzerdefinierte Ports zu binden
  • Apache muss installiert sein, bevor wir Virtual Hosts konfigurieren können
  • Dienstneustarts erfolgen, nachdem alle Konfigurationen abgeschlossen sind

Speichern und beenden.

Jetzt sind Sie bereit, Ihre vollständige Automatisierung auszuführen:

ansible-playbook web_dev_server.yml

Das Playbook wird ausgeführt und Sie sehen eine detaillierte Ausgabe. Hier ist, was Sie erwarten können:

PLAY [Configure Dev Web Server] *************************************************

TASK [Gathering Facts] **********************************************************
ok: [localhost]                     ## Ansible sammelt Systeminformationen

TASK [Set SELinux to enforcing mode] *******************************************
changed: [localhost]                ## SELinux-Modus wurde geändert

TASK [Configure SELinux ports for Apache] **************************************
changed: [localhost] => (item={'ports': '9081', 'proto': 'tcp', 'setype': 'http_port_t', 'state': 'present'})
changed: [localhost] => (item={'ports': '9082', 'proto': 'tcp', 'setype': 'http_port_t', 'state': 'present'})

TASK [infra.apache : Ensure Apache is installed.] *******************************
changed: [localhost]                ## Apache-Paket wurde installiert

TASK [apache.developer_configs : Create developer user accounts] ****************
changed: [localhost] => (item={'username': 'jdoe', 'port': 9081})
changed: [localhost] => (item={'username': 'jdoe2', 'port': 9082})

TASK [apache.developer_configs : Create developer web root directories] *********
changed: [localhost] => (item={'username': 'jdoe', 'port': 9081})
changed: [localhost] => (item={'username': 'jdoe2', 'port': 9082})

TASK [apache.developer_configs : Create a sample index.html for each developer] *
changed: [localhost] => (item={'username': 'jdoe', 'port': 9081})
changed: [localhost] => (item={'username': 'jdoe2', 'port': 9082})

TASK [apache.developer_configs : Deploy developer apache configs] ***************
changed: [localhost]                ## Konfigurationsdatei wurde erstellt

RUNNING HANDLER [apache.developer_configs : restart apache] *********************
changed: [localhost]                ## Apache wurde neu gestartet

PLAY RECAP **********************************************************************
localhost                  : ok=17   changed=12   unreachable=0    failed=0    skipped=3    rescued=0    ignored=0

Sie haben erfolgreich ein komplexes Playbook zusammengestellt und ausgeführt, das mehrere Rollen aus verschiedenen Quellen kombiniert, um eine vollständige Webentwicklungs-Umgebung zu erstellen!

Überprüfung der SELinux- und Apache-Konfiguration auf dem RHEL-Server

In diesem letzten Schritt überprüfen Sie, ob Ihre Ansible-Automatisierung das System korrekt konfiguriert hat. Es ist entscheidend zu bestätigen, dass die Dienste wie erwartet laufen und die Sicherheitsrichtlinien (SELinux) korrekt angewendet wurden. Sie verwenden Standard-RHEL-Befehlszeilentools, um den Zustand des Systems zu überprüfen.

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

cd ~/project

1. Überprüfung der SELinux-Konfiguration

Die SELinux-Module aus den Collections hatten die Aufgabe, den SELinux-Modus auf enforcing zu setzen und neue Ports für den Typ http_port_t zuzulassen.

Überprüfen Sie den aktuellen SELinux-Status mit dem Befehl sestatus.

sestatus

Die Ausgabe sollte anzeigen, dass SELinux aktiviert und im enforcing-Modus ist.

SELinux status:                 enabled
SELinuxfs mount:                /sys/fs/selinux
SELinux root directory:         /etc/selinux
Loaded policy name:             targeted
Current mode:                   enforcing
Mode from config file:          enforcing
Policy MLS status:              enabled
Policy deny_unknown status:     allowed
Memory protection checking:     actual (secure)
Max kernel policy version:      33

Verwenden Sie als Nächstes den Befehl semanage port, um zu überprüfen, ob die Ports 9081 und 9082 zum Kontext http_port_t hinzugefügt wurden. Sie können die Ausgabe an grep weiterleiten, um die relevanten Zeilen zu finden.

sudo semanage port -l | grep http_port_t

Sie sollten Ihre benutzerdefinierten Ports in der Liste der Standard-HTTP-Ports sehen. Die genaue Ausgabe kann variieren, aber sie wird die von Ihnen definierten Ports enthalten.

http_port_t                    tcp      9082, 9081, 80, 81, 443, 488, 8008, 8009, 8443, 9000
pegasus_http_port_t            tcp      5988

Dies bestätigt, dass die SELinux-Module die Richtlinie erfolgreich aktualisiert haben.

2. Überprüfung des Apache-Dienstes und der Konfiguration

Die Rolle infra.apache hat den Dienst httpd installiert und gestartet. Da systemctl in dieser Container-Umgebung nicht verfügbar ist, können Sie den laufenden Prozess mit ps überprüfen.

ps aux | grep httpd

Sie sollten mehrere laufende httpd-Prozesse sehen, was darauf hindeutet, dass der Dienst aktiv ist.

root        8851  0.2  0.4  25652 16228 ?        Ss   09:31   0:00 /usr/sbin/httpd -DFOREGROUND
apache      8852  0.0  0.1  25308  6044 ?        S    09:31   0:00 /usr/sbin/httpd -DFOREGROUND
apache      8853  0.0  0.3 1443348 11364 ?       Sl   09:31   0:00 /usr/sbin/httpd -DFOREGROUND
apache      8854  0.0  0.3 1443348 11480 ?       Sl   09:31   0:00 /usr/sbin/httpd -DFOREGROUND
apache      8855  0.0  0.4 1574484 15848 ?       Sl   09:31   0:00 /usr/sbin/httpd -DFOREGROUND
labex       9298  0.0  0.0   6408  2176 pts/3    S+   09:31   0:00 grep --color=auto httpd

3. Überprüfung der Zugänglichkeit von Webinhalten

Der wichtigste Test ist schließlich, ob die Entwickler-Websites zugänglich sind. Ihre Rolle apache.developer_configs hat virtuelle Hosts auf den Ports 9081 und 9082 eingerichtet. Verwenden Sie den Befehl curl, um die Inhalte von jedem Endpunkt abzurufen.

Testen Sie zuerst die Website für den Benutzer jdoe auf Port 9081.

curl http://localhost:9081

Die erwartete Ausgabe ist der Inhalt der index.html-Datei, die Sie für diesen Benutzer erstellt haben.

Welcome to jdoe's dev space

Testen Sie als Nächstes die Website für den Benutzer jdoe2 auf Port 9082.

curl http://localhost:9082

Sie sollten die entsprechende Willkommensnachricht sehen.

Welcome to jdoe2's dev space

Diese erfolgreichen curl-Befehle bestätigen, dass Apache korrekt konfiguriert ist, die virtuellen Hosts funktionieren und die SELinux-Richtlinie den Datenverkehr auf den benutzerdefinierten Ports zulässt.

Herzlichen Glückwunsch! Sie haben erfolgreich ein vollständiges Ansible-Automatisierungsprojekt erstellt, das eine benutzerdefinierte Rolle, eine Rolle aus einem Git-Repository und SELinux-Module aus Ansible-Collections kombiniert, um einen sicheren, mandantenfähigen Webentwicklungs-Server zu konfigurieren.

Zusammenfassung

In diesem Labor lernen Sie, wie Sie die Konfiguration eines RHEL-Webservers automatisieren, indem Sie die Leistungsfähigkeit und Struktur von Ansible Roles und Collections nutzen. Sie beginnen mit der Erstellung einer benutzerdefinierten Rolle von Grund auf mit dem Befehl ansible-galaxy init, der eine standardisierte Verzeichnisstruktur für wiederverwendbare Automatisierungsinhalte erstellt. Dieser grundlegende Schritt bereitet die Bühne für komplexere Automatisierungsaufgaben.

Aufbauend auf der benutzerdefinierten Rolle integrieren Sie dann externe Abhängigkeiten, einschließlich einer Rolle aus einem Git-Repository über eine requirements.yml-Datei und einer offiziellen RHEL System Role aus einer Ansible Collection. Schließlich fassen Sie diese verschiedenen Rollentypen – benutzerdefiniert, Git-basiert und System – in einem einzigen Playbook zusammen, führen es zur Konfiguration des Servers aus und überprüfen die resultierenden Apache- und SELinux-Einstellungen, um den Erfolg der Automatisierung zu bestätigen.