我有以下Ansible设置:
playbook.yml
---
- hosts: all
sudo: true
vars_files:
- vars/all.yml
tasks:
- debug: msg="foo.bar = {{ foo.bar if foo.bar is defined else False }}"
- debug: msg="foo_bar = {{ foo_bar if foo_bar is defined else False }}"
乏/ all.yml
---
foo:
greeting: "Hello, world!"
主机/生产
production ansible_ssh_host=xxx.xxx.xxx.xxx ansible_ssh_user=root
host_vars /生产
---
foo:
bar: baz
foo_bar: baz
当我运行ansible-playbook -i hosts/production playbook.yml
时,我得到以下结果:
TASK: [debug msg="foo.bar = {{ foo.bar if foo.bar is defined else False }}"] ***
ok: [production] => {
"msg": "foo.bar = False"
}
TASK: [debug msg="foo_bar = False"] *******************************
ok: [production] => {
"msg": "foo_bar = baz"
}
为什么我的嵌套主机var foo.bar
在顶级主机var foo_bar
不起作用时不起作用?
答案 0 :(得分:2)
Ansible与散列(字典)一起使用的默认行为不是合并它们,而是用更具体的散列替换低优先级散列变量。因此主机变量赢得了组变量,并且用vars:
声明的额外变量赢得了这两个变量。 Full details here
所以实际上,当你添加" Hello world"在包含的变量文件中,您将消除主机变量中的foo
字典。您可以通过添加调试来打印整个哈希来看到这一点:
tasks:
- debug: msg="foo.bar = {{ foo.bar if foo.bar is defined else False }}"
- debug: msg="foo_bar = {{ foo_bar if foo_bar is defined else False }}"
- debug: var=foo
这增加了这个有用的输出:
TASK: [debug var=foo] *********************************************************
ok: [vagrantbox] => {
"var": {
"foo": {
"greeting": "Hello, world!"
}
}
}
PLAY RECAP ********************************************************************
vagrantbox : ok=4 changed=0 unreachable=0 failed=0
如果需要在foo
中组合不同的值,可以使用Jinja组合过滤器,或创建本地ansible.cfg并设置hash_behaviour变量进行合并。
我发现合并哈希对于使用Ansible管理大量服务器是完全必要的,Ansible official docs建议不要使用它,除非您认为自己绝对需要它,否则#39;。取决于你的用例,我想!但是它会准确地给出你的帖子所期望的结果:
TASK: [debug msg="foo.bar = {{ foo.bar if foo.bar is defined else False }}"] ***
ok: [vagrantbox] => {
"msg": "foo.bar = baz"
}
TASK: [debug msg="foo_bar = False"] *******************************************
ok: [vagrantbox] => {
"msg": "foo_bar = baz"
}
TASK: [debug var=foo] *********************************************************
ok: [vagrantbox] => {
"var": {
"foo": {
"bar": "baz",
"greeting": "Hello, world!"
}
}
}