(与Ansible 角色中的回调或钩子以及可重用的一系列任务有关):
有没有比(ab)使用 jina2 模板表达式更好的方法来追加到列表或在 Ansible 中向字典添加键?
我知道您可以执行以下操作:
- name: this is a hack
shell: echo "{% originalvar.append('x') %}New value of originalvar is {{originalvar}}"
但是真的没有任何元任务或助手可以做到这一点吗?
它感觉很脆弱,似乎没有文档记录,并且依赖于许多关于变量在 Ansible 中如何工作的假设。
我的用例是多个角色(数据库服务器扩展),每个角色都需要为基本角色(数据库服务器)提供一些配置。这不像在 db server 配置文件中添加一行那么简单;每个更改都适用于同一行,例如扩展名bdr
和pg_stat_statements
必须都出现在目标行上:
shared_preload_libaries = 'bdr, pg_stat_statements'
执行此操作的 Ansible 方法是否只是使用正则表达式多次处理配置文件(每个扩展名一次),提取当前值,解析它,然后重写它?如果是这样,您如何在多次运行中使其具有幂等性?
如果配置比这更难解析并且不像附加另一个逗号分隔值那么简单怎么办?想想 XML 配置文件。
从 Ansible v2.x 开始,您可以执行以下操作:
以上所有内容都记录在: https ://docs.ansible.com/ansible/latest/user_guide/playbooks_filters.html#combining-hashes-dictionaries
您可以使用 合并变量中的两个列表
+
。假设您有一个group_vars
包含以下内容的文件:它用于模板中,
pgsql.conf.j2
例如:然后,您可以将扩展附加到测试数据库服务器,如下所示:
当角色在任何测试服务器中运行时,将添加额外的扩展。
我不确定这也适用于字典,并且还要小心空格并在行尾留下一个悬空的逗号。
你需要把循环分成2
和 addhost.yml
这里几乎所有的答案都需要更改任务,但我需要在 vars 定义中动态合并字典,而不是在运行期间。
例如,我想在其中定义一些共享变量
all
group_vars
,然后我想在其他一些group
或host_vars
. 在为角色工作时非常有用。如果您尝试使用
combine
orunion
过滤器覆盖 var 文件中的原始变量,您将在模板过程中以无限循环结束,因此我创建了此解决方法(这不是解决方案)。您可以根据某些名称模式定义多个变量,然后自动将它们加载到角色中。
group_vars/all.yml
group_vars/group1.yml
角色代码片段
do_some_stuff.yml
这只是一个片段,但您应该了解它是如何工作的。注意:lookup('varnames','') 从 ansible 2.8 开始可用
我想也可以
dictionary_of_bla.*
在运行时使用相同的查找将所有变量合并到一个字典中。这种方法的优点是您不需要设置确切的变量名称列表,而只有模式和用户可以动态设置它。
不确定他们什么时候添加的,但至少对于字典/哈希(不是列表/数组),您可以设置变量hash_behaviour,如下所示:
hash_behaviour = merge
在您的ansible.cfg
.我花了好几个小时才偶然发现这个设置:S
Ansible
是一个自动化系统,并且,关于配置文件管理,它与apt
. 越来越多的软件提供从conf.d
目录读取配置片段的功能的原因是使此类自动化系统能够具有不同的包/角色,从而将配置添加到软件中。我相信这不是Ansible
做你想做的事的哲学,而是使用conf.d
技巧。如果正在配置的软件不提供此功能,您可能会遇到麻烦。既然你提到了 XML 配置文件,我借此机会做一些抱怨。Unix 传统使用纯文本配置文件是有原因的。二进制配置文件不适合系统自动化,因此任何类型的二进制格式都会给您带来麻烦,并且可能需要您创建一个程序来处理配置。(如果有人认为 XML 是纯文本格式,他们应该去好好研究一下。)
现在,关于你的具体
PostgreSQL
问题。PostgreSQL
确实支持这个conf.d
把戏。首先,我会检查是否shared_preload_libraries
可以多次指定。我在文档中没有找到任何提示,但我仍然会尝试。如果不能多次指定,我会向他们解释我的问题PostgreSQL
,以防他们有想法;这是一个PostgreSQL
问题,而不是一个Ansible
问题。如果没有解决方案并且我真的无法将不同的角色合并为一个,我将实现一个系统来编译托管主机上的配置。在这种情况下,我可能会创建一个/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
软件包。