首页 > 解决方案 > Ansible:在角色执行时应用标签

问题描述

我试图明确地了解标签是如何在 Ansible 中的角色执行中应用的

我在https://docs.ansible.com/ansible/latest/user_guide/playbooks_tags.html#adding-tags-to-roles阅读了文档并尝试了一个测试角色

 ~/ansible/roles/internal/test/tasks > cat tag-foo.yml
---
- import_tasks: tag-foo.yml
  tags:
    - foo
    - foo2

- import_tasks: tag-bar.yml
  tags:
    - bar

- import_tasks: always.yml
  tags:
    - always

- import_tasks: never.yml
  tags:
    - never
    - nevermind

 ~/ansible/roles/internal/test/tasks > cat tag-foo.yml
---
- name: This is tag 'foo'
  debug:
    msg: This is tag 'foo'

 ~/ansible/roles/internal/test/tasks > cat tag-bar.yml
---
- name: This is tag 'bar'
  debug:
    msg: This is tag 'bar'

 ~/ansible/roles/internal/test/tasks > cat always.yml
---
- name: This is tag 'always'
  debug:
    msg: This is tag 'always'

 ~/ansible/roles/internal/test/tasks > cat never.yml
---
- name: This is tag 'never'
  debug:
    msg: This is tag 'never'

我创建了一个测试剧本文件:

 ~/ansible > cat plays/test.yml
- hosts: all

  tasks:
    - name: Execute test role with all tags
      import_role:
        name: test
      tags: foo2

    - name: Execute test role with tag 'foo'
      import_role:
        name: test
      tags:
        - foo

我不明白的是,如果我使用 foo 标签执行剧本,则该角色会执行两次,而不仅仅是一次仅执行来自tag-foo.yml和的任务tag-always.yml

 ~/ansible > ansible-playbook -i test.ini plays/test.yml -l test.domain.local -t foo

PLAY [all] ********************************************************************************************************************************************

TASK [Gathering Facts] ********************************************************************************************************************************
ok: [test.domain.local]

TASK [test : This is tag 'foo'] ***********************************************************************************************************************
ok: [test.domain.local] => {
    "msg": "This is tag 'foo'"
}

TASK [test : This is tag 'always'] ********************************************************************************************************************
ok: [test.domain.local] => {
    "msg": "This is tag 'always'"
}

TASK [test : This is tag 'foo'] ***********************************************************************************************************************
ok: [test.domain.local] => {
    "msg": "This is tag 'foo'"
}

TASK [test : This is tag 'bar'] ***********************************************************************************************************************
ok: [test.domain.local] => {
    "msg": "This is tag 'bar'"
}

TASK [test : This is tag 'always'] ********************************************************************************************************************
ok: [test.domain.local] => {
    "msg": "This is tag 'always'"
}

TASK [test : This is tag 'never'] *********************************************************************************************************************
ok: [test.domain.local] => {
    "msg": "This is tag 'never'"
}

PLAY RECAP ********************************************************************************************************************************************
test.domain.local           : ok=7    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

我想要的是从单个语句中强制标记import_role,而不必在ansible-playbook命令中指定它。

编辑:我尝试将import_role语句替换include_role为剧本,添加apply应用foo标签的选项:

- name: Execute test role with tag 'foo'
  include_role:
    name: test
    apply:
      tags:
        - foo

我将角色文件中的import_tasks语句替换为:main.ymlinclude_tasks

---
- include_tasks: tag-foo.yml
  tags:
    - foo
    - foo2

- include_tasks: tag-bar.yml
  tags:
    - bar

- include_tasks: always.yml
  tags:
    - always

- include_tasks: never.yml
  tags:
    - never
    - nevermind

但不幸的是,没有任何改变:“bar”任务无论如何都会执行:

 ~/ansible > ansible-playbook -i test.ini plays/test.yml -l test.domain.local

PLAY [all] ********************************************************************************************************************************************

TASK [Gathering Facts] ********************************************************************************************************************************
ok: [test.domain.local]

TASK [Execute test role with tag 'foo'] ***************************************************************************************************************

TASK [test : include_tasks] ***************************************************************************************************************************
included: /Users/me/ansible/roles/internal/test/tasks/tag-foo.yml for test.domain.local

TASK [test : This is tag 'foo'] ***********************************************************************************************************************
ok: [test.domain.local] => {
    "msg": "This is tag 'foo'"
}

TASK [test : include_tasks] ***************************************************************************************************************************
included: /Users/me/ansible/roles/internal/test/tasks/tag-bar.yml for test.domain.local

TASK [test : This is tag 'bar'] ***********************************************************************************************************************
ok: [test.domain.local] => {
    "msg": "This is tag 'bar'"
}

TASK [test : include_tasks] ***************************************************************************************************************************
included: /Users/me/ansible/roles/internal/test/tasks/always.yml for test.domain.local

TASK [test : This is tag 'always'] ********************************************************************************************************************
ok: [test.domain.local] => {
    "msg": "This is tag 'always'"
}

PLAY RECAP ********************************************************************************************************************************************
test.domain.local           : ok=7    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

标签: ansibleansible-role

解决方案


通过 using import_role,它是静态重用,标签不作为导入的条件,而是添加到导入角色的每个任务中。

要使用标签来调节角色的执行,您应该使用带有include_role.

有关导入的更多文档包括:https ://docs.ansible.com/ansible/latest/user_guide/playbooks_reuse.html#re-using-files-and-roles

标签机制是通过 CLI 设置的。如果您想通过剧本定义角色的不同行为,vars并且when是更好的选择:

- include_role: my_role
  vars:
     only_foo: True

# in my_role:
- debug:
     msg: Only on foo
  when: only_foo

推荐阅读