While Ansible tags are commonly used to exclude tasks from execution (by running playbooks with --skip-tags
), many users need the inverse functionality - executing tasks only when specific tags are explicitly requested.
By default, when you run an Ansible playbook without any tag specifications:
- All tasks execute unless skipped via
when
conditions - Tagged tasks still run unless explicitly skipped
What we want is the opposite behavior - a task should run only when its tag is specifically requested.
Ansible provides access to currently active tags through the ansible_run_tags
magic variable. Here's how to use it:
- name: Only execute when 'foo' tag is specified
debug:
msg: "This task only runs with --tags foo"
when: "'foo' in ansible_run_tags"
For more complex scenarios, consider these approaches:
1. Multiple tag requirement:
when:
- "'foo' in ansible_run_tags"
- "'bar' in ansible_run_tags"
2. Tag with fallback condition:
when:
- "'deploy' in ansible_run_tags"
- some_other_condition|default(false)
Here's how you might implement a database migration that should only run when explicitly requested:
- name: Run database migrations
command: /usr/bin/db-migrate
when: "'db_migrate' in ansible_run_tags"
tags:
- db_migrate
- never
The never
tag serves as additional protection against accidental execution.
- Test thoroughly - tag conditions can affect idempotency
- Document all tag-only tasks clearly
- Consider combining with
changed_when
for better output
Another pattern is to place sensitive tasks in separate files and conditionally include them:
- name: Include dangerous operations
include_tasks: dangerous.yml
when: "'dangerous' in ansible_run_tags"
In Ansible playbooks, tags serve as powerful filters that allow you to selectively run portions of your automation. While the default behavior executes all tasks, we often need the opposite functionality - executing tasks only when specific tags are explicitly requested.
The standard tag implementation works as an exclusion filter, where untagged tasks always run unless skipped via --skip-tags
. What if we need a task that:
- Runs only when "foo" tag is specified
- Remains skipped in all other cases (including no tags specified)
Ansible provides access to currently active tags through the ansible_run_tags
variable. Here's how to use it:
- name: Task that runs only with 'foo' tag
debug:
msg: "This only appears when 'foo' tag is specified"
when: "'foo' in ansible_run_tags'
tags: foo
Consider these real-world scenarios:
1. Conditional Package Installation
- name: Install debug tools (only with 'debug' tag)
apt:
name: "{{ item }}"
state: present
loop:
- htop
- lsof
- strace
when: "'debug' in ansible_run_tags"
tags: debug
2. Environment-Specific Configuration
- name: Apply production firewall rules
iptables:
# rules here
when: "'prod' in ansible_run_tags"
tags: prod
Combining Multiple Tags
- name: Maintenance mode operations
command: /usr/bin/maintenance_script
when:
- "'maintenance' in ansible_run_tags"
- "'critical' in ansible_run_tags"
tags: maintenance,critical
Using Tag Inheritance in Roles
When working with roles, you can apply this pattern at the role level:
- name: Include database setup
include_role:
name: database
when: "'db_setup' in ansible_run_tags"
tags: db_setup
- The
ansible_run_tags
variable contains tags actually specified in the command line - Always include the tag in the task's
tags:
field for consistency - This approach works in Ansible 2.5 and later
- For complex conditions, consider using
ansible_run_tags
with other facts