Ansible:如何通过专用标签引入角色并控制任务执行范围
我有一个用于新虚拟机基础配置的os-base角色,计划在os-base/tasks/main.yml中通过标签引入certificates角色,配置如下:
- name: Copy CA certificates to prevent MITM issues ansible.builtin.include_role: name: certificates apply: tags: - ca - wildcards tags: - ca
预期通过标签仅运行os-base引入的certificates角色中指定标签的任务,但实际执行时,certificates角色的所有任务(包括带never标签的任务)都会被执行。
certificates/tasks/main.yml
- name: Import always executed block of tasks ansible.builtin.import_role: name: commons tasks_from: always_block - name: Install root CA certificates ansible.builtin.import_tasks: file: _deploy_ca_certs.yml tags: ca - name: Install pair of private key, and certificate ansible.builtin.import_tasks: file: _deploy_keypair.yml tags: certs - name: Install wildcard pair ansible.builtin.import_tasks: file: _deploy_wildcard.yml tags: wildcard - name: Install pair of private key, and certificate for IDM ansible.builtin.import_tasks: file: _deploy_keypair_idm.yml tags: [ idm, never ]
commons/always_block(辅助任务)
- name: Display summary ansible.builtin.pause: seconds: 0 prompt: |- ──────────────────────────────────────────────────────────────────────────────────────────────────── parent_role_names: {{ ansible_parent_role_names | join(' -> ') }} role_name: {{ role_name }} ansible_distribution: {{ ansible_distribution }}{{ ansible_distribution_major_version }} ansible_os_family: {{ ansible_os_family }} ansible_user: {{ ansible_user }} become_user: {{ become_user | default('not set') }} target: {{ target | default(t) }} -> {{ target | default(t) | expand_groups(hostvars, groups) | join(', ') }} tags: {{ ansible_run_tags | join(',') }} skip_tags: {{ ansible_skip_tags | join(',') }} group_names: {{ group_names | join(', ') }} ────────────────────────────────────────────────────────────────────────────────────────────────────
执行以下命令时:
ansible-playbook playbooks/os-base.yml -e t=node1 ansible-playbook playbooks/os-base.yml -e t=node1 -t ca
ansible_run_tags的值为all或命令行-t指定的ca,不受include_role中apply: tags的影响,导致certificates角色所有任务(包括带never标签的_deploy_keypair_idm.yml)全部执行。
但直接运行certificates角色时,标签过滤正常:
ansible-playbook playbooks/certificates.yml -e t=node13 -t ca,wildcard
注:环境变量
t|target用于指定目标主机,替代主机清单,每个剧本对应roles目录下的专属角色。
include_role的apply: tags参数是给被引入角色的所有任务新增指定标签,而非过滤任务。这会导致certificates角色的所有任务都被添加上ca和wildcards标签,当命令行指定-t ca时,所有任务都匹配该标签,因此全部执行。同时,never标签的逻辑是“未指定任何运行标签时跳过”,一旦命令行指定了标签,never的跳过规则会被覆盖,带never的任务也会执行。
去掉include_role中的apply配置,仅保留角色调用的触发标签,让certificates角色内的任务通过自身原有标签与命令行指定标签匹配:
修改os-base/tasks/main.yml为:
- name: Copy CA certificates to prevent MITM issues ansible.builtin.include_role: name: certificates tags: - ca
执行效果
- 执行
ansible-playbook playbooks/os-base.yml -e t=node1 -t ca时,include_role被触发,certificates角色内只有带ca标签的任务(Install root CA certificates)会执行,其他任务(包括带never标签的IDM任务)因未匹配标签被跳过。 - 如果需要同时执行
ca和wildcard标签的任务,只需修改命令行:
ansible-playbook playbooks/os-base.yml -e t=node1 -t ca,wildcard
此时certificates角色内带ca和wildcard标签的任务会执行,其余任务被跳过。
内容的提问来源于stack exchange,提问作者piecia

