在ansible中合并字典

时间:2014-08-21 09:26:54

标签: python dictionary merge ansible

我目前正在构建使用ansible安装PHP的角色,而且我在合并字典方面遇到了一些困难。我已经尝试了几种方法,但是我不能像我想要的那样让它工作:

# 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)

有没有办法合并两个字典,所以我可以用“with_dict”吗?

6 个答案:

答案 0 :(得分:63)

在Ansible 2.0中,有一个Jinja过滤器combine,用于:

- debug: msg="{{ item.key }} = {{ item.value }}"
  with_dict: "{{ my_default_values | combine(my_values) }}"

答案 1 :(得分:11)

如果你想要哈希合并,我会在ansible中打开哈希合并功能。 在您的ansible配置文件turn hash merging on中。

使用 hash_behaviour = merge ,您可以拥有两个具有相同变量名称的var文件:

defaults.yml:

values:
  key: value

overrides.yml:

values:
  my_key: my_value

为了合并两个vars,您需要包含两个var文件:

ansible-playbook some-play.yml ... -e@defaults.yml  -e@overrides.yml

你最终会得到这个:

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

调用变量的更新可以在Jinja中完成,但一般来说它会很乱,我不会在你的模板之外做,甚至试图完全避免它。

答案 2 :(得分:5)

现在可以使用锚点并扩展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

结果:

TASK [debug]
ok: [localhost] => {
    "my_default_values": {
        "key": "value"
    }
}

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

我不知道为什么以前没有提到这个。

答案 3 :(得分:3)

如果您需要多次合并字典,可以将其设置为新的&#34;变量&#34;:

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

- debug: msg="{{ item.key }} = {{ item.value }}"
  with_dict: _my_values

答案 4 :(得分:1)

从Ansible Galaxy尝试this role

我之前因为同样的原因这样做了。它可以从几个vars文件深度合并字典,并设置合并的自定义优先级。

此角色可以在Ansible 2.0 +

下运行

答案 5 :(得分:-2)

>>> 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'}