Ansible group_vars 变量优先级(group_vars 覆盖其他 group_vars)

Ansible group_vars 变量优先级(group_vars 覆盖其他 group_vars)

在 Ansible 2.2 上,

我有一个 Ansible 主机文件:

[webserver]
aegir.dev

[hostmaster]
aegir.dev

我有两个group_vars/文件:

# group_vars/webserver.yml
my_var:
  - vagrant

# group_vars/hostmaster.yml
my_var:
  - vagrant
  - aegir

剧本如下:

- hosts: webserver
  tasks:
    - debug: var=my_var

- hosts: hostmaster
  tasks:
    - debug: var=my_var

输出:

PLAY [webserver] ***************************************************************

TASK [setup] *******************************************************************
ok: [aegir.dev]

TASK [debug] *******************************************************************
ok: [aegir.dev] => {
    "my_var": [
        "vagrant",
        "aegir"
    ]
}

PLAY [hostmaster] **************************************************************

TASK [setup] *******************************************************************
ok: [aegir.dev]

TASK [debug] *******************************************************************
ok: [aegir.dev] => {
    "my_var": [
        "vagrant",
        "aegir"
    ]
}

为什么webserver和都hostmaster使用来自的变量hostmaster.yml

可能我使用方式不group_vars正确,但我该如何解决这个问题呢?

编辑

实际情况是,我在两个组上运行相同的角色,一个组webserver实际上包含 4 个通用服务器,另一个hostmaster组是同一角色上的 Web 服务器 + 额外配置(用户 aegir 仅存在于 aegir.dev 上,而不存在于其他 3 个 Web 服务器上)

答案1

这个问题有点老了,但是提到的问题已经存在,所以我把我的答案写给了需要答案的人。

实际上,基于文档,Ansible 专注于主机和任务,因此组实际上在清单和主机匹配之外不存在。为了解决这个问题,我们需要为组的变量添加前缀(就像使用命名空间来避免冲突一样)。

# inventory/hosts.yml
webservers:
  hosts:
    host1:
    host2:
  vars:
    webserver_my_var: ...

hostmaster:
  hosts:
    host1:
  vars:
    hostmaster_my_var: ...

并且在剧本中,您可以安全地使用该变量。

# playbooks/main.yml
- hosts: webserver
  tasks:
    - debug: var=webserver_my_var | mandatory

- hosts: hostmaster
  tasks:
    - debug: var=hostmaster_my_var | mandatory

这样您就可以安全地消除问题。

在多个组中使用相同的变量名还有另一个问题。仅通过查看清单很难猜测变量的值,您需要了解组之间的关系以及一个组与另一个组的顺序/优先级,这项工作很辛苦,而且容易出错。

答案2

这是预期行为。请参阅文档

在任何部分内,重新定义变量将覆盖前一个实例。如果多个组具有相同的变量,则最后加载的组获胜。如果您在剧本的 vars: 部分中定义同一个变量两次,则第二次的变量有效。

相关内容