Ansible verwendet Jinja2 für den Filter von Variablen.
Möchten Sie manchmal Variablen einschließlich Wörterbücher vertiefen? Heute werde ich zwei Möglichkeiten vorstellen, um eine tiefe Verschmelzung von Variablen mit Ansible zu realisieren. Was anders ist, ist, dass die Methode für Ansible 2.0 und höher und darunter unterschiedlich ist.
Seit Ansible 2.0 wurde ein neuer ** Mähdrescherfilter ** implementiert. http://docs.ansible.com/ansible/playbooks_filters.html#combining-hashes-dictionaries
test.yml
- hosts: localhost
gather_facts: no
vars:
dict:
foo:
bar: 1
dict2:
foo:
baz: 2
qux: 2
# combining hashes/dictionaries (new in version 2.0)
dict_combine: "{{ dict | combine(dict2, recursive=True) }}"
tasks:
- debug:
var: dict_combine
Wenn Sie die oben genannten Schritte ausführen, erhalten Sie die folgenden Ergebnisse.
$ ansible-playbook -i localhost, test.yml
PLAY [localhost] ***************************************************************
TASK [debug] *******************************************************************
ok: [localhost] => {
"dict_combine": {
"foo": {
"bar": 1,
"baz": 2
},
"qux": 2
}
}
Es ist sehr praktisch. Der Inhalt von dict-> foo wird ordnungsgemäß zusammengeführt. Das Weglassen von "rekursiv" ist übrigens nur eine Zusammenführung von Updates.
recursive=false
$ ansible-playbook -i localhost, test.yml
PLAY [localhost] ***************************************************************
TASK [debug] *******************************************************************
ok: [localhost] => {
"dict_combine": {
"foo": {
"baz": 2
},
"qux": 2
}
}
Übrigens könnte die Funktion zum Kombinieren, die rekursiv weglässt, wie folgt realisiert werden, indem update () auch in der Version vor Ansible 2.0 verwendet wird.
test.yml
- hosts: localhost
gather_facts: no
vars:
dict:
foo:
bar: 1
dict2:
foo:
baz: 2
qux: 2
# **[Note]**
# jinja2 'do' tag need expression-statement extension
# please set below to [default] section in ansible.cfg
# jinja2_extensions=jinja2.ext.do
dict_update: |
{% do dict.update(dict2) %}
{{ dict }}
tasks:
- debug:
var: dict_update
Wenn Sie Ansible 1.X aus verschiedenen Gründen verwenden müssen, ist dies etwas unpraktisch, da Sie Combine nicht verwenden können. Natürlich können Sie den in 2.0 implementierten Quellteil des Mähdreschers importieren, aber da dies eine große Sache ist, möchte ich mein eigenes Filter-Plugin erstellen. http://docs.ansible.com/ansible/developing_plugins.html#filter-plugins
Um das Plugin zu verwenden, geben Sie den Pfad (filter_plugins =) in ansible.cfg ein oder legen Sie die benutzerdefinierte Datei direkt im Plugin-Verzeichnis von ansible selbst ab. Sie wird gelesen, wenn ansible ausgeführt wird.
/path-to/ansible/filter_plugins/dict_merge.py
from copy import deepcopy
def dict_merge(a, b):
if not isinstance(b, dict):
return b
result = deepcopy(a)
for k, v in b.iteritems():
if k in result and isinstance(result[k], dict):
result[k] = dict_merge(result[k], v)
else:
result[k] = deepcopy(v)
return result
class FilterModule(object):
def filters(self):
return {'dict_merge': dict_merge}
Damit ist die Plug-In-Erstellung abgeschlossen. Es ist einfacher als du denkst. Lass es uns testen.
test.yml
- hosts: localhost
gather_facts: no
vars:
dict:
foo:
bar: 1
dict2:
foo:
baz: 2
qux: 2
# custom filter plugin
dict_merged: "{{ dict | dict_merge(dict2) }}"
tasks:
- debug:
var: dict_merged
Das Ausführungsergebnis ist wie folgt.
$ ansible-playbook -i localhost, test.yml
PLAY [localhost] ***************************************************************
TASK [debug] *******************************************************************
ok: [localhost] => {
"dict_merged": {
"foo": {
"bar": 1,
"baz": 2
},
"qux": 2
}
}
Ich konnte das gleiche Ergebnis wie Mähdrescher erzielen. Natürlich verschmilzt es auch tiefere Diktate.
Zusätzlich zum Filter-Plug-In verfügt Ansible über mehrere Plug-Ins, die Sie selbst erstellen können. http://docs.ansible.com/ansible/developing_plugins.html
Lookup- und Callback-Plug-Ins sind relativ informativ und enthalten Informationen zu Personen, die verschiedene Aufgaben ausführen.
Let's enjoy your Ansible life!