36 Module

36.1 Einführung

Module sind die Grundbausteine von Ansible-Tasks. Ein Modul ist eine eigenständige Funktionseinheit, die eine spezifische Aufgabe auf dem Zielsystem ausführt.

36.1.1 Kernprinzipien von Modulen

Abstraktion: Module abstrahieren komplexe Systemoperationen in einfache, deklarative Anweisungen. Statt manuelle Befehle auszuführen, beschreibt man den gewünschten Zustand.

Idempotenz: Module können mehrfach ausgeführt werden, ohne unerwünschte Seiteneffekte zu verursachen. Ist der gewünschte Zustand bereits erreicht, ändern sie nichts.

JSON-Rückgabe: Alle Module geben strukturierte JSON-Daten zurück, die Informationen über Ausführung, Änderungen und Ergebnisse enthalten.

36.1.2 Modul-Typen

Built-in Module: Im Ansible-Core enthalten, immer verfügbar ohne zusätzliche Installation.

- name: Datei kopieren
  ansible.builtin.copy:
    src: config.txt
    dest: /etc/app/config.txt

Community Module: Über Collections verfügbar, müssen explizit installiert werden.

- name: Docker Container starten
  community.docker.docker_container:
    name: webserver
    image: nginx

36.2 Verwendung

36.2.1 Grundlegende Syntax

- name: Beschreibung der Aufgabe
  modul_name:
    parameter1: wert1
    parameter2: wert2

36.2.2 ansible.builtin.copy

Kopiert Dateien vom Control Node auf Managed Nodes.

- name: Konfigurationsdatei kopieren
  ansible.builtin.copy:
    src: /local/path/config.conf
    dest: /remote/path/config.conf
    owner: root
    group: root
    mode: '0644'
    backup: yes

Wichtige Parameter: - src: Quelldatei auf Control Node - dest: Zieldatei auf Managed Node - owner/group: Besitzer und Gruppe - mode: Dateiberechtigungen - backup: Backup vor Überschreibung erstellen

36.2.3 ansible.builtin.package

Installiert, aktualisiert oder entfernt Pakete distributionsunabhängig.

- name: Nginx installieren
  ansible.builtin.package:
    name: nginx
    state: present

- name: Mehrere Pakete installieren
  ansible.builtin.package:
    name:
      - vim
      - git
      - htop
    state: present

Parameter: - name: Paketname oder Liste von Paketnamen - state: present (installiert), absent (entfernt), latest (neueste Version)

36.2.4 ansible.builtin.service

Verwaltet Systemdienste.

- name: Nginx starten und aktivieren
  ansible.builtin.service:
    name: nginx
    state: started
    enabled: yes

- name: Service neustarten
  ansible.builtin.service:
    name: apache2
    state: restarted

Parameter: - name: Service-Name - state: started, stopped, restarted, reloaded - enabled: Service beim Boot aktivieren (yes/no)

36.2.5 Rückgabewerte verarbeiten

36.2.5.1 register

Speichert Modul-Rückgaben in einer Variable.

- name: Verzeichnis auflisten
  ansible.builtin.command:
    cmd: ls -la /var/log
  register: log_listing

- name: Ergebnis anzeigen
  ansible.builtin.debug:
    var: log_listing.stdout_lines

36.2.5.2 changed_when

Definiert, wann ein Task als “geändert” gilt.

- name: Script ausführen
  ansible.builtin.command:
    cmd: /usr/local/bin/check_status.sh
  register: status_check
  changed_when: "'UPDATED' in status_check.stdout"

36.2.5.3 failed_when

Definiert Fehlerbedingungen unabhängig vom Exit-Code.

- name: Anwendung prüfen
  ansible.builtin.uri:
    url: http://localhost:8080/health
  register: health_check
  failed_when: health_check.status != 200

36.2.6 Komplexes Beispiel

- name: Webserver installieren und konfigurieren
  ansible.builtin.package:
    name: nginx
    state: present
  register: nginx_install

- name: Konfiguration kopieren
  ansible.builtin.copy:
    src: nginx.conf
    dest: /etc/nginx/nginx.conf
    backup: yes
  register: config_copy

- name: Nginx neustarten bei Änderungen
  ansible.builtin.service:
    name: nginx
    state: restarted
    enabled: yes
  when: nginx_install.changed or config_copy.changed

36.3 Abgrenzung

36.3.1 Module vs. Plugins

Module führen Aktionen auf Managed Nodes aus: - Dateien kopieren, Pakete installieren, Services starten - Werden über Tasks aufgerufen - Geben JSON-Strukturen zurück

Plugins erweitern Ansible-Funktionalität auf dem Control Node: - Inventory-Plugins: Dynamische Inventories - Filter-Plugins: Datenmanipulation in Templates - Callback-Plugins: Ausgabe-Formatierung

36.3.2 Action vs. Lookup Plugins

Action Plugins: Führen Aktionen aus, oft als Wrapper um Module.

- name: Template verarbeiten
  ansible.builtin.template:
    src: config.j2
    dest: /etc/app/config

Lookup Plugins: Lesen Daten zur Laufzeit.

- name: Passwort aus Datei lesen
  ansible.builtin.debug:
    msg: "Password: {{ lookup('file', '/secure/password.txt') }}"

36.4 Best Practices

36.4.1 Module vor shell/command bevorzugen

Schlecht:

- name: Paket installieren
  ansible.builtin.shell: apt-get install -y nginx

Gut:

- name: Paket installieren
  ansible.builtin.package:
    name: nginx
    state: present

Vorteile: Idempotenz, bessere Fehlerbehandlung, distributionsunabhängig.

36.4.2 Idempotenz sicherstellen

- name: Verzeichnis erstellen
  ansible.builtin.file:
    path: /opt/application
    state: directory
    mode: '0755'
    owner: app
    group: app

Dieses Modul erkennt automatisch, ob das Verzeichnis bereits existiert und mit korrekten Berechtigungen versehen ist.

36.4.3 Collections verwenden

# requirements.yml
collections:
  - name: community.general
    version: ">=3.0.0"
  - name: ansible.posix
ansible-galaxy collection install -r requirements.yml

36.4.4 Aussagekräftige Task-Namen

# Schlecht
- copy:
    src: file.txt
    dest: /tmp/file.txt

# Gut
- name: Konfigurationsdatei für Monitoring-Agent kopieren
  ansible.builtin.copy:
    src: monitoring-config.yml
    dest: /etc/monitoring/config.yml

36.5 Übungen

36.5.1 Übung 1: Datei mit copy erstellen

Aufgabe: Erstelle eine Textdatei mit spezifischem Inhalt und Berechtigungen.

Lösung:

---
- hosts: localhost
  tasks:
    - name: Info-Datei erstellen
      ansible.builtin.copy:
        content: |
          System Information
          ==================
          Created by Ansible
          Timestamp: {{ ansible_date_time.iso8601 }}
        dest: /tmp/system-info.txt
        mode: '0644'
        owner: "{{ ansible_user_id }}"

    - name: Datei-Erstellung bestätigen
      ansible.builtin.file:
        path: /tmp/system-info.txt
        state: file
      register: file_stat

    - name: Ergebnis anzeigen
      ansible.builtin.debug:
        msg: "Datei erstellt: {{ file_stat.path }}"

Test: ansible-playbook datei-erstellen.yml

36.5.2 Übung 2: Paket installieren und Service starten

Aufgabe: Installiere einen Webserver und stelle sicher, dass er läuft.

Lösung:

---
- hosts: localhost
  become: yes
  tasks:
    - name: Apache installieren
      ansible.builtin.package:
        name: "{{ apache_package }}"
        state: present
      vars:
        apache_package: "{{ 'httpd' if ansible_os_family == 'RedHat' else 'apache2' }}"

    - name: Apache starten und aktivieren
      ansible.builtin.service:
        name: "{{ apache_service }}"
        state: started
        enabled: yes
      vars:
        apache_service: "{{ 'httpd' if ansible_os_family == 'RedHat' else 'apache2' }}"

    - name: Service-Status prüfen
      ansible.builtin.service_facts:

    - name: Status anzeigen
      ansible.builtin.debug:
        msg: "Apache läuft: {{ ansible_facts.services[apache_service].state == 'running' }}"
      vars:
        apache_service: "{{ 'httpd' if ansible_os_family == 'RedHat' else 'apache2' }}"

36.5.3 Übung 3: Rückgabe mit register auswerten

Aufgabe: Führe eine Systemprüfung durch und reagiere auf das Ergebnis.

Lösung:

---
- hosts: localhost
  tasks:
    - name: Festplattenspeicher prüfen
      ansible.builtin.shell:
        cmd: df -h / | tail -n1 | awk '{print $5}' | sed 's/%//'
      register: disk_usage
      changed_when: false

    - name: Speicherverbrauch ausgeben
      ansible.builtin.debug:
        msg: "Festplatte ist zu {{ disk_usage.stdout }}% voll"

    - name: Warnung bei hohem Speicherverbrauch
      ansible.builtin.debug:
        msg: "WARNUNG: Festplatte ist fast voll!"
      when: disk_usage.stdout | int > 80

    - name: Log-Dateien rotieren bei Platzmangel
      ansible.builtin.command:
        cmd: logrotate -f /etc/logrotate.conf
      when: disk_usage.stdout | int > 90
      become: yes

    - name: E-Mail bei kritischem Zustand
      ansible.builtin.mail:
        to: admin@example.com
        subject: "Festplatte fast voll auf {{ ansible_hostname }}"
        body: "Speicherverbrauch: {{ disk_usage.stdout }}%"
      when: disk_usage.stdout | int > 95

Erweiterte Variante mit Fehlerbehandlung:

    - name: Service-Status prüfen mit Timeout
      ansible.builtin.command:
        cmd: systemctl is-active nginx
      register: nginx_status
      failed_when: false
      timeout: 10

    - name: Service starten falls gestoppt
      ansible.builtin.service:
        name: nginx
        state: started
      when: nginx_status.rc != 0

    - name: Fehlschlag dokumentieren
      ansible.builtin.lineinfile:
        path: /var/log/ansible-checks.log
        line: "{{ ansible_date_time.iso8601 }} - Nginx was down, restarted"
        create: yes
      when: nginx_status.rc != 0