如何更新无库存中的字典值

时间:2019-04-25 18:43:21

标签: ansible

我有一个角色测试。

角色/测试/默认值/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

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

1 个答案:

答案 0 :(得分:0)

尽管有specific configuration option you can set to change the default behavior,但一般来说您无法做到的是。您可以在链接的文档中阅读有关此内容的信息,但我不建议启用它,因为这会使您的剧本的行为取决于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_varsgroup_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"
}