在 Ansible 中附加到列表或向字典添加键

Cra*_*ger 41 ansible

(与回调或钩子以及可重用系列任务相关,在 Ansible 角色中):

有没有比 (ab) 使用 jina2 模板表达式更好的方法来附加到列表或向 Ansible 中的字典添加键?

我知道你可以这样做:

- name: this is a hack
  shell: echo "{% originalvar.append('x') %}New value of originalvar is {{originalvar}}"
Run Code Online (Sandbox Code Playgroud)

但是真的没有元任务或助手来做到这一点吗?

它感觉很脆弱,似乎没有记录,并且依赖于许多关于变量在 Ansible 中如何工作的假设。

我的用例是多个角色(数据库服务器扩展),每个角色都需要为基本角色(数据库服务器)提供一些配置。它不像在 db 服务器配置文件中添加一行那么简单;每个更改都适用于同一行,例如扩展名,bdr并且pg_stat_statements必须同时出现在目标行上:

shared_preload_libaries = 'bdr, pg_stat_statements'
Run Code Online (Sandbox Code Playgroud)

这样做的 Ansible 方法是否只是使用正则表达式多次处理配置文件(每个扩展名一次),提取当前值,解析它,然后重写它?如果是这样,您如何使多次运行具有幂等性?

如果配置比这更难解析并且它不像附加另一个逗号分隔值那么简单怎么办?想想 XML 配置文件。

Max*_*gan 45

从 Ansible v2.x 开始,您可以执行以下操作:

# use case I: appending to LIST variable:

      - name: my appender
        set_fact:
          my_list_var: '{{my_list_myvar + new_items_list}}'

# use case II: appending to LIST variable one by one:

      - name: my appender
        set_fact:
          my_list_var: '{{my_list_var + [item]}}'
        with_items: '{{my_new_items|list}}'

# use case III: appending more keys DICT variable in a "batch":

      - name: my appender
        set_fact:
          my_dict_var: '{{my_dict_var|combine(my_new_keys_in_a_dict)}}'

# use case IV: appending keys DICT variable one by one from tuples
      - name: setup list of tuples (for 2.4.x and up
        set_fact:
          lot: >
            [('key1', 'value1',), ('key2', 'value2',), ..., ('keyN', 'valueN',)],
      - name: my appender
        set_fact:
          my_dict_var: '{{my_dict_var|combine({item[0]: item[1]})}}'
        with_items: '{{lot}}'
# use case V: appending keys DICT variable one by one from list of dicts (thanks to @ssc)

  - name: add new key / value pairs to dict
    set_fact:
      my_dict_var: "{{ my_dict_var | combine({item.key: item.value}) }}"
    with_items:
    - { key: 'key01', value: 'value 01' }
    - { key: 'key02', value: 'value 03' }
    - { key: 'key03', value: 'value 04' }
Run Code Online (Sandbox Code Playgroud)

以上所有内容都记录在:http : //docs.ansible.com/ansible/playbooks_filters.html


GnP*_*GnP 17

您可以使用 将变量中的两个列表合并+。假设您有一个group_vars包含以下内容的文件:

---
# group_vars/all
pgsql_extensions:
  - ext1
  - ext2
  - ext3
Run Code Online (Sandbox Code Playgroud)

它在模板中使用,pgsql.conf.j2如:

# {{ ansible_managed }}
pgsql_extensions={% for item in pgsql_extensions %}{{ item }}, {% endfor %}
Run Code Online (Sandbox Code Playgroud)

然后,您可以将扩展附加到测试数据库服务器,如下所示:

---
# group_vars/testing_db
append_exts:
  - ext4
  - ext5
pgsql_extensions: "{{ pgsql_extensions + append_exts }}"
Run Code Online (Sandbox Code Playgroud)

当角色在任何测试服务器中运行时,将添加额外的扩展。

我不确定这也适用于字典,并且还要小​​心空格并在行尾留下一个悬空的逗号。

  • 似乎如果您尝试这样做来连接两个列表,它会认为这是一个无限递归模板,因为左侧也在右侧。我误解了如何使用它吗? (4认同)
  • @spectras 至少从 Ansible 2.7 开始,这不起作用。正如 Ibrahim 所建议的,这会导致错误:“在模板字符串中检测到递归循环”。 (2认同)