Je suis en train de créer un rôle pour installer PHP en utilisant ansible, et j'ai des difficultés à fusionner les dictionnaires. J'ai essayé plusieurs façons de le faire, mais je n'arrive pas à le faire travailler comme je le veux:
# A vars file:
my_default_values:
key = value
my_values:
my_key = my_value
# In a playbook, I create a task to attempt merging the
# two dictionaries (which doesn't work):
- debug: msg="{{ item.key }} = {{ item.value }}"
with_dict: my_default_values + my_values
# I have also tried:
- debug: msg="{{ item.key }} = {{ item.value }}"
with_dict: my_default_values|union(my_values)
# I have /some/ success with using j2's update,
# but you can't use j2 syntax in "with_dict", it appears.
# This works:
- debug: msg="{{ my_default_values.update(my_values) }}"
# But this doesn't:
- debug: msg="{{ item.key }} = {{ item.value }}"
with_dict: my_default_values.update(my_values)
Existe-t-il un moyen de fusionner deux dictionnaires, donc je peux l'utiliser avec "with_dict"?
Dans Ansible 2.0, il existe un filtre Jinja, combine
, pour cela:
- debug: msg="{{ item.key }} = {{ item.value }}"
with_dict: "{{ my_default_values | combine(my_values) }}"
Si vous voulez fusionner le hachage, je voudrais activer la fonction de fusion du hachage dans ansible. Dans votre fichier de configuration ansible activez la fusion de hachage .
Avec hash_behaviour = merge vous pouvez avoir deux fichiers var avec le même nom de variable:
defaults.yml:
values:
key: value
overrides.yml:
values:
my_key: my_value
Pour que les deux vars soient fusionnés, vous devrez inclure les deux fichiers var:
ansible-playbook some-play.yml ... [email protected] [email protected]
Et vous vous retrouverez avec ceci:
TASK: [debug var=values] ********************************************************
ok: [localhost] => {
"values": {
"key": value,
"my_key": my_value
}
}
Appeler la mise à jour sur une variable peut être fait dans Jinja mais en général, ce sera compliqué, je ne le ferais pas en dehors de vos modèles et même essayer de l'éviter complètement.
Il est désormais possible d'utiliser l'ancre et d'étendre les fonctionnalités de YAML:
---
- hosts: localhost
vars:
my_default_values: &def
key: value
my_values:
<<: *def
my_key: my_value
tasks:
- debug: var=my_default_values
- debug: var=my_values
Résultat:
TASK [debug]
ok: [localhost] => {
"my_default_values": {
"key": "value"
}
}
TASK [debug]
ok: [localhost] => {
"my_values": {
"key": "value",
"my_key": "my_value"
}
}
Je ne sais pas pourquoi cela n'a pas été mentionné auparavant.
Si vous avez besoin du dictionnaire fusionné plusieurs fois, vous pouvez le définir sur une nouvelle "variable":
- set_fact: _my_values="{{ my_default_values|combine(my_values) }}"
- debug: msg="{{ item.key }} = {{ item.value }}"
with_dict: _my_values
Essayez ce rôle depuis Ansible Galaxy.
Je l'ai fait il y a quelque temps pour la même raison. Il peut fusionner en profondeur les dictionnaires de plusieurs fichiers vars et définir la priorité personnalisée de la fusion.
Ce rôle peut fonctionner sous Ansible 2.0+