Ein Kollege brachte mich auf die Frage: Wie trennt man in einem Playbook die Logik von der Konfiguration? Der möchte ich hier endlich mal nachgehen.

1 | Einführung |
---|---|
2 | Das Inventory |
3 | Über Rollen und Tasks |
4 | Die Module |
5 | Playbooks |
6 | Konfiguration |
7 | gather_facts |
8 | eigene Module |
9 | Ansible subtasks Tutorial Teil 9 |
10 | Playbook Konfiguration |
11 | Schleifen |
externe Konfiguration
Eine externe Konfiguration für ein Playbook ist z.B. dann interessant, wenn es in unterschiedlichen Umgebungen mit verschiedenen Werten laufen soll.
In diesem Post gehen wir mal davon aus, dass das Playbook auf unterschiedlichen Stages für „develop“ und „testing“ laufen soll. Auf den beiden Stages werden verschiedene Usernamen benutzt.
In develop soll der User dev_user heißen, auf der production Stage prod_user
Das Playbook
Ich habe ein einfaches Playbook erstellt, dass mir die Werte der Variablen stage und user ausgibt. Da wir gleich zwei verschiedene Möglichkeiten ausprobieren, um variable Werte in das Playbook hineinzubekommen, benutzt das Play roles/env/tasks/main.yml beide Varianten.
- name: Zeige die Variablen stage und user aus ENV und aus Ansible-Variablen an.
vars:
stage: "{{ stage }}"
user: "{{ user }}"
debug:
msg:
- "ENV: {{ lookup('env', 'stage') }}"
- "ENV: {{ lookup('env', 'user') }}"
- "VAR: {{ stage | default('Nicht gesetzt') }}"
- "VAR: {{ user | default('Nicht gesetzt') }}"
Das Play deklariert die Variablen stage und user und sucht sie sich über die lookup
Funktion einmal aus dem ENV Kontext und beim zweiten Mal aus dem VAR Kontext für die Ausgabe.
Das Playbook env.yml ruft einfach nur die entsprechende Rolle auf.
- hosts: "{{ target }}"
gather_facts: false
remote_user: pi
roles:
- env
Version 1 mit Environment Variablen
Eine Möglichkeit wäre, in einem bash Script Variablen zu definieren und diese dann im Playbook abzufragen.
set -a
source ${1}
set +a
ansible-playbook -e="target=localhost" env.yml
Dieses Script bekommt den Namen einer.ini Datei übergeben, in der die Variablen gesetzt werden.
Die Datei vars-develop.ini sieht so aus
stage='develop'
user='dev_user'
Die vars-production.ini sieht genauso aus, hat nur andere Werte in den Variablen. Das set -a
sorgt dafür, dass alle Variablen aus der .ini Datei auch exportiert werden. set +a
nimmt diese Konfiguration wieder zurück.
Das Script kannst du jetzt mit
./vars.sh vars-production.ini
starten.

In der Ausgabe erkennst du, dass sowohl bei ENV als auch bei VAR die Werte für stage und user gesetzt sind.
Version 2 mit Variablen Definition beim ansible-playbook Aufruf
Für jedes Playbook ein Script zu schreiben ist vielleicht etwas lästig und nicht unbedingt gewünscht, daher gibt es eine Möglichkeit, Variablen direkt beim Aufruf mit ansible-playbook zu übergeben.
Das Geheimnis ist einfach der --extra-vars
Parameter des Kommandos, den wir einfach an den Aufruf anhängen können.
ansible-playbook -e="target=localhost" env.yml --extra-vars "user=dev_user stage=develop"
Du erkennst sofort, dass du mehrere Variablen einfach durch ein Leerzeichen getrennt, definieren kannst.

Version 3 Variablendeklaration in JSON Datei
Bei richtig vielen Variablen ist Version 2 nicht mehr wirklich zu benutzen. Daher kannst du die Variablen auch im JSON Format in einer Datei vars-develop.json deklarieren und den Dateinamen an ansible-playbook übergeben.
{
"stage": "develop",
"user": "dev_user"
}
Der Aufruf geschieht jetzt wieder mit dem –extra-vars Parameter, allerdings wird dann der Dateiname mit vorangestelltem @
übergeben.
ansible-playbook -e="target=localhost" env.yml --extra-vars "@vars-develop.json"

Fazit
Durch die externe Konfiguration kannst du ein Playbook sehr viel besser allgemeingültig halten.
Alle Dateien findest du im Git Repo.