Angenommen, Sie müssen denselben Webserver auf zehn verschiedenen Systemen installieren, aber mit jeweils unterschiedlichen Ports, Logverzeichnissen und Konfigurationen. Statt zehn separate Playbooks zu schreiben und zu warten, nutzen Sie Variablen – und haben damit nur ein einziges, flexibles Playbook für alle Umgebungen.
Variablen sind ein wesentliches Element in Ansible, das die Flexibilität und Wiederverwendbarkeit von Playbooks erheblich steigert. Durch den Einsatz von Variablen können Sie Werte dynamisch definieren und anpassen, ohne die Struktur des Playbooks ändern zu müssen. Variablen ermöglichen es, Playbooks für verschiedene Umgebungen oder Hostgruppen zu verwenden, indem spezifische Werte einfach angepasst werden.
Variablen können an verschiedenen Stellen in Ansible definiert werden, darunter:
vars definiert
werden.group_vars und
host_vars: Variablen können in Dateien definiert
werden, die spezifisch für Gruppen oder Hosts sind.Beispiel für die Deklaration von Variablen in einem Playbook:
---
- name: Beispiel Playbook mit Variablen
hosts: webservers
vars:
http_port: 8080
max_clients: 100
tasks:
- name: Setze Apache Port
lineinfile:
path: /etc/apache2/ports.conf
regexp: '^Listen'
line: "Listen {{ http_port }}"
- name: Setze maximale Anzahl von Clients
lineinfile:
path: /etc/apache2/apache2.conf
regexp: '^MaxClients'
line: "MaxClients {{ max_clients }}"Variablen werden in Ansible durch doppelgeschweifte Klammern
{{ }} referenziert. Ansible löst diese Platzhalter zur
Laufzeit auf und ersetzt sie durch die tatsächlichen Werte der
Variablen.
Beispiel:
line: "Listen {{ http_port }}"In diesem Beispiel wird die Variable http_port aufgelöst
und der Wert, z.B. 8080, wird in die Konfigurationsdatei
eingefügt.
In Ansible gibt es eine festgelegte Reihenfolge, nach der Variablen priorisiert und überschrieben werden können. Diese Prioritätenreihenfolge, auch als “Precedence” bezeichnet, bestimmt, welche Variable verwendet wird, wenn mehrere Variablen mit demselben Namen definiert sind.
Wichtiger Hinweis: Bei gleichnamigen Variablen wird immer der Wert mit der höchsten Priorität verwendet. Dies kann zu schwer nachvollziehbaren Fehlern führen, wenn Variablen in mehreren Quellen definiert sind.
| Rang | Quelle | Gültigkeitsbereich | Überschreibbar |
|---|---|---|---|
| 1 | Kommandozeile (-e) |
global | ja |
| 2 | Playbook-vars: |
pro Playbook | ja |
| 3 | Rollen-vars/main.yml |
Rolle | ja |
| 4 | group_vars / host_vars |
Inventory-spezifisch | ja |
| 5 | Rollen-defaults/main.yml |
Rolle (Standardwert) | ja |
| 6 | set_fact zur Laufzeit |
Host-lokal | ja |
| 7 | automatisch gesammelte Fakten | Host-lokal (read-only) | nein |
Beispiel zur Demonstration der Prioritäten:
---
- name: Beispiel Playbook für Variablen-Priorität
hosts: webservers
vars:
http_port: 8080 # Wird überschrieben, wenn über Kommandozeile definiert
max_clients: 100
tasks:
- name: Setze Apache Port
lineinfile:
path: /etc/apache2/ports.conf
regexp: '^Listen'
line: "Listen {{ http_port }}"Wird dieses Playbook mit einer über die Kommandozeile definierten Variable aufgerufen, hat diese den Vorrang:
ansible-playbook -i inventory playbook.yml -e "http_port=9090"In diesem Fall wird http_port mit 9090
überschrieben.
Rolleninterner Scope:
defaults/main.yml: Standardwerte der Rolle (niedrigste
Priorität)vars/main.yml: Feste Rollenvariablen (mittlere
Priorität)tasks/main.yml: Task-spezifische VariablenExterner Scope:
group_vars/: Gruppenbezogene Variablenhost_vars/: Hostspezifische VariablenAnsible ermöglicht es, Variablen innerhalb von Strings zu interpolieren, was bedeutet, dass Variablenwerte in Strings eingefügt werden können, um dynamische Werte zu erzeugen.
Playbook-Ausschnitt:
- name: Erstelle eine Begrüßungsdatei
copy:
content: "Willkommen, {{ ansible_user }}!"
dest: /home/{{ ansible_user }}/welcome.txtIn diesem Beispiel wird der Benutzername, der zur Laufzeit durch
ansible_user bestimmt wird, sowohl im Inhalt als auch im
Dateipfad verwendet.
Ansible unterstützt auch die Verwendung von verschachtelten Variablen und komplexen Datenstrukturen wie Listen und Dictionaries. Dies ermöglicht eine noch größere Flexibilität bei der Definition von Konfigurationen.
Beispiel für komplexe Datenstrukturen:
---
- name: Beispiel Playbook mit verschachtelten Variablen
hosts: all
vars:
users:
- name: alice
uid: 1001
- name: bob
uid: 1002
tasks:
- name: Erstelle Benutzer
user:
name: "{{ item.name }}"
uid: "{{ item.uid }}"
loop: "{{ users }}"Ansible ermöglicht die dynamische Berechnung und Manipulation von Variablenwerten zur Laufzeit durch die Verwendung von Filtern und Jinja2-Templates.
Beispiel für die Verwendung von Jinja2-Filtern:
---
- name: Berechne dynamischen Wert
hosts: all
vars:
base_path: "/var/www"
site_name: "example"
tasks:
- name: Erstelle dynamisches Verzeichnis
file:
path: "{{ base_path }}/{{ site_name | lower }}"
state: directoryHier wird der Name des Verzeichnisses zur Laufzeit durch die Kombination und Verarbeitung mehrerer Variablen berechnet.
Komplexe Datenstrukturen wie Listen und Dictionaries sind in Ansible äußerst nützlich, um strukturierte Daten zu verwalten und wiederverwendbare Konfigurationen zu erstellen.
Listen werden in YAML durch einfache Bindestriche definiert und ermöglichen es, mehrere Werte in einer geordneten Reihenfolge zu speichern.
Beispiel für eine Liste:
users:
- alice
- bob
- charlieDictionaries (Schlüssel-Wert-Paare) sind eine Möglichkeit, zusammengehörige Daten in einer nicht geordneten Struktur zu speichern.
Beispiel für ein Dictionary:
user_details:
alice:
uid: 1001
shell: /bin/bash
bob:
uid: 1002
shell: /bin/zshSie können Listen und Dictionaries kombinieren, um komplexe Datenstrukturen zu erstellen, die sich hervorragend für die Verwaltung von Konfigurationen in Ansible eignen.
Beispiel für eine kombinierte Struktur:
users:
- name: alice
uid: 1001
shell: /bin/bash
- name: bob
uid: 1002
shell: /bin/zshDiese Struktur kann dann in Ansible-Tasks wie folgt verwendet werden:
tasks:
- name: Erstelle Benutzer
user:
name: "{{ item.name }}"
uid: "{{ item.uid }}"
shell: "{{ item.shell }}"
loop: "{{ users }}"Diese Flexibilität in der Verwendung von Variablen ermöglicht es, Playbooks zu erstellen, die einfach zu warten, wiederverwendbar und auf verschiedene Anwendungsfälle anpassbar sind.