ansible:在剧本中用不同的变量调用相同的角色

ansible:在剧本中用不同的变量调用相同的角色,ansible,Ansible,我试图从一个独特的剧本中控制同一角色n次呼叫n个不同的变量: --- - hosts: myhost vars: user: user1 virtualenv: venv_nameV3 roles: - makeuser - stack # use virtualenv var so stack role is installed in venv_nameV3 - stack # should need it's own virtu

我试图从一个独特的剧本中控制同一角色n次呼叫n个不同的变量:

---
- hosts: myhost
  vars:
    user: user1
    virtualenv: venv_nameV3
  roles:
    - makeuser
    - stack  # use virtualenv var so stack role is installed in venv_nameV3      
    - stack  # should need it's own virtualenv value e.g. venv_nameV4
    - stack  # should need it's own virtualenv value e.g. venv_nameV5
    - stack  # should need it's own virtualenv value e.g. venv_nameV6

您可以通过使用以下语法添加变量来参数化角色

---
- hosts: myhost
  vars:
    user: user1
    virtualenv: default_venv_name
  roles:
    - makeuser
    - { role: stack, virtualenv: 'venv_nameV3' }
    - { role: stack, virtualenv: 'venv_nameV4' }
    - { role: stack, virtualenv: 'venv_nameV5' }
    - { role: stack, virtualenv: 'venv_nameV6' }

您无法插入适当的代码块作为注释,因此以下是用纯YAML而不是JSON编写的公认答案:

我最初的答案不正确。下面是正确的答案:

---

- hosts: myhost
  vars:
    user: user1
    virtualenv: default_venv_name
  roles:
    - makeuser
    - role: stack
      virtualenv: venv_nameV3
    - role: stack
      virtualenv: venv_nameV4
    - role: stack
      virtualenv: venv_nameV5
    - role: stack
      virtualenv: venv_nameV6
---

- hosts: myhost
  vars:
    user: user1
    virtualenv: default_venv_name
  roles:
    - makeuser
    - role: stack
      vars:
        virtualenv: venv_nameV3
    - role: stack
      vars:
        virtualenv: venv_nameV4
    - role: stack
      vars:
        virtualenv: venv_nameV5
    - role: stack
      vars:
        virtualenv: venv_nameV6
原始答案:

---

- hosts: myhost
  vars:
    user: user1
    virtualenv: default_venv_name
  roles:
    - makeuser
    - role: stack
      virtualenv: venv_nameV3
    - role: stack
      virtualenv: venv_nameV4
    - role: stack
      virtualenv: venv_nameV5
    - role: stack
      virtualenv: venv_nameV6
---

- hosts: myhost
  vars:
    user: user1
    virtualenv: default_venv_name
  roles:
    - makeuser
    - role: stack
      vars:
        virtualenv: venv_nameV3
    - role: stack
      vars:
        virtualenv: venv_nameV4
    - role: stack
      vars:
        virtualenv: venv_nameV5
    - role: stack
      vars:
        virtualenv: venv_nameV6
虽然它们只是略有不同,但它们改变了Ansible处理默认变量的方式(在
defaults/main.yml
中定义):

如果在剧本中包含角色时遗漏了一个变量,Ansible将使用同一角色上一次运行中的变量(“变量出血”)

在接受答案的上下文中,当在最后一次调用
stack
角色时未设置
virtualenv:venv\u nameV6
时,
virtualenv
将具有
venv\u nameV5
(从上一次调用
stack
角色)的值,无论角色的
defaults/main.yml
文件中设置了什么
virtualenv

如果您像我在正确答案中那样调用您的角色,您角色的
defaults/main.yml
文件将得到尊重,
virtualenv
将被设置为您定义为默认的任何文件


有点小差别,但很难找到。

有没有非json的方法?我试着用一些做实验,但没有用。Json样式还可以,但在剧本中感觉有点难看。@fquinner您无法插入适当的代码块作为注释,因此我创建了一个单独的答案。我可以为同一角色包含不同的文件吗?抱歉,虽然您通常没有错,但此答案中的描述看起来不完整,实际上具有误导性。请再做一些测试。・・・总的来说,这不是问题所在——你试着回答——然后发现你自己的答案有缺陷——如果你刚刚替换了它,就可以了,但是你开始解释为什么你错了——而且这个描述远远不正确。・・・例如:检查如果删除
vars:
不是从上一个声明中,而是从上一个声明中删除,而保留上一个声明-它仍然是“从上一个调用中”会发生什么?谢谢您的评论。你是对的,这不是问题所在。我添加了一个专用的答案,因为无法正确格式化注释中的代码块(换行符被删除)。这就是为什么我评论了这个被接受的答案,并以“…这里是用纯YAML而不是JSON编写的被接受的答案”开始我自己的回答。至于实际的答案:如果你能指出到底是什么错了,而不是让我弄明白,如果你已经知道的话,那就太好了——我很乐意编辑它。这就是我想要的解释。。“可变出血”!!