9 Arbeitsweise von Ansible

9.1 Deklarativer Ansatz mit imperativer Struktur

Ansible verwendet einen hybrid deklarativ-imperativen Ansatz für das Konfigurationsmanagement. Während der gewünschte Zustand einzelner Ressourcen deklarativ definiert wird, erfolgt die Ausführung der Tasks in der festgelegten Reihenfolge (imperativ).

9.1.1 Deklarative Ebene (Module):

- name: Installiere Apache
  apt:
    name: apache2
    state: present

Das Modul definiert den Zielzustand (state: present), ohne die Implementierungsdetails zu spezifizieren.

9.1.2 Imperative Ebene (Task-Reihenfolge):

- hosts: webservers
  tasks:
    - name: Installiere Apache
      apt:
        name: apache2
        state: present
    
    - name: Starte Apache Service
      systemd:
        name: apache2
        state: started
        enabled: yes
    
    - name: Kopiere Konfigurationsdatei
      copy:
        src: ./templates/apache.conf
        dest: /etc/apache2/sites-available/000-default.conf
        owner: root
        mode: '0644'
      notify: restart apache

Die Tasks werden sequenziell in der definierten Reihenfolge ausgeführt, obwohl jeder Task deklarativ formuliert ist.

9.2 Idempotenz und Wiederholbarkeit

Ansible überprüft vor jeder Änderung den aktuellen Systemzustand und führt nur notwendige Modifikationen durch. Dies wird durch Checksum-Vergleiche, Systemabfragen und Zustandsprüfungen realisiert.

9.2.1 Praktisches Beispiel für Idempotenz:

- name: Konfigurationsdatei bereitstellen
  copy:
    src: ./templates/app.conf
    dest: /etc/myapp/app.conf
    owner: appuser
    group: appgroup
    mode: '0644'
    backup: yes

Verhalten bei wiederholter Ausführung:

9.2.2 Idempotenz-Prüfungen in Modulen:

9.3 Ablauf eines Playbook-Runs (Execution Flow)

9.3.1 Detaillierte Execution-Phasen:

  1. Inventory-Parsing

  2. Variablen-Resolution

  3. Connection Setup

  4. Facts Gathering (falls aktiviert)

    gather_facts: yes  # Standard
  5. Task-Ausführung (sequenziell)

  6. Handler-Ausführung

  7. Cleanup & Reporting

9.3.2 CLI-Ausführung:

ansible-playbook -i inventory/hosts playbooks/site.yml -v

9.4 Wichtige Mechanismen der Playbook-Ausführung

9.4.1 Handler: Event-basierte Aktionen

Handler werden nur ausgeführt, wenn sie durch einen changed-Status ausgelöst werden:

tasks:
  - name: Aktualisiere Apache-Konfiguration
    copy:
      src: apache.conf
      dest: /etc/apache2/apache2.conf
    notify: restart apache

handlers:
  - name: restart apache
    systemd:
      name: apache2
      state: restarted

Wichtig: Handler laufen erst am Ende des Plays (oder bei flush_handlers).

9.4.2 Bedingungen (when)

Tasks können bedingt ausgeführt werden:

- name: Installiere Apache auf Debian-Systemen
  apt:
    name: apache2
    state: present
  when: ansible_os_family == "Debian"

- name: Installiere httpd auf RedHat-Systemen
  yum:
    name: httpd
    state: present
  when: ansible_os_family == "RedHat"

9.4.3 Schleifen (loop)

Wiederholung von Tasks mit verschiedenen Parametern:

- name: Erstelle mehrere Benutzer
  user:
    name: "{{ item.name }}"
    shell: "{{ item.shell }}"
    groups: "{{ item.groups }}"
  loop:
    - { name: 'alice', shell: '/bin/bash', groups: 'wheel' }
    - { name: 'bob', shell: '/bin/zsh', groups: 'users' }
    - { name: 'charlie', shell: '/bin/bash', groups: 'wheel,docker' }

9.4.4 Fehlerbehandlung (block/rescue/always)

Strukturierte Behandlung von Fehlern und Cleanup:

- block:
    - name: Kritische Konfiguration anwenden
      template:
        src: critical.conf.j2
        dest: /etc/critical.conf
    
    - name: Service neustarten
      systemd:
        name: myservice
        state: restarted
  
  rescue:
    - name: Fallback-Konfiguration aktivieren
      copy:
        src: fallback.conf
        dest: /etc/critical.conf
    
    - name: Administrator benachrichtigen
      mail:
        to: admin@company.com
        subject: "Konfigurationsfehler auf {{ inventory_hostname }}"
  
  always:
    - name: Logs rotieren
      command: logrotate -f /etc/logrotate.conf

9.4.5 Weitere wichtige Optionen:

9.5 Diagramm: Technischer Playbook-Workflow

┌─────────────────┐
│   Playbook      │
│   Start         │
└─────────┬───────┘
          │
┌─────────▼───────┐
│ Inventory       │ ← hosts, groups, variables
│ Loading         │
└─────────┬───────┘
          │
┌─────────▼───────┐
│ Variable        │ ← group_vars, host_vars, 
│ Resolution      │   extra_vars, defaults
└─────────┬───────┘
          │
┌─────────▼───────┐
│ Connection      │ ← SSH setup, become
│ Setup           │   privilege escalation
└─────────┬───────┘
          │
┌─────────▼───────┐
│ Facts           │ ← ansible_* variables
│ Gathering       │   (if gather_facts: yes)
└─────────┬───────┘
          │
┌─────────▼───────┐
│ Task Loop       │
│ ┌─────────────┐ │
│ │Task 1       │ │ ← check state → execute if needed
│ │  status: ok │ │ ← ok/changed/failed/skipped
│ └─────────────┘ │
│ ┌─────────────┐ │
│ │Task 2       │ │ ← notify handlers if changed
│ │status:change│ │
│ └─────────────┘ │
│ ┌─────────────┐ │
│ │Task N       │ │
│ │status:failed│ │ ← abort play if fatal
│ └─────────────┘ │
└─────────┬───────┘
          │
┌─────────▼───────┐
│ Handler         │ ← execute only if notified
│ Execution       │   and tasks changed
└─────────┬───────┘
          │
┌─────────▼───────┐
│ Summary         │ ← ok=X changed=X 
│ Report          │   unreachable=X failed=X
└─────────────────┘

9.5.1 Status-Codes im Detail: