fusion de dictionnaires dans ansible

je suis en train de construire un rôle pour l'installation de PHP en utilisant ansible, et j'ai quelques difficultés à fusionner les dictionnaires. J'ai essayé plusieurs façons de le faire, mais je ne peux pas le faire fonctionner 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)

y a-t-il un moyen de fusionner deux dictionnaires, pour que je puisse l'utiliser avec "with_dict"?

31
demandé sur Berry Langerak 2014-08-21 13:26:53

6 réponses

dans la version Ansible 2.0, Il y a un filtre Jinja,combine:

- debug: msg="{{ item.key }} = {{ item.value }}"
  with_dict: "{{ my_default_values | combine(my_values) }}"
56
répondu augurar 2016-04-13 19:18:50

si vous voulez la fusion de hachage, Je activerais la fonction de fusion de hachage dans une possibilité. Dans votre ansible fichier de configuration tour de hachage de la fusion sur.

hash_behaviour=merge vous pouvez avoir deux fichiers var avec le même nom de variable:

valeurs par défaut.yml:

values:
  key: value

remplace.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 ... -e@defaults.yml  -e@overrides.yml

Et vous allez vous retrouver avec ceci:

TASK: [debug var=values] ********************************************************
ok: [localhost] => {
    "values": {
        "key": value,
        "my_key": my_value
    }
}

appeler update sur une variable peut être fait dans Jinja mais en général ce sera un peu compliqué, Je ne le ferais pas en dehors de vos modèles et même alors essayer de l'éviter complètement.

12
répondu jarv 2014-08-21 12:35:25
---
- 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.

4
répondu leiiv 2017-01-24 08:57:10

si vous avez besoin du dictionnaire fusionné plusieurs fois, vous pouvez le définir à une nouvelle "variable":

- set_fact: _my_values="{{ my_default_values|combine(my_values) }}"

- debug: msg="{{ item.key }} = {{ item.value }}"
  with_dict: _my_values
2
répondu Nat 2016-06-01 07:15:12

rôle de la galaxie possible.

je l'ai fait il y a quelque temps pour la même raison. Il peut fusionner des dictionnaires profonds à partir de plusieurs fichiers vars et définir la priorité personnalisée de la fusion.

ce rôle peut fonctionner sous Ansible 2.0+

1
répondu eugene0707 2016-11-15 21:07:10
>>> key = 'default key'
>>> value = 'default value'
>>> my_key = 'my key'
>>> my_value = 'my value'
>>>
>>> my_default_values = {key: value}
>>> print my_default_values
{'default key': 'default value'}
>>>
>>> my_values = {my_key: my_value}
>>> print my_values
{'my key': 'my value'}
>>>
>>> with_dict = my_default_value.copy()
>>> print with_dict
{'default key': 'default value'}
>>> with_dict.update(my_values)
>>> print with_dict
{'default key': 'default value', 'my key': 'my value'}
-1
répondu Quentin THEURET 2014-08-21 09:59:55