在ansible中合并字典

Ber*_*rak 41 python merge dictionary 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)
Run Code Online (Sandbox Code Playgroud)

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

aug*_*rar 69

在Ansible 2.0中,有一个Jinja过滤器,combine为此:

- debug: msg="{{ item.key }} = {{ item.value }}"
  with_dict: "{{ my_default_values | combine(my_values) }}"
Run Code Online (Sandbox Code Playgroud)


jar*_*arv 12

如果你想要哈希合并,我会在ansible中打开哈希合并功能.在你的ansible配置文件中打开哈希合并.

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

defaults.yml:

values:
  key: value
Run Code Online (Sandbox Code Playgroud)

overrides.yml:

values:
  my_key: my_value
Run Code Online (Sandbox Code Playgroud)

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

ansible-playbook some-play.yml ... -e@defaults.yml  -e@overrides.yml
Run Code Online (Sandbox Code Playgroud)

你会最终得到这个:

TASK: [debug var=values] ********************************************************
ok: [localhost] => {
    "values": {
        "key": value,
        "my_key": my_value
    }
}
Run Code Online (Sandbox Code Playgroud)

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

  • 更改此设置可能会破坏其他角色.尝试使用jinja2组合方法. (9认同)
  • 关注@kalu所说的 - 使用哈希合并是危险的劝阻. (3认同)

lei*_*iiv 8

现在可以使用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
Run Code Online (Sandbox Code Playgroud)

结果:

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

TASK [debug] 
ok: [localhost] => {
    "my_values": {
        "key": "value", 
        "my_key": "my_value"
    }
}
Run Code Online (Sandbox Code Playgroud)

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

  • 太酷了!尽管这可以完成任务,但我认为问题是您需要用“&name”修饰所有源对象,这可能会很麻烦。如果您使用共享角色,而该角色(和原始变量对象)由其他人维护,则可能会出现问题。另外,我还没有测试过,但是似乎有运行时问题,文件加载时会进行评估,Jinja模板解决方案可能会在预期的时间发生,尤其是当有“ when”修饰符时。关于此与Combine()之间的评估时间有任何想法吗? (4认同)

Nat*_*Nat 6

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

\n\n
- set_fact: _my_values="{{\xc2\xa0my_default_values|combine(my_values) }}"\n\n- debug: msg="{{ item.key }} = {{ item.value }}"\n  with_dict: _my_values\n
Run Code Online (Sandbox Code Playgroud)\n