首页 > 解决方案 > 使用相同的变量键名调用 Ansible group_vars、host_vars

问题描述

我有如下库存结构,

[devgroup]
server001
server002

我们在这里要做的是验证这些主机上的挂载点,在上述两台服务器之间有一些常见的挂载点。现在我们决定使用 group_vars 和 host_vars 来满足要求。

group_vars/devgroup.yml
host_vars/server001.yml
        /server002.yml
devgroup.yml has below variables

mounts:
    /a
    /b
server001.yml has
mounts:
    /d
    /e
server002.yml has
mounts:
    /s
    /t

因此,上面的 /a /b 位于两台服务器中,因为每台服务器都有单独的唯一挂载点。那么,现在在我的剧本中如何获得所有变量?根据标准 group_vars 将被 host_vars 覆盖,如果它具有相同的变量(mounts)键名。感谢您对此的帮助。

标签: ansible

解决方案


问:“在我的剧本中,我怎样才能得到所有的变量?”

答:引用 Ansible 配置设置DEFAULT_HASH_BEHAVIOUR

默认情况下,Ansible 将按特定优先顺序覆盖变量,如变量优先级中所述:我应该在哪里放置变量?...一些用户更喜欢将散列变量(在 Python 术语中称为“字典”)合并。此设置称为“合并”。这不是默认行为,它不会影响值为标量(整数、字符串)或数组的变量。我们通常建议不要使用此设置...

问题中的变量不是字典,不能合并。

相反,让我们创建可用于挂载文件系统的字典。例如

shell> cat group_vars/devgroup.yml
mounts:
    a:
      dev: sda1
      mnt: /a
    b:
      dev: sda2
      mnt: /b
shell> cat host_vars/server001.yml
mounts:
    d:
      dev: sda3
      mnt: /d
    e:
      dev: sda4
      mnt: /e
shell> cat host_vars/server002.yml
mounts:
    s:
      dev: sda5
      mnt: /s
    t:
      dev: sda6
      mnt: /t

剧本

shell> cat pb.yml
- hosts: devgroup
  tasks:
    - debug:
        var: mounts

默认情况下,通过host_vars覆盖group_vars并给出

shell> ansible-playbook pb.yml
[...]
ok: [server001] => {
    "mounts": {
        "d": {
            "dev": "sda3", 
            "mnt": "/d"
        }, 
        "e": {
            "dev": "sda4", 
            "mnt": "/e"
        }
    }
}
ok: [server002] => {
    "mounts": {
        "s": {
            "dev": "sda5", 
            "mnt": "/s"
        }, 
        "t": {
            "dev": "sda6", 
            "mnt": "/t"
        }
    }
}

但是使用ANSIBLE_HASH_BEHAVIOUR=merge相同的剧本将字典合并

shell> export ANSIBLE_HASH_BEHAVIOUR=merge
shell> ansible-playbook pb.yml 
[...]
ok: [server001] => {
    "mounts": {
        "a": {
            "dev": "sda1", 
            "mnt": "/a"
        }, 
        "b": {
            "dev": "sda2", 
            "mnt": "/b"
        }, 
        "d": {
            "dev": "sda3", 
            "mnt": "/d"
        }, 
        "e": {
            "dev": "sda4", 
            "mnt": "/e"
        }
    }
}
ok: [server002] => {
    "mounts": {
        "a": {
            "dev": "sda1", 
            "mnt": "/a"
        }, 
        "b": {
            "dev": "sda2", 
            "mnt": "/b"
        }, 
        "s": {
            "dev": "sda5", 
            "mnt": "/s"
        }, 
        "t": {
            "dev": "sda6", 
            "mnt": "/t"
        }
    }
}

推荐阅读