我有一个角色测试。
在roles / test / defaults / mail.yaml中
# defaults file for test
data:
a: hello
如何从库存文件中覆盖data.a
的值
我在库存文件中尝试了以下语法,但没有奏效
1).
[master]
Master ansible_host=127.0.0.1 data.a=world
2)
[master]
Master ansible_host=127.0.0.1 data['a']=world
有没有正确的方法只覆盖特定的键而不是整个字典。
一般来说,尽管有一个specific configuration option you can set to change the default behavior,你不能做你所要求的。您可以在链接的文档中阅读相关文档,但我不建议启用它,因为这会使您的playbooks的行为依赖于它在何处运行的ansible配置,这可能会导致意外(a)你在另一台机器上运行剧本,你忘记包括适当的配置或(b)如果你以外的其他人运行剧本。
在标准用法中,如果你有defaults/main.yml
:
data:
a: something
b: something else
您可以在库存中覆盖data
变量本身,但如果您需要像字典这样的结构化变量,则需要使用YAML库存格式:
all:
children:
master:
hosts:
Master:
ansible_host: 127.0.0.1
data:
a: another thing
使用此库存,data
的值将是{"a": "another thing"}
。
您可以通过为默认值和特定于主机的覆盖使用不同的变量名来解决此问题。例如,如果你在defaults/main.yml
:
data:
a: foo
b: bar
在你的库存,或host_vars
,或group_vars
你有:
host_data:
a: red
c: bucket
然后,您可以在访问数据时使用combine
过滤器:
{{ data|combine(host_data) }}
这将评估为一个字典,看起来像:
{
"a": "red",
"b": "bar",
"c": "bucket"
}
在一个示例任务中:
- name: iterate over the keys and values of our variable
debug:
msg: "{{ item.key }} is {{ item.value }}"
loop: "{{ (data|combine(host_data))|dict2items }}"
鉴于我们上面的示例数据会产生:
TASK [iterate over the keys and values of our variable] ***************************************
ok: [Master] => (item={'key': u'a', 'value': u'red'}) => {
"msg": "a is red"
}
ok: [Master] => (item={'key': u'c', 'value': u'bucket'}) => {
"msg": "c is bucket"
}
ok: [Master] => (item={'key': u'b', 'value': u'bar'}) => {
"msg": "b is bar"
}