标签
如果您有一个大型剧本,可能需要只运行剧本的特定部分,而不是运行整个剧本。您可以使用 Ansible 标签来实现。使用标签来执行或跳过选定的任务是一个两步过程
将标签添加到您的任务,可以单独添加,也可以从块、剧本、角色或导入中继承标签。
在运行剧本时选择或跳过标签。
注意
tags
关键字是剧本“预处理”的一部分,在决定哪些任务可供执行时具有很高的优先级。
使用 tags 关键字添加标签
您可以向单个任务或包含文件添加标签。您还可以通过在块、剧本、角色或导入文件级别定义标签来向多个任务添加标签。关键字 tags
解决了所有这些用例。 tags
关键字始终定义标签并将它们添加到任务;它不会选择或跳过要执行的任务。您只能在运行剧本时使用命令行根据标签选择或跳过任务。有关更多详细信息,请参见 在运行剧本时选择或跳过标签。
向单个任务添加标签
在最简单的级别,您可以将一个或多个标签应用于单个任务。您可以在剧本、任务文件中或角色中向任务添加标签。这是一个使用不同标签标记两个任务的示例
tasks:
- name: Install the servers
ansible.builtin.yum:
name:
- httpd
- memcached
state: present
tags:
- packages
- webservers
- name: Configure the service
ansible.builtin.template:
src: templates/src.j2
dest: /etc/foo.conf
tags:
- configuration
您可以将相同的标签应用于多个单个任务。此示例使用相同的标签“ntp”标记了几个任务
---
# file: roles/common/tasks/main.yml
- name: Install ntp
ansible.builtin.yum:
name: ntp
state: present
tags: ntp
- name: Configure ntp
ansible.builtin.template:
src: ntp.conf.j2
dest: /etc/ntp.conf
notify:
- restart ntpd
tags: ntp
- name: Enable and run ntpd
ansible.builtin.service:
name: ntpd
state: started
enabled: true
tags: ntp
- name: Install NFS utils
ansible.builtin.yum:
name:
- nfs-utils
- nfs-util-lib
state: present
tags: filesharing
如果您使用 --tags ntp
在剧本中运行这四个任务,Ansible 将运行三个标记为 ntp
的任务,并跳过没有该标签的一个任务。
向处理程序添加标签
处理程序是任务的一种特殊情况,它们仅在收到通知时才会执行,因此它们会忽略所有标签,并且不能选择或反对它们。
向块添加标签
如果要将标签应用于剧本中的许多(但不是所有)任务,请使用一个 块 并在该级别定义标签。例如,我们可以编辑上面显示的 NTP 示例以使用块
# myrole/tasks/main.yml
- name: ntp tasks
tags: ntp
block:
- name: Install ntp
ansible.builtin.yum:
name: ntp
state: present
- name: Configure ntp
ansible.builtin.template:
src: ntp.conf.j2
dest: /etc/ntp.conf
notify:
- restart ntpd
- name: Enable and run ntpd
ansible.builtin.service:
name: ntpd
state: started
enabled: true
- name: Install NFS utils
ansible.builtin.yum:
name:
- nfs-utils
- nfs-util-lib
state: present
tags: filesharing
请注意,tag
选择优先于大多数其他逻辑,包括 block
错误处理。在 block
中的任务上设置标签,但在 rescue
或 always
部分不设置标签,如果您的标签选择不涵盖这些部分中的任务,将阻止它们触发。
- block:
- debug: msg=run with tag, but always fail
failed_when: true
tags: example
rescue:
- debug: msg=I always run because the block always fails, except if you select to only run 'example' tag
always:
- debug: msg=I always run, except if you select to only run 'example' tag
此示例在没有指定 --tags
的情况下调用时运行所有 3 个任务,但在使用 --tags example
运行时仅运行第一个任务。
向剧本添加标签
如果剧本中的所有任务都应该获得相同的标签,您可以在剧本级别添加标签。例如,如果您有一个只包含 NTP 任务的剧本,您可以标记整个剧本
- hosts: all
tags: ntp
tasks:
- name: Install ntp
ansible.builtin.yum:
name: ntp
state: present
- name: Configure ntp
ansible.builtin.template:
src: ntp.conf.j2
dest: /etc/ntp.conf
notify:
- restart ntpd
- name: Enable and run ntpd
ansible.builtin.service:
name: ntpd
state: started
enabled: true
- hosts: fileservers
tags: filesharing
tasks:
...
注意
标记的任务将包括剧本的所有隐式任务(如事实收集),包括通过角色添加的任务。
向角色添加标签
有三种方法可以向角色添加标签
通过在
roles
下设置标签,将相同标签或标签添加到角色中的所有任务。请参见本节中的示例。通过在剧本中静态
import_role
上设置标签,将相同标签或标签添加到角色中的所有任务。请参见 向导入文件添加标签 中的示例。向角色本身的单个任务或块添加标签或标签。这是唯一允许您选择或跳过角色中某些任务的方法。要选择或跳过角色中的任务,您必须在单个任务或块上设置标签,在剧本中使用动态
include_role
,并将相同标签或标签添加到包含文件。当您使用这种方法,然后使用--tags foo
运行剧本时,Ansible 将运行包含文件本身以及角色中也具有标签foo
的任何任务。有关详细信息,请参见 向包含文件添加标签。
当您使用 roles
关键字在剧本中静态包含角色时,Ansible 会将您定义的任何标签添加到角色中的所有任务。例如
roles:
- role: webserver
vars:
port: 5000
tags: [ web, foo ]
或
---
- hosts: webservers
roles:
- role: foo
tags:
- bar
- baz
# using YAML shorthand, this is equivalent to:
# - { role: foo, tags: ["bar", "baz"] }
注意
在角色级别添加标签时,不仅所有任务都被标记,而且角色的依赖项也会对其任务进行标记。有关详细信息,请参见标签继承部分。
向包含文件添加标签
您可以在剧本中向动态包含文件应用标签。与单个任务上的标签一样,include_*
任务上的标签仅应用于包含文件本身,而不应用于包含文件中或角色中的任何任务。如果向动态包含文件添加 mytag
,然后使用 --tags mytag
运行该剧本,Ansible 将运行包含文件本身,运行包含文件中或角色中标记为 mytag
的任何任务,并跳过包含文件中或角色中没有该标签的任何任务。有关更多详细信息,请参见 选择性运行可重用文件中带有标签的任务。
您向包含文件添加标签的方式与向任何其他任务添加标签的方式相同
---
# file: roles/common/tasks/main.yml
- name: Dynamic reuse of database tasks
include_tasks: db.yml
tags: db
您可以仅向角色的动态包含文件添加标签。在此示例中,foo
标签 不会应用于 bar
角色内部的任务
---
- hosts: webservers
tasks:
- name: Include the bar role
include_role:
name: bar
tags:
- foo
向导入文件添加标签
您还可以将标签或标签应用于由静态 import_role
和 import_tasks
语句导入的所有任务
---
- hosts: webservers
tasks:
- name: Import the foo role
import_role:
name: foo
tags:
- bar
- baz
- name: Import tasks from foo.yml
import_tasks: foo.yml
tags: [ web, foo ]
包含文件的标签继承:块和 apply
关键字
默认情况下,Ansible 不会将 标签继承 应用于使用 include_role
和 include_tasks
进行的动态重用。如果向包含文件添加标签,它们仅应用于包含文件本身,而不应用于包含文件中或角色中的任何任务。这使您能够在运行剧本时执行角色或任务文件中的选定任务 - 请参见 选择性运行可重用文件中带有标签的任务。
如果您想要标签继承,您可能需要使用导入。但是,在单个剧本中同时使用包含和导入会导致难以诊断的错误。因此,如果您的剧本使用 include_*
来重用角色或任务,并且您需要在某个包含中进行标签继承,Ansible 提供了两种解决方法。您可以使用 apply
关键字
- name: Apply the db tag to the include and to all tasks in db.yml
include_tasks:
file: db.yml
# adds 'db' tag to tasks within db.yml
apply:
tags: db
# adds 'db' tag to this 'include_tasks' itself
tags: db
或者您可以使用一个块
- block:
- name: Include tasks from db.yml
include_tasks: db.yml
tags: db
特殊标签
Ansible 为特殊行为保留了几个标签名称:always
、never
、tagged
、untagged
和 all
。 always
和 never
主要用于标记任务本身,另外三个用于选择要运行或跳过的标签。
始终和从不
Ansible 为特殊行为保留了几个标签名称,其中两个是 always
和 never
。如果您将 always
标签分配给任务或剧本,Ansible 将始终运行该任务或剧本,除非您明确跳过它(--skip-tags always
)或该任务定义的另一个标签。
例如
tasks:
- name: Print a message
ansible.builtin.debug:
msg: "Always runs"
tags:
- always
- name: Print a message
ansible.builtin.debug:
msg: "runs when you use specify tag1, all(default) or tagged"
tags:
- tag1
- name: Print a message
ansible.builtin.debug:
msg: "always runs unless you explicitly skip, like if you use ``--skip-tags tag2``"
tags:
- always
- tag2
警告
默认情况下,内部事实收集任务被标记为 "always"。但是,如果您对剧本应用标签并直接跳过它(
--skip-tags
)或在使用--tags
并省略它时间接跳过它,则可以跳过它。
警告
默认情况下,角色参数规范验证任务被标记为 "always"。如果您使用
--skip-tags always
,将跳过此验证。
版本 2.5 中的新增功能。
如果您将 never
标签分配给任务或剧本,Ansible 会跳过该任务或剧本,除非您明确请求它(--tags never
)或为该任务定义的另一个标签。
例如
tasks:
- name: Run the rarely-used debug task, either with ``--tags debug`` or ``--tags never``
ansible.builtin.debug:
msg: '{{ showmevar }}'
tags: [ never, debug ]
上面示例中很少使用的调试任务仅在您明确请求 debug
或 never
标签时运行。
运行剧本时选择或跳过标签
将标签添加到任务、包含、块、剧本、角色和导入后,您可以在运行 ansible-playbook 时根据其标签选择性地执行或跳过任务。Ansible 运行或跳过所有与您在命令行传递的标签匹配的标签的任务。如果您在块或剧本级别添加了标签,使用 roles
,或者使用导入,则该标签将应用于块、剧本、角色或导入角色或文件中的每个任务。如果您有一个具有多个标签的角色,并且您希望在不同的时间调用角色的子集,请使用动态包含,或将角色拆分为多个角色。
ansible-playbook 提供五个与标签相关的命令行选项
--tags all
- 运行所有任务,包括已标记和未标记的任务,除非是never
(默认行为)。--tags tag1,tag2
- 仅运行带有标签tag1
或标签tag2
的任务(以及标记为always
的任务)。--skip-tags tag3,tag4
- 运行所有任务,除了带有标签tag3
或标签tag4
或者never
的任务。--tags tagged
- 仅运行至少具有一个标签的任务(never
覆盖)。--tags untagged
- 仅运行没有标签的任务(always
覆盖)。
例如,要在非常长的剧本中仅运行标记为 configuration
或 packages
的任务和块
ansible-playbook example.yml --tags "configuration,packages"
要运行除标记为 packages
的任务之外的所有任务
ansible-playbook example.yml --skip-tags "packages"
要运行所有任务,即使是由于标记为 never
而被排除的任务
ansible-playbook example.yml --tags "all,never"
运行带有 tag1 或 tag3 的任务,但跳过也带有 tag4 的任务
ansible-playbook example.yml --tags "tag1,tag3" --skip-tags "tag4"
标签优先级
跳过始终优先于显式标签,例如,如果您同时指定了 --tags
和 --skip-tags
,则后者优先。例如,--tags tag1,tag3,tag4 --skip-tags tag3
仅运行标记为 tag1 或 tag4 的任务,但不运行标记为 tag3 的任务,即使任务具有其他标签也是如此。
预览使用标签的结果
在运行角色或剧本时,您可能不知道或不记得哪些任务具有哪些标签,或者哪些标签存在。Ansible 为 ansible-playbook 提供两个命令行标志,可帮助您管理带标签的剧本
--list-tags
- 生成可用标签的列表--list-tasks
- 与--tags tagname
或--skip-tags tagname
一起使用时,生成已标记任务的预览
例如,如果您不知道剧本、角色或任务文件中配置任务的标签是 config
还是 conf
,则可以在不运行任何任务的情况下显示所有可用标签
ansible-playbook example.yml --list-tags
如果您不知道哪些任务具有标签 configuration
和 packages
,则可以传递这些标签并添加 --list-tasks
。Ansible 会列出这些任务,但不会执行任何任务。
ansible-playbook example.yml --tags "configuration,packages" --list-tasks
这些命令行标志有一个限制:它们无法显示动态包含的文件或角色中的标签或任务。有关静态导入和动态包含之间差异的更多信息,请参见 比较包含和导入:动态和静态重用。
在可重用文件中选择性地运行已标记任务
如果您有一个角色或任务文件,在任务或块级别定义了标签,则可以使用动态包含而不是静态导入,在剧本中选择性地运行或跳过这些已标记任务。您必须在包含的任务和包含语句本身中使用相同的标签。例如,您可以创建一个包含一些已标记和一些未标记任务的文件
# mixed.yml
tasks:
- name: Run the task with no tags
ansible.builtin.debug:
msg: this task has no tags
- name: Run the tagged task
ansible.builtin.debug:
msg: this task is tagged with mytag
tags: mytag
- block:
- name: Run the first block task with mytag
...
- name: Run the second block task with mytag
...
tags:
- mytag
您可以在剧本中包含上面的任务文件
# myplaybook.yml
- hosts: all
tasks:
- name: Run tasks from mixed.yml
include_tasks:
name: mixed.yml
tags: mytag
使用 ansible-playbook -i hosts myplaybook.yml --tags "mytag"
运行剧本时,Ansible 会跳过没有标签的任务,运行已标记的单个任务,以及运行块中的两个任务。此外,由于它被标记为 always
,它还可以运行事实收集(隐式任务)。
标签继承:将标签添加到多个任务
如果您想将相同的标签或标签应用于多个任务,而不必在每个任务中添加 tags
行,则可以在剧本或块级别定义标签,或者在添加角色或导入文件时定义标签。Ansible 会将这些标签应用于依赖项链中的所有子任务。对于角色和导入,Ansible 会将 roles
部分或导入设置的标签附加到角色或导入文件中单个任务或块设置的任何标签。这称为标签继承。标签继承很方便,因为您不必标记每个任务。但是,这些标签仍然单独应用于这些任务。
对于剧本、块、role
关键字和静态导入,Ansible 会应用标签继承,将您定义的标签添加到剧本、块、角色或导入文件中每个任务中。但是,标签继承不会应用于使用 include_role
和 include_tasks
的动态重用。使用动态重用(包含),您定义的标签仅应用于包含本身。如果您需要标签继承,请使用静态导入。如果您无法使用导入,因为您的剧本的其余部分使用包含,请参阅 包含的标签继承:块和 apply 关键字,了解如何解决此行为。
您可以在剧本中向动态包含文件应用标签。与单个任务上的标签一样,include_*
任务上的标签仅应用于包含文件本身,而不应用于包含文件中或角色中的任何任务。如果向动态包含文件添加 mytag
,然后使用 --tags mytag
运行该剧本,Ansible 将运行包含文件本身,运行包含文件中或角色中标记为 mytag
的任何任务,并跳过包含文件中或角色中没有该标签的任何任务。有关更多详细信息,请参见 选择性运行可重用文件中带有标签的任务。
全局配置标签
如果您默认运行或跳过某些标签,则可以使用 Ansible 配置中的 TAGS_RUN 和 TAGS_SKIP 选项来设置这些默认值。
另请参阅
- Ansible 剧本
剧本简介
- 角色
按角色组织剧本
- 交流
有疑问?需要帮助?想分享您的想法?请访问 Ansible 交流指南