Ansible,如何自定义主机组变量优先级?

一般情况下,Ansible 的变量加载顺序是固定的,那么在同一优先级下,如何指定某一变量的优先级呢?

变量的默认加载顺序如下:

  • roles defaults目录下的变量
  • 组变量:inventory 文件
  • 组变量:inventory/group_vars/all
  • 组变量:playbook/group_vars/all
  • 组变量:inventory/group_vars/*
  • 组变量:playbook/group_vars/*
  • 主机变量:inventory 文件
  • 主机变量:inventory/group_vars/*
  • 主机变量:playbook/group_vars/*
  • facts变量
  • play变量:vars定义的
  • play变量:vars_prompt定义的
  • play变量:vars_files导入的
  • roles vars目录下的变量
  • block中task定义的变量
  • playbook中task定义的变量
  • include_vars导入的变量
  • set_facts/register注册的变量
  • 使用roles/include_role/import_role语句时定义的变量
  • 使用include语句(ansible旧版本)时定义的变量
  • 命令行-e参数指定的额外变量(优先级最高)

可以看出,Ansible 的变量可以定义的地方居多

这里针对变量的顺序定义我们不再进行实验。

我们只说一种场景,一个主机 host1,即属于主机组 a_group,又属于 b_group。

好巧不巧,两个主机组定义了同一个变量:

1
2
3
4
a_group:
testvar: a
b_group:
testvar: b

默认情况下,最后一个加载的组的变量,会覆盖之前的,也就是默认情况下,此时 testvar 应该为 a。

我们做下实验。

实验

定义清单文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
node1 ansible_host=110.182.137.8

[a_group]
node1

[a_group:vars]
testvar=a

[b_group]
node1

[b_group:vars]
testvar=b

[all:vars]
ansible_ssh_user=test
ansible_ssh_pass=test

运行测试命令:

1
2
3
4
5
$ ansible -i tests node1 -m debug -a "var=testvar"
node1 | SUCCESS => {
"changed": false,
"testvar": "b"
}

可以看出,后加载的 b_group 的变量,覆盖了 a_group 的变量。

那么,主机组加载顺序是否和在文件中定义的顺序有关呢?

我们修改一下清单文件,将 a_group 的位置放在后面:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
node1 ansible_host=110.182.137.8

[b_group]
node1

[b_group:vars]
testvar=b

[a_group]
node1

[a_group:vars]
testvar=a

[all:vars]
ansible_ssh_user=test
ansible_ssh_pass=test

再次运行测试命令:

1
2
3
4
5
$ ansible -i tests node1 -m debug -a "var=testvar"
node1 | SUCCESS => {
"changed": false,
"testvar": "b"
}

可以看出,仍然是 b_group 的优先级较高。

也就是说,主机组是安装字母顺序进行加载的(猜测结论)。

这里,如果,我们想要提高 a_group 的优先级,该如何处理呢?

这里就需要 ansible_group_priority 变量出厂了。

默认情况下,ansible_group_priority 的权重都是 1,那么只要将某个主机组的 ansible_group_priority 大于 1,即可提升其优先级。

比如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
node1 ansible_host=110.182.137.8

[b_group]
node1

[b_group:vars]
testvar=b

[a_group]
node1

[a_group:vars]
testvar=a
ansible_group_priority=2

[all:vars]
ansible_ssh_user=test
ansible_ssh_pass=test

再次运行测试命令:

1
2
3
4
5
$ ansible -i tests node1 -m debug -a "var=testvar"
node1 | SUCCESS => {
"changed": false,
"testvar": "a"
}

可以看出,此时 a_group 的变量覆盖掉了 b_group 的变量。

结论

可以使用变量 ansible_group_priority 来设置某个主机组变量的优先级,ansible_group_priority 默认为 1,数值越大,代表优先级越高。


参考:

  1. https://docs.ansible.com/ansible/latest/user_guide/intro_inventory.html#how-we-merge
  2. https://www.cnblogs.com/mauricewei/p/10054300.html
hoxis wechat
一个脱离了高级趣味的程序员,关注回复1024有惊喜~
赞赏一杯咖啡
  • 本文作者: hoxis | 微信公众号【不正经程序员】
  • 本文链接: https://hoxis.github.io/ansible-vars-priority.html
  • 版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 3.0 许可协议。转载请注明出处!
  • 并保留本声明和上方二维码。感谢您的阅读和支持!
0%