In this article, we are going to learn what are Ansible tags and the effective ways to use tags in Ansible playbooks to run only specific tasks.
Table of Contents
What Are Ansible Tags?
When you run the playbook, ansible will read the playbook from top to bottom and run the tasks one by one. Sometimes we may need only particular tasks to be executed. In such cases, Ansible tags allow you to run or skip tasks as you wish.
The Keyword tags should be used to create tags. Tags can be created for plays, individual tasks, blocks, imports, and roles.
Task Level Ansible Tags
Take a look at the apt
package management playbook below where I have created two tasks. Tagged both the tasks with tags keyword.
- name: Package Installation hosts: ubuntu.anslab.com gather_facts: false become: true tasks: - name: Updating cache ( sudo apt update ) apt: update_cache: true tags: cache_update - name: Remove packages - no dependency apt: autoremove: yes tags: remove
If I run this playbook nothing related to tags will happen and ansible will run all the tasks as usual from top to bottom. You should tell ansible which task with particular tag should run and which should be skipped.
Along with ansible-playbook
command, use --tags
or -t
flag and pass the tag name to run only that particular task.
$ ansible-playbook tags_testing.yml --tags <tag names> $ ansible-playbook tags_testing.yml --tags cache_update
Sample Output:
PLAY [Package Installation] **************************************************************************************************************** TASK [Updating cache ( sudo apt update )] ************************************************************************************************** changed: [ubuntu.anslab.com] PLAY RECAP ********************************************************************************************************************************* ubuntu.anslab.com : ok=1 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
You can also pass more than one tags to --tags
flag by separating the values with commas.
$ ansible-playbook tags_testing.yml --tags "cache_update,remove"
Sample Output:
PLAY [Package Installation] **************************************************************************************************************** TASK [Updating cache ( sudo apt update )] ************************************************************************************************** changed: [ubuntu.anslab.com] TASK [Remove packages - no dependency] ***************************************************************************************************** ok: [ubuntu.anslab.com] PLAY RECAP ********************************************************************************************************************************* ubuntu.anslab.com : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
To skip particular tags and run all other tags, you can use --skip-tags
flag. Similarly, You can also pass multiple tags as arguments by separating them with commas to --skip-tags
flag.
$ ansible-playbook tags_testing.yml --skip-tags cache_update $ ansible-playbook tags_testing.yml --skip-tags "cache_update,remove" # MULTIPLE TAGS
Sample Output:
PLAY [Package Installation] **************************************************************************************************************** TASK [Remove packages - no dependency] ***************************************************************************************************** ok: [ubuntu.anslab.com] PLAY RECAP ********************************************************************************************************************************* ubuntu.anslab.com : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Multi Tagging
You can have more than one name tagged to a task using the YAML
list format. If you see the below playbook, a second tag (i.e pkg_mt
) is added to both the tasks.
tasks: - name: Updating cache ( sudo apt update ) apt: update_cache: true tags: - cache_update - pkg_mt - name: Remove packages - no dependency apt: autoremove: yes tags: - remove - pkg_mt
You can also use python list notation to create multiple tags.
tasks: - name: Updating cache ( sudo apt update ) apt: update_cache: true tags: ["cache_update", "pkg_mt"] - name: Remove packages - no dependency apt: autoremove: yes tags: ["remove", "pkg_mt"]
Now, run the playbook:
$ ansible-playbook tags_testing.yml --tags pkg_mt
Sample Output:
PLAY [Package Installation] **************************************************************************************************************** TASK [Updating cache ( sudo apt update )] ************************************************************************************************** changed: [ubuntu.anslab.com] TASK [Remove packages - no dependency] ***************************************************************************************************** ok: [ubuntu.anslab.com] PLAY RECAP ********************************************************************************************************************************* ubuntu.anslab.com : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Get Tag Information
To get the list of tags from the playbook, you can use the --list-tags
flag.
$ ansible-playbook tags_testing.yml --list-tags playbook: tags_testing.yml play #1 (ubuntu.anslab.com): Package Installation TAGS: [pkg_mt] TASK TAGS: [cache_update, pkg_mt, remove]
To get the task list with particular tags, you can combine --tags
flag and --list-tasks
flags.
$ ansible-playbook tags_testing.yml --list-tasks --tags remove playbook: tags_testing.yml play #1 (ubuntu.anslab.com): Package Installation TAGS: [pkg_mt] tasks: Remove packages - no dependency TAGS: [pkg_mt, remove]
You can also use --list-tasks
tag alone which will print both tag names and task/play names.
$ ansible-playbook tags_testing.yml --list-tasks playbook: tags_testing.yml play #1 (ubuntu.anslab.com): Package Installation TAGS: [pkg_mt] tasks: Updating cache ( sudo apt update ) TAGS: [cache_update, pkg_mt] Remove packages - no dependency TAGS: [pkg_mt, remove]
Play Level Tags
Tags can also be applied at the play level. This tag will be inherited by all the tasks in the play. In the below playbook, I have added a tag named pkg_mt
to the play.
- name: Package Installation hosts: ubuntu.anslab.com gather_facts: false become: true tags: pkg_mt tasks: - name: Updating cache ( sudo apt update ) apt: update_cache: true tags: cache_update - name: Remove packages - no dependency apt: autoremove: yes tags: remove
You can run --list-tasks
and see the tag "pkg_mt" being inherited by all tasks in the play.
$ ansible-playbook tags_testing.yml --list-tasks playbook: tags_testing.yml play #1 (ubuntu.anslab.com): Package Installation TAGS: [pkg_mt] tasks: Updating cache ( sudo apt update ) TAGS: [cache_update, pkg_mt] Remove packages - no dependency TAGS: [pkg_mt, remove]
Special Tags
There are two special tags named always and never.
- ALWAYS - Always run the task unless you explicitly use
--skip-tags
to stop running the task. - NEVER - A task will never run unless you explicitly use the
--tags
flag to run the task.
In any case, if you want to skip tasks that are tagged with the "always" tag then you have to use skip tags.
$ ansible-playbook tags_testing --skip-tags always
In any case if you wish to run tasks that are tagged with a "never" tag, explicitly pass it to the --tags
flag.
$ ansible-playbook tags_testing --tags never
Tag vs Untag
A playbook may consist of tasks with tags and without tags. You can either choose to run tasks that have no tags or at least with one or more tags.
To run tasks that have no tags, pass untagged to --tags
flag. This way ansible will check and run tasks that don't have any tags mapped to them in the playbook.
$ ansible-playbook tags_testing --tags untagged
To run tasks that have at least one tag mapped to them, pass tagged to --tags
flag.
$ ansible-playbook tags_testing --tags tagged
Apply Tags To Blocks
Blocks allow you to group tasks logically. Block-rescue-always are used for exception handling in ansible. Instead of applying tags to each task in the play you can group the tasks under blocks and apply tags to blocks.
Below is the pseudo-code for triggering a shell script and sending an email. Here I have applied the tag "pipeline" at the block level. When I run the playbook with the pipeline tag all the tasks in the block will run.
- block: - name: Trigger Pipeline script script: /home/dev/project1/trigger_pipeline.sh - name: Send email to dev team mail: host: smtp.dummy.com port: 587 username: username@dummy.com to: devteam@dummy.com subject: Pipeline triggered. body: Input file generated for today. Pipeline triggered. delegate_to: localhost tags: pipeline
Conclusion
In this article we discussed what are Ansible tags and how to use tags at the play and task level in the playbook. We have also seen about the predefined tags "always" and "never" and how to use them in the playbook. Finally, we looked at how to use the tags with blocks.
Tags may seem to be a basic concept but it is very useful to group the task and allow us to structure the playbook in a way that we control what task should run and how it should run.
Resource: