Während einfache Playbooks aus einer Liste von Tasks bestehen, die auf einer Gruppe von Hosts ausgeführt werden, bieten erweiterte Playbook-Techniken zusätzliche Flexibilität, Skalierbarkeit und Wiederverwendbarkeit. Durch den Einsatz von Techniken wie bedingter Logik, Schleifen, Blockstrukturen und der dynamischen Modifizierung von Playbooks können komplexe Automatisierungsszenarien effizient bewältigt werden.
block, rescue, always)Blöcke in Ansible dienen dazu, mehrere Aufgaben zusammenzufassen, und
erlauben es, Fehlerbehandlungen (rescue) und immer
auszuführende Aufgaben (always) zu definieren. Sie
ermöglichen eine bessere Kontrolle über die Ausführung von Aufgaben und
tragen zur Fehlerbehebung bei.
Beispiel für einen Block mit Fehlerbehandlung:
- name: Installation eines Webservers
block:
- name: Installiere Apache
apt:
name: apache2
state: present
notify: Starte Apache
- name: Konfiguriere Apache
template:
src: apache.conf.j2
dest: /etc/apache2/apache2.conf
rescue:
- name: Benachrichtige bei Fehlern
debug:
msg: "Fehler bei der Installation oder Konfiguration von Apache."
always:
- name: Stelle sicher, dass Apache-Protokolle vorhanden sind
file:
path: /var/log/apache2
state: directorywhen)Mit der when-Anweisung können Sie Playbooks so steuern,
dass Tasks nur dann ausgeführt werden, wenn bestimmte Bedingungen
erfüllt sind. Dies kann auf Fakten, Variablen oder andere Bedingungen
basieren.
Beispiel für bedingte Logik:
- name: Installiere Apache nur auf Debian-basierten Systemen
apt:
name: apache2
state: present
when: ansible_os_family == "Debian"Sie können komplexere Bedingungen mit and,
or und not kombinieren.
Beispiel für eine kombinierte Bedingung:
- name: Installiere Nginx nur auf Debian-basierten Systemen, außer wenn Apache läuft
apt:
name: nginx
state: present
when: ansible_os_family == "Debian" and apache_running == falseloopSchleifen (loop) in Ansible ermöglichen die Wiederholung
einer Aufgabe für eine Liste von Elementen. Dies kann die Installation
mehrerer Pakete, die Verwaltung mehrerer Benutzer oder das Bearbeiten
von Konfigurationsdateien umfassen.
Beispiel für die Installation mehrerer Pakete:
- name: Installiere mehrere Pakete
apt:
name: "{{ item }}"
state: present
loop:
- apache2
- mysql-server
- phpSie können geschachtelte Schleifen verwenden, um mehrere Variablen oder komplexe Datenstrukturen in Playbooks zu verwalten.
Beispiel für eine geschachtelte Schleife:
- name: Erstelle Verzeichnisse für verschiedene Benutzer
file:
path: "/home/{{ item.user }}/{{ item.folder }}"
state: directory
loop:
- { user: 'alice', folder: 'documents' }
- { user: 'bob', folder: 'music' }
- { user: 'charlie', folder: 'pictures' }include_tasks und import_tasksMit include_tasks und import_tasks können
Sie dynamisch Aufgaben in ein Playbook einbinden. Der Unterschied
besteht darin, dass include_tasks die Aufgaben zur Laufzeit
einbindet, während import_tasks dies zur Parsing-Zeit
tut.
Beispiel für die dynamische Einbindung von Tasks:
- name: Importiere ein statisches Task-Set
import_tasks: tasks/apache.yml
- name: Inkludiere ein dynamisches Task-Set
include_tasks: tasks/dynamic_tasks.yml
when: ansible_os_family == "RedHat"Ansible verwendet Jinja2-Templates, um dynamische Konfigurationsdateien zu erstellen, die während der Playbook-Ausführung angepasst werden können. Dies ermöglicht eine flexible und wiederverwendbare Verwaltung von Konfigurationsdateien.
Beispiel für ein Jinja2-Template
(nginx.conf.j2):
server {
listen 80;
server_name {{ server_name }};
location / {
root {{ document_root }};
}
}
Beispiel für die Verwendung des Templates in einem Playbook:
- name: Wende Nginx-Template an
template:
src: nginx.conf.j2
dest: /etc/nginx/nginx.conf
vars:
server_name: example.com
document_root: /var/www/htmlMit Jinja2-Filtern können Sie Variablen transformieren und Daten innerhalb eines Playbooks dynamisch verarbeiten.
Beispiel für die Verwendung von Filtern:
- name: Zeige die erste IP-Adresse
debug:
msg: "Die erste IP-Adresse ist {{ ansible_all_ipv4_addresses | first }}"
- name: Zeige eine Liste von Benutzern in Großbuchstaben an
debug:
msg: "{{ item | upper }}"
loop:
- alice
- bob
- charlieIn Ansible können Sie komplexe Datenstrukturen wie Listen und Dictionaries verwenden, um mehrere Werte zu speichern und darauf dynamisch zuzugreifen.
Beispiel für ein Dictionary:
users:
alice:
shell: /bin/bash
uid: 1001
bob:
shell: /bin/zsh
uid: 1002In einem Playbook können Sie diese Datenstruktur durchlaufen:
- name: Erstelle Benutzer
user:
name: "{{ item.key }}"
shell: "{{ item.value.shell }}"
uid: "{{ item.value.uid }}"
loop: "{{ users | dict2items }}"retryManchmal müssen Aufgaben wiederholt werden, wenn sie beim ersten
Versuch fehlschlagen, z.B. aufgrund vorübergehender Netzwerkprobleme.
Mit retry und delay können Sie dies
steuern.
Beispiel für eine wiederholte Aufgabe:
- name: Prüfe, ob der Webserver verfügbar ist
uri:
url: http://localhost
return_content: yes
retries: 5
delay: 10
until: result.status == 200
register: resultfailed_when und ignore_errorsMit failed_when können Sie benutzerdefinierte
Bedingungen festlegen, unter denen eine Aufgabe als fehlgeschlagen
betrachtet wird. Mit ignore_errors können Sie Fehler
ignorieren und das Playbook fortsetzen.
Beispiel für benutzerdefinierte Fehlerbedingungen:
- name: Überprüfe den freien Speicherplatz
command: df -h /
register: disk_usage
failed_when: "'100%' in disk_usage.stdout"Beispiel für das Ignorieren von Fehlern:
- name: Starte einen Dienst, aber ignoriere Fehler
service:
name: apache2
state: restarted
ignore_errors: yes