Ansible变量的值不一致

Ansible变量的值不一致,ansible,Ansible,在过去的几天里,我一直在和ansible玩游戏,并且遇到了一种对我来说毫无意义的行为。我可以用一个简单的剧本来重现这一点,剧本中有两个角色。每个角色设置一个变量,然后导入一系列其他角色。其他角色什么也不做,只是打印变量的值,然后导入链中的下一个角色。我得到的结果是: $ansible playbook site.yml "msg": "role_1a v1 = role_1a default" "msg": "role_2 v1 = role_1a default" "msg": "role_3

在过去的几天里,我一直在和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"
问:“很显然,其他人似乎都能毫无问题地使用变量,我更倾向于相信,在这一过程中,我遗漏了一些基本概念。”

A:不幸的是,情况并非如此。很可能这是一个不可回答的问题。有一打。其中一些提醒了这里描述的问题


我能够重现报告的结果。戏

- hosts: localhost
  roles:
    - role_1a
    - role_1b
给予

让我们确保消息的顺序是正确的。改变任务(类似角色1、2、3、4)

给予

如期而至

    "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 }}"
不定义变量
v1
。此语句仅根据需要计算变量
v1
。引述自:

惰性评估:通常,Ansible会在最后一秒对playbook内容中的任何变量进行评估,这意味着如果您定义了一个数据结构,那么该数据结构本身就可以定义其中的变量值,并且一切都如您所期望的那样“正常工作”。这也意味着变量字符串可以在这些字符串中包含其他变量

由于所有角色都已导入,因此角色顺序的更改也应获得相同的结果

- hosts: localhost
  roles:
    - role_1b
    - role_1a
给予


解决了这个问题。

不是答案,但我快速测试了这个问题,我相信您关于解析默认值的假设是绝对正确的。将
role_1b
default中的变量更改为
v2
会使其“按预期工作”。我对该解释有困难的原因有两个:1。我很难想象一个合理的解析顺序会产生这个输出。2.在我看来,这会使ansible变量变得无用。在发布问题之前,我进行了广泛的搜索,没有发现任何与之类似的东西。正因为如此,而且很明显,其他人似乎都能够毫无问题地使用变量,我更倾向于相信,在这一过程中,我遗漏了一些基本概念。感谢您提供的链接和示例。我从中得到的是,我不能对通用角色使用默认值/变量,这是出于设计。当然可以,但可以对它们进行名称空间设置,以避免冲突。我不确定名称空间的含义。如果您能给出一个小示例或至少描述如何将它们应用于此问题,这将非常有用。名称空间意味着向主机“注册”变量,即将变量放入hostvars中。例如,set_fact:v1=“{v1}}”解决了这个问题,所以这两种解决方法的行为都与我最初预期的一样。我甚至可以通过将defaults/main.yml移动到tasks/defaults.yml,并将set_fact置于顶部,然后将其导入到角色中,从而相对干净地完成第二个任务。问题是,这增加了优先级,我不能再使用库存或组变量重写。至于术语表项,我不清楚赋值时绑定变量会如何阻止做同样的事情。无论如何,这不太可能改变,我想我现在只是在抱怨,所以我真的只想感谢你的帮助。
    "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"
# 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"
- debug: msg="role_1a v1 = {{ v1 }}"
- 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"