首页 文章

Ansible变量覆盖默认为另一个角色

提问于
浏览
5

我不确定如何在Ansible中的角色之间覆盖变量 .

为了简化设置,我将两个角色应用于同一主机 . 第一个角色在 default/main.yml 中定义一个变量:

do_some_task: yes

并在其任务中查找该变量:

- name: Some Task
  when: do_some_task

第二个角色覆盖了 vars/main.yml 中的那个,它应该优先于默认值:

do_some_task: no

但是,该任务仍在运行,表明该变量未被覆盖 . 似乎覆盖范围限定为第二个角色的任务 . 我通过向两个角色添加调试任务来测试它:

- name: Test some task
  debug: "msg='do_some_task = {{ do_some_task }}'"

这证实了第一个角色看到的变量值与第二个角色不同 .

TASK: [role1 | Test some task]
ok: [myhost] => {
    "msg": "do_some_task = True" 
}

...

TASK: [role2 | Test some task]
ok: [myhost] => {
    "msg": "do_some_task = False" 
}

对此的常见答案似乎是在库存或主机变量中设置变量 . 然而,这不是特别干:如果你有不同库存的许多主机,你必须在很多地方设置相同的变量 .

那么是否有某种方法可以覆盖另一个角色的变量?

2 回答

  • 0

    如果你使用Ansible> = 2.2,你可以使用 include_roles

    - name: Pass variables to role
        include_role:
        name: role1
        vars:
           do_some_task: "{{ role2_do_some_task }}"
    

    您还可以使用Anslbie> = 1.3的角色依赖项 . 写 role2/meta/main.yml 如:

    ---
      dependencies:
      - { role: role1, do_some_task: yes }
    

    如果你不想要,既然你不想把变量定义放在playbook中,定义它们的唯一合理的地方是库存 .

    您可以定义需要在同一组中覆盖role1默认值的那些:

    [overwrite_do_some_task]
      host1
      host3
    
      [overwrite_do_some_task:vars]
      do_some_task=yes
    

    如果在运行role1之前没有给出变量值,那么预期的行为是,使用角色default,这是OP观察到的 .

    注意:为角色变量添加前缀更具可读性 . 即使用 role1_do_some_task 而不是 do_some_task . 这样做,你不太可能混淆自己 . 见Ansible Best Practices: The Essentials .

  • 1

    如果要将角色包装为另一个角色,则可以通过从外部角色专门传递变量来覆盖内部角色的变量 .

    因此,根据您的示例,您将拥有以下内部角色任务:

    - name: Some Task
      when: do_some_task
    

    这个内部角色有一个像这样的变量集:

    do_some_task: true
    

    然后,当你在这样的剧本中调用你的外部角色时,你可以覆盖内部角色:

    - name: outer-role
      hosts: outer-role-nodes
      roles:
        -   role: outer-role
        - { role: inner role,
            do_some_task: "{{ do_some_task }}" }
    

    这应该从外部角色获取 do_some_task 变量并覆盖内部角色的 do_some_task .

相关问题