Ansible - 当使用带有with_items的set_fact模块时,如何在字典中附加新密钥?

Ana*_*tel 16 ansible

我想在使用带有with_items的set_fact时将键添加到字典中.这是一个小POC,它将帮助我完成其他一些工作.我试图概括POC,以便从中删除所有不相关的细节.

当我执行下面的代码时,它会显示一个字典,其中只有一个键对应于with_items的最后一项.它似乎正在重新创建一个新字典,或者可能会覆盖with_items中每个项目的现有字典.我想要一本包含所有键的字典.

码:

---
- hosts: localhost
  connection: local
  vars:
      some_value: 12345
      dict: {}
  tasks:
     - set_fact: {
          dict: "{
             {{ item }}: {{ some_value }}
             }"
            }
       with_items:
          - 1
          - 2
          - 3
     - debug: msg="{{ dict }}"
Run Code Online (Sandbox Code Playgroud)

And*_*eas 25

这也可以在不使用Ansible 2.2中测试的插件的情况下完成.

---
- hosts: localhost
  connection: local
  vars:
    some_value: 12345
    dict: {}
  tasks:
  - set_fact:
      dict: "{{ dict | combine( { item: some_value } ) }}"
    with_items:
      - 1
      - 2
      - 3
  - debug: msg="{{ dict }}"
Run Code Online (Sandbox Code Playgroud)

或者,这可以在没有包含文件的复杂单行内容的情况下编写.

  tasks:
  - include: append_dict.yml
    with_items: [1, 2, 3]
Run Code Online (Sandbox Code Playgroud)

append_dict.yml:

- name: "Append dict: define helper variable"
  set_fact:
    _append_dict: "{ '{{ item }}': {{ some_value }} }"

- name: "Append dict: execute append"
  set_fact:
    dict: "{{ dict | combine( _append_dict ) }}"
Run Code Online (Sandbox Code Playgroud)

输出:

TASK [debug]
*******************************************************************
ok: [localhost] => {
    "msg": {
        "1": "12345",
        "2": "12345",
        "3": "12345"
    }
}
Run Code Online (Sandbox Code Playgroud)

单引号'各地{{ some_value }}都需要存储字符串值作了明确规定.

此语法也可用于通过引用和从dict元素方面追加.with_dictitem.keyitem.value

例如,可以在同一步骤中执行诸如添加前缀和后缀或散列的操作

    set_fact:
      dict: "{{ dict | combine( { item.key + key_postfix: item.value + '_' +  item.value | hash('md5') } ) }}"
Run Code Online (Sandbox Code Playgroud)

  • 您可以使用 `dict: "{{ dict | default({}) | merge( { item: some_value } ) }}"` 不必将其初始化为空字典。 (3认同)

Ben*_*ley 7

使用过滤插件.

首先,在你的ansible base dir中创建一个新文件filter_plugins/makedict.py.

现在创建一个名为"makedict"(或任何你想要的)的新函数,它接受一个值和一个列表并返回一个新的字典,其中键是列表的元素,值总是相同的.

class FilterModule(object):
     def filters(self):
         return { 'makedict': lambda _val, _list: { k: _val for k in _list }  }
Run Code Online (Sandbox Code Playgroud)

现在,您可以使用剧本中的新过滤器来实现所需的结果:

- hosts: 127.0.0.1
  connection: local
  vars:
      my_value: 12345
      my_keys: [1, 2, 3]
  tasks:
    - set_fact: my_dict="{{ my_value | makedict(my_keys) }}"
    - debug: msg="{{ item.key }}={{ item.value }}"
      with_dict: "{{my_dict}}"
Run Code Online (Sandbox Code Playgroud)

您可以使用选项中的选项自定义过滤器插件的位置.filter_pluginsansible.cfg