gpt4 book ai didi

Ansible 变量的值不一致

转载 作者:行者123 更新时间:2023-12-02 02:39:42 25 4
gpt4 key购买 nike

过去几天我一直在使用 ansible,并且遇到了一种对我来说毫无意义的行为。我可以用一个运行两个角色的简单剧本来重现这一点。每个角色设置一个变量,然后导入一系列其他角色。其他角色什么也不做,只是打印出变量的值,然后导入链中的下一个角色。我得到的输出是:

$ ansible-playbook site.yml

"msg": "role_1a v1 = role_1a default"
"msg": "role_2 v1 = role_1a default"
"msg": "role_3 v1 = role_1a default"
"msg": "role_4 v1 = role_1b default" <=== expected role_1a default
"msg": "role_5 v1 = role_1b default" <=== expected role_1a default

"msg": "role_1b v1 = role_1b default"
"msg": "role_2 v1 = role_1b default"
"msg": "role_3 v1 = role_1a default" <=== expected role_1b default
"msg": "role_4 v1 = role_1b default"
"msg": "role_5 v1 = role_1b default"

我现在已经阅读了大约二十遍关于变量的部分,我能看到的唯一可能与此相关的是“自从 Ansible 2.7 中定义的变量和角色的默认值是在剧本解析时暴露”,我想这可能意味着执行时的变量继承是一个错误。

# site.yml
- hosts: testserver
roles:
- role_1a
- role_1b

# roles/role_1a/defaults/main.yml
v1: "role_1a default"

# roles/role_1a/tasks/main.yml
- debug: msg="role_1a v1 = {{ v1 }}"
- import_role: name=role_2

# roles/role_2/tasks/main.yml
- debug: msg="role_2 v1 = {{ v1 }}"
- import_role: name=role_3

# roles/role_3/tasks/main.yml
- debug: msg="role_3 v1 = {{ v1 }}"
- import_role: name=role_4

# roles/role_4/tasks/main.yml
- debug: msg="role_4 v1 = {{ v1 }}"
- import_role: name=role_5

# roles/role_5/tasks/main.yml
- debug: msg="role_5 v1 = {{ v1 }}"

# roles/role_1b/defaults/main.yml
v1: "role_1b default"

# roles/role_1b/tasks/main.yml
- debug: msg="role_1b v1 = {{ v1 }}"
- import_role: name=role_2

# hosts
[testing]
testserver

# /etc/ansible/ansible.cfg
[defaults]
[inventory]
[privilege_escalation]
[paramiko_connection]
[ssh_connection]
[persistent_connection]
[accelerate]
[selinux]
[colors]
[diff]

$ ansible --version
ansible 2.9.3
config file = /etc/ansible/ansible.cfg
configured module search path = [u'/home/joe/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
ansible python module location = /usr/lib/python2.7/site-packages/ansible
executable location = /usr/bin/ansible
python version = 2.7.5 (default, Aug 7 2019, 00:51:29) [GCC 4.8.5 20150623 (Red Hat 4.8.5-39)]
re

最佳答案

Q: "The fact that apparently everyone else seems to be able to use variables without issues, I am more inclined to believe that there is some fundamental concept I missed along the way."

答:不幸的是,情况并非如此。很可能是 Ansible 问题。有十几个include and import issues 。其中一些提醒这里描述的问题

<小时/>我能够重现报告的结果。剧情

- hosts: localhost
roles:
- role_1a
- role_1b

给出

    "msg": "role_1a v1 = role_1a default"
"msg": "role_2 v1 = role_1a default"
"msg": "role_3 v1 = role_1a default"
"msg": "role_4 v1 = role_1b default"
"msg": "role_5 v1 = role_1b default"
"msg": "role_1b v1 = role_1b default"
"msg": "role_2 v1 = role_1b default"
"msg": "role_3 v1 = role_1a default"
"msg": "role_4 v1 = role_1b default"
"msg": "role_5 v1 = role_1b default"

让我们确保消息的顺序正确。更改的任务(类似role_1a,2,3,4)

# roles/role_1b/tasks/main.yml
- debug: msg="role_1b v1 = {{ v1 }}"
- import_role:
name: role_2
vars:
root: "role_1b"

# roles/role_5/tasks/main.yml
- debug: msg="root = {{ root }} | role_5 v1 = {{ v1 }}"

给予

    "msg": "role_1a v1 = role_1a default"
"msg": "root = role_1a | role_2 v1 = role_1a default"
"msg": "root = role_1a | role_3 v1 = role_1a default"
"msg": "root = role_1a | role_4 v1 = role_1b default"
"msg": "root = role_1a | role_5 v1 = role_1b default"
"msg": "role_1b v1 = role_1b default"
"msg": "root = role_1b | role_2 v1 = role_1b default"
"msg": "root = role_1b | role_3 v1 = role_1b default" <=== was: role_1a default
"msg": "root = role_1b | role_4 v1 = role_1b default"
"msg": "root = role_1b | role_5 v1 = role_1b default"

这表明消息的​​顺序是正确的。但是,结果却发生了变化。现在 role_1b 的结果符合预期。

<小时/>

Q: "Namespace the variables to avoid conflicts. What is namespacesing?"

A:“命名空间”的意思是“定义变量”,特别是“向主机注册变量”,即将变量放入hostvars中。例如

# roles/role_1a/tasks/main.yml
- set_fact:
v1: "{{ v1 }}"
- debug: msg="role_1a v1 = {{ v1 }}"
- import_role:
name: role_2
vars:
root: "role_1a"

符合预期

    "msg": "role_1a v1 = role_1a default"
"msg": "root = role_1a | role_2 v1 = role_1a default"
"msg": "root = role_1a | role_3 v1 = role_1a default"
"msg": "root = role_1a | role_4 v1 = role_1a default"
"msg": "root = role_1a | role_5 v1 = role_1a default"
"msg": "role_1b v1 = role_1a default"
"msg": "root = role_1b | role_2 v1 = role_1a default"
"msg": "root = role_1b | role_3 v1 = role_1a default"
"msg": "root = role_1b | role_4 v1 = role_1a default"
"msg": "root = role_1b | role_5 v1 = role_1a default"

因为一旦变量v1在付款簿范围内定义,就不需要寻找默认值。需要注意的是

- debug: msg="role_1a v1 = {{ v1 }}"

undefined variable v1。该语句仅根据需要计算变量v1。引用自Ansible Glosary :

Lazy Evaluation: In general, Ansible evaluates any variables in playbook content at the last possible second, which means that if you define a data structure that data structure itself can define variable values within it, and everything “just works” as you would expect. This also means variable strings can include other variables inside of those strings.

更改角色的顺序应该会获得相同的结果,因为所有角色都已导入。

- hosts: localhost
roles:
- role_1b
- role_1a

给出

    "msg": "role_1b v1 = role_1b default" <=== expected role_1a default
"msg": "root = role_1b | role_2 v1 = role_1b default" <=== expected role_1a default
"msg": "root = role_1b | role_3 v1 = role_1b default" <=== expected role_1a default
"msg": "root = role_1b | role_4 v1 = role_1a default"
"msg": "root = role_1b | role_5 v1 = role_1a default"
"msg": "role_1a v1 = role_1a default"
"msg": "root = role_1a | role_2 v1 = role_1a default"
"msg": "root = role_1a | role_3 v1 = role_1a default"
"msg": "root = role_1a | role_4 v1 = role_1a default"
"msg": "root = role_1a | role_5 v1 = role_1a default"

这表明所有角色可能都需要“命名空间”。例如

# roles/role_1b/tasks/main.yml
- set_fact:
v1: "{{ v1 }}"
- debug: msg="role_1b v1 = {{ v1 }}"
- import_role:
name: role_2
vars:
root: "role_1b"

解决这个问题。

关于Ansible 变量的值不一致,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60420127/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com