Ansible忽略嵌套的host_vars

时间:2015-12-12 04:52:10

标签: ansible ansible-playbook

我有以下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不起作用时不起作用?

1 个答案:

答案 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!"
        }
    }
}