如何更新ansible库存中的dict值

问题描述 投票:0回答:1

我有一个角色测试。

在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

有没有正确的方法只覆盖特定的键而不是整个字典。

ansible
1个回答
0
投票

一般来说,尽管有一个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"
}
© www.soinside.com 2019 - 2024. All rights reserved.