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

(与Ansibleangular色中的Callbacks或hooks以及可重用的一系列任务有关 ):

有没有更好的方法来追加到列表中,或者使用jina2模板expression式将关键字添加到Ansible的字典中(ab)?

我知道你可以做这样的事情:

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

但是真的没有这样的元任务或帮手吗?

它感觉脆弱,似乎没有logging,并依赖于关于variables如何在Ansible中工作的大量假设。

我的用例是多个angular色(数据库服务器扩展),每个angular色都需要为基本angular色(数据库服务器)提供一些configuration。 这不像在数据库服务器configuration文件中添加一行那么简单; 每个更改都适用于同一行 ,例如,扩展pg_stat_statementspg_stat_statements必须出现在目标行上:

 shared_preload_libaries = 'bdr, pg_stat_statements' 

是Ansible的方式做到这一点,只是处理configuration文件多次(每扩展一次)与正则expression式提取当前值,parsing它,然后重写它? 如果是这样的话,你如何在多次运行中使这个幂等性?

如果configuration比parsing更难,而且不像追加另一个逗号分隔值那么简单? 想想XMLconfiguration文件。

你可以用一个variables合并两个列表。 假设你有一个包含这个内容的group_vars文件:

 --- # group_vars/all pgsql_extensions: - ext1 - ext2 - ext3 

它用在模板pgsql.conf.j2如下所示:

 # {{ ansible_managed }} pgsql_extensions={% for item in pgsql_extensions %}{{ item }}, {% endfor %} 

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

 --- # group_vars/testing_db append_exts: - ext4 - ext5 pgsql_extensions: "{{ pgsql_extensions + append_exts }}" 

当angular色在任何testing服务器上运行时,将添加附加扩展。

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

由于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: my appender set_fact: my_dict_var: '{{my_dict_var|combine({item[0]: item[1]})}}' with_items: - ('key1', 'value1',) - ('key2', 'value2',) ... - ('keyN', 'valueN',) 

以上所有内容均logging在: http : //docs.ansible.com/ansible/playbooks_filters.html

你需要将循环分成2个

 --- 
 - 主机:localhost
  任务: 
     -  include_vars:堆栈
     -  set_facts:roles = {{stacks.Roles | 分裂(' ')}}
     - 包括:addhost.yml
       with_items:“{{roles}}”

和addhost.yml

 -  set_facts:groupname = {{item}}
 -  set_facts:ips = {{stacks [item] | split('')}}
 -  local_action:add_host hostname = {{item}} groupname = {{groupname}}
   with_items:{{ips}}

Ansible是一个自动化系统,关于configuration文件pipe理,它与apt并没有太大的区别。 越来越多的软件提供了从conf.d目录读取configuration片段的function的原因是为了使这样的自动化系统具有不同的软件包/angular色添加configuration到软件。 我相信Ansible的哲学Ansible你想到的,而是使用conf.d技巧。 如果正在configuration的软件不提供此function,则可能会遇到麻烦。

既然你提到了XMLconfiguration文件,我借此机会发牢骚。 Unix使用纯文本configuration文件的传统有一个原因。 二进制configuration文件不适合系统自动化,所以任何types的二进制格式都会给您带来麻烦,并且可能需要您创build一个程序来处理configuration。 (如果有人认为XML是纯文本格式,他们应该去检查一下他们的大脑。)

现在,在你的具体PostgreSQL问题。 PostgreSQL确实支持conf.d技巧。 首先,我会检查是否可以多次指定shared_preload_libraries 。 我没有在文档中发现任何暗示,但我仍然会尝试。 如果不能指定多次,我会向PostgreSQL员工解释我的问题,以防他们有想法; 这是一个PostgreSQL问题,而不是一个Ansible问题。 如果没有解决scheme,我真的不能将不同的angular色合并成一个,我会实现一个系统来编译托pipe主机上的configuration。 在这种情况下,我可能会创build一个脚本/usr/local/sbin/update_postgresql_config ,它将编译/etc/postgresql/postgresql.conf.jinja/etc/postgresql/9.x/main/postgresql.conf 。 该脚本将从/etc/postgresql/shared_preload_libraries.txt读取共享的预加载库,每行一个库,并将它们提供给jinja。

自动化系统这样做并不罕见。 一个例子是Debian exim4软件包。