You can add tags to a single task or include. You can also add tags to multiple tasks by defining them at the level of a block, play, role, or import. The keyword tags
addresses all these use cases. The tags
keyword always defines tags and adds them to tasks; it does not select or skip tasks for execution. You can only select or skip tasks based on tags at the command line when you run a playbook. See Selecting or skipping tags when you run a playbook for more details.
At the simplest level, you can apply one or more tags to an individual task. You can add tags to tasks in playbooks, in task files, or within a role. Here is an example that tags two tasks with different 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
You can apply the same tag to more than one individual task. This example tags several tasks with the same tag, “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: yes tags: ntp - name: Install NFS utils ansible.builtin.yum: name: - nfs-utils - nfs-util-lib state: present tags: filesharing
If you ran these four tasks in a playbook with --tags ntp
, Ansible would run the three tasks tagged ntp
and skip the one task that does not have that tag.
You add tags to includes the same way you add tags to any other task:
--- # file: roles/common/tasks/main.yml - name: Dynamic re-use of database tasks include_tasks: db.yml tags: db
You can add a tag only to the dynamic include of a role. In this example, the foo
tag will not
apply to tasks inside the bar
role:
--- - hosts: webservers tasks: - name: Include the bar role include_role: name: bar tags: - foo
With plays, blocks, the role
keyword, and static imports, Ansible applies tag inheritance, adding the tags you define to every task inside the play, block, role, or imported file. However, tag inheritance does not apply to dynamic re-use with include_role
and include_tasks
. With dynamic re-use (includes), the tags you define apply only to the include itself. If you need tag inheritance, use a static import. If you cannot use an import because the rest of your playbook uses includes, see Tag inheritance for includes: blocks and the apply keyword for ways to work around this behavior.
If you want to apply a tag to many, but not all, of the tasks in your play, use a block and define the tags at that level. For example, we could edit the NTP example shown above to use a block:
# myrole/tasks/main.yml tasks: - 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: yes - name: Install NFS utils ansible.builtin.yum: name: - nfs-utils - nfs-util-lib state: present tags: filesharing
If all the tasks in a play should get the same tag, you can add the tag at the level of the play. For example, if you had a play with only the NTP tasks, you could tag the entire play:
- 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: yes - hosts: fileservers tags: filesharing tasks: ...
There are three ways to add tags to roles:
roles
. See examples in this section.import_role
in your playbook. See examples in Adding tags to imports.include_role
in your playbook, and add the same tag or tags to the include. When you use this approach, and then run your playbook with --tags foo
, Ansible runs the include itself plus any tasks in the role that also have the tag foo
. See Adding tags to includes for details.When you incorporate a role in your playbook statically with the roles
keyword, Ansible adds any tags you define to all the tasks in the role. For example:
roles: - role: webserver vars: port: 5000 tags: [ web, foo ]
or:
--- - hosts: webservers roles: - role: foo tags: - bar - baz # using YAML shorthand, this is equivalent to: # - { role: foo, tags: ["bar", "baz"] }
--- - 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
keywordBy default, Ansible does not apply tag inheritance to dynamic re-use with include_role
and include_tasks
. If you add tags to an include, they apply only to the include itself, not to any tasks in the included file or role. This allows you to execute selected tasks within a role or task file - see Selectively running tagged tasks in re-usable files when you run your playbook.
If you want tag inheritance, you probably want to use imports. However, using both includes and imports in a single playbook can lead to difficult-to-diagnose bugs. For this reason, if your playbook uses include_*
to re-use roles or tasks, and you need tag inheritance on one include, Ansible offers two workarounds. You can use the apply
keyword:
- name: Apply the db tag to the include and to all tasks in db.yaml 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
Or you can use a block:
- block: - name: Include tasks from db.yml include_tasks: db.yml tags: db
For example:
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 tag1" tags: - tag1
Warning
--tags
or the same tag in --skip-tags
.Warning
--skip-tags always
.New in version 2.5.
If you assign the never
tag to a task or play, Ansible will skip that task or play unless you specifically request it (--tags never
).
For example:
tasks: - name: Run the rarely-used debug task ansible.builtin.debug: msg: '{{ showmevar }}' tags: [ never, debug ]
The rarely-used debug task in the example above only runs when you specifically request the debug
or never
tags.
ansible-playbook offers five tag-related command-line options:
--tags all
- run all tasks, ignore tags (default behavior)--tags [tag1, tag2]
- run only tasks with either the tag tag1
or the tag tag2
--skip-tags [tag3, tag4]
- run all tasks except those with either the tag tag3
or the tag tag4
--tags tagged
- run only tasks with at least one tag--tags untagged
- run only tasks with no tagsFor example, to run only tasks and blocks tagged configuration
and packages
in a very long playbook:
ansible-playbook example.yml --tags "configuration,packages"
To run all tasks except those tagged packages
:
ansible-playbook example.yml --skip-tags "packages"
When you run a role or playbook, you might not know or remember which tasks have which tags, or which tags exist at all. Ansible offers two command-line flags for ansible-playbook that help you manage tagged playbooks:
--list-tags
- generate a list of available tags--list-tasks
- when used with --tags tagname
or --skip-tags tagname
, generate a preview of tagged tasksFor example, if you do not know whether the tag for configuration tasks is config
or conf
in a playbook, role, or tasks file, you can display all available tags without running any tasks:
ansible-playbook example.yml --list-tags
If you do not know which tasks have the tags configuration
and packages
, you can pass those tags and add --list-tasks
. Ansible lists the tasks but does not execute any of them.
ansible-playbook example.yml --tags "configuration,packages" --list-tasks
These command-line flags have one limitation: they cannot show tags or tasks within dynamically included files or roles. See Comparing includes and imports: dynamic and static re-use for more information on differences between static imports and dynamic includes.
If you have a role or a tasks file with tags defined at the task or block level, you can selectively run or skip those tagged tasks in a playbook if you use a dynamic include instead of a static import. You must use the same tag on the included tasks and on the include statement itself. For example you might create a file with some tagged and some untagged 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
And you might include the tasks file above in a playbook:
# myplaybook.yml - hosts: all tasks: - name: Run tasks from mixed.yml include_tasks: name: mixed.yml tags: mytag
When you run the playbook with ansible-playbook -i hosts myplaybook.yml --tags "mytag"
, Ansible skips the task with no tags, runs the tagged individual task, and runs the two tasks in the block.
If you run or skip certain tags by default, you can use the TAGS_RUN and TAGS_SKIP options in Ansible configuration to set those defaults.
See also
An introduction to playbooks
Playbook organization by roles
Have a question? Stop by the google group!
#ansible IRC chat channel
© 2012–2018 Michael DeHaan
© 2018–2021 Red Hat, Inc.
Licensed under the GNU General Public License version 3.
https://docs.ansible.com/ansible/latest/user_guide/playbooks_tags.html