将变量传递到包含的剧本

war*_*iuc 4 ansible ansible-2.x

我正在添加我的剧本中的另一本剧本。我需要向它传递一个名为 的变量required_node_version。我在我的剧本中使用相同的变量,因此期望包含的剧本将继承它。但它不会导致“未定义”错误。所以我尝试使用这个不太优雅的解决方案:

- hosts: localhost
  connection: local
  vars:
    required_node_version: v6.3.1

  ...    

- include: ../../base/ci/build.yml
  vars:
    required_node_version: "{{required_node_version}}"
Run Code Online (Sandbox Code Playgroud)

什么导致{"failed": true, "msg": "ERROR! recursive loop detected in template string: {{required_node_version}}"}

有什么优雅的解决方案吗?

Sha*_*a99 6

Ansible 单独维护每个播放的状态。一场戏剧的可变范围也与其他戏剧分开。您可以将戏剧中定义的变量范围视为有向无环图,其中每个节点名称都是唯一的,并且值将在第二次写入时被覆盖。

\n\n

当您在剧本中包含其他一些剧本(包括顶层剧本)时,包含的剧本将具有自己的变量范围,因为它是完全不同的剧本。因此,您\xe2\x80\x99将无法访问 main play 中定义的变量。实际错误不是递归循环检测到的错误,实际错误是变量未定义错误,因为您正在尝试访问在其他播放中定义的变量。

\n\n

尝试这个:

\n\n

主.yml

\n\n
---\n- hosts: all\n  vars:\n    name: shasha\n\n- include: included_playbook.yml\n  vars:\n    name1: "{{name}}""\n
Run Code Online (Sandbox Code Playgroud)\n\n

现在您将得到实际的错误:name is undefined ,因为您在将name分配给name1时尝试从不同范围(不同的玩法)访问变量。

\n\n

现在更改你的main.yml

\n\n

主.yml

\n\n
---\n- hosts: all\n  vars:\n    name: shasha\n\n- include: included_playbook.yml\n  vars:\n    name: shashank\n
Run Code Online (Sandbox Code Playgroud)\n\n

虽然名称被定义了两次,但它们彼此不同,因为两者的范围不同(主要游戏的范围和包含游戏的范围)。所以这工作正常,没有任何问题。

\n\n
\n\n

一些替代解决方案:

\n\n

1. 调用 playbook 时传递变量:

\n\n

由于您包含的剧本也可以作为主剧本运行,在这种情况下,您将如何使用该变量?您可以在该剧本中定义变量,也可以从命令行传递它。

\n\n

当您在调用剧本时传递变量时,它将自动在两个剧本(主剧本以及包含的剧本)的范围内创建该变量:

\n\n
ansible-playbook -i hosts main.yml -e "required_node_version=v6.3.1"\n
Run Code Online (Sandbox Code Playgroud)\n\n

或者,您可以创建一个 JSON 文件,其中包含您所包含的所有剧本中常见的所有公共变量,然后在调用主 ansible 剧本时传递该 JSON 文件。

\n\n

2. 重新设计 Ansible 剧本:

\n\n

如果您包含的 ansible playbook 作为帮助程序而不是以独立方式使用,则您应该在任务级别包含此 playbook。您仍将保持可重用性,并且只有单一作用域,因此您无需担心显式传递变量。

\n\n

更多关于递归循环检测到错误背后的原因:

\n\n

当你将一个变量赋值给另一个变量时,Ansible 实际上并没有使用右值的概念,而是执行两者之间的绑定。例如,您认为以下代码中变量name1的值是多少:

\n\n

主.yml

\n\n
---\n- hosts: all\n  vars:\n   - name: old_val\n   - name1: "{{name}}"\n   - name: new_val\n\n  tasks:\n    - debug: msg="{{name1}}"\n
Run Code Online (Sandbox Code Playgroud)\n\n

如果您的答案是new_val,那么您就理解了逻辑。将name1视为引用,它引用name,而name现在引用 new_val。因此,唯一存在的值是new_value,而name1name只是引用new_value的引用。\n对old_value 的引用丢失。

\n\n

现在考虑下面的脚本:

\n\n

main_recursive.yml

\n\n
---\n- hosts: all\n  vars:\n   - name: shasha\n   - name1: "{{name}}"\n   - name: "{{name1}}"\n\n  tasks:\n    - debug: msg="{{name}}"\n
Run Code Online (Sandbox Code Playgroud)\n\n

现在让我们尝试解析name的值。name指向name1name1指向name。没关系,但是我们如何达到实际值???没办法,这是一个递归循环!

\n