Ansible Tags: Run Specific Tasks in Playbooks (Complete Guide)
By Luca Berton · Published 2024-01-01 · Category: installation
How to use Ansible tags to run or skip specific tasks. Tag tasks, roles, and plays. Use --tags and --skip-tags to control execution.
Ansible Tags: Run Specific Tasks in Playbooks (Complete Guide)
Ansible tags let you selectively run or skip tasks within a playbook. Instead of running every task, you can execute only the ones tagged for configuration, deployment, or testing — saving time during development and targeted operations.
See also: Ansible Tags: Run Only Specific Tasks in a Playbook (Guide)
Basic Usage
Tag a Task
---
- name: Web server setup
hosts: webservers
become: true
tasks:
- name: Install packages
ansible.builtin.apt:
name: [nginx, certbot]
state: present
tags: packages
- name: Deploy configuration
ansible.builtin.template:
src: nginx.conf.j2
dest: /etc/nginx/nginx.conf
tags: config
- name: Start nginx
ansible.builtin.systemd:
name: nginx
state: started
enabled: true
tags: service
Run Only Tagged Tasks
# Run only tasks tagged "config"
ansible-playbook site.yml --tags config
# Run multiple tags
ansible-playbook site.yml --tags "packages,config"
# Skip specific tags
ansible-playbook site.yml --skip-tags service
# List all tags in a playbook
ansible-playbook site.yml --list-tags
Tag Syntax Options
Single Tag
- name: Install nginx
ansible.builtin.apt:
name: nginx
tags: packages
Multiple Tags on One Task
- name: Install nginx
ansible.builtin.apt:
name: nginx
tags:
- packages
- nginx
- setup
Tag an Entire Block
- name: Database setup
tags: database
block:
- name: Install PostgreSQL
ansible.builtin.apt:
name: postgresql
state: present
- name: Configure PostgreSQL
ansible.builtin.template:
src: pg_hba.conf.j2
dest: /etc/postgresql/16/main/pg_hba.conf
- name: Start PostgreSQL
ansible.builtin.systemd:
name: postgresql
state: started
Tag a Role
- hosts: webservers
roles:
- role: nginx
tags: nginx
- role: certbot
tags: [ssl, certbot]
- role: monitoring
tags: monitoring
Tag an Entire Play
- name: Configure web servers
hosts: webservers
tags: web
tasks:
- name: All tasks in this play inherit the "web" tag
ansible.builtin.debug:
msg: "This runs with --tags web"
See also: VMware Tag Verification with Ansible
Special Tags
always
Tasks tagged always run every time (unless explicitly skipped):
- name: Gather facts (always runs)
ansible.builtin.setup:
tags: always
- name: Show deployment info (always runs)
ansible.builtin.debug:
msg: "Deploying v{{ version }} to {{ env }}"
tags: always
# Even with --tags config, "always" tasks still run
ansible-playbook site.yml --tags config
# To skip "always" tasks, explicitly skip them
ansible-playbook site.yml --tags config --skip-tags always
never
Tasks tagged never only run when explicitly requested:
- name: Dangerous cleanup (only when explicitly requested)
ansible.builtin.shell: rm -rf /tmp/app-cache/*
tags: never
- name: Debug output (only in debug mode)
ansible.builtin.debug:
var: hostvars[inventory_hostname]
tags:
- never
- debug
# This task won't run normally
ansible-playbook site.yml
# Explicitly run it
ansible-playbook site.yml --tags debug
Tag Patterns
Environment-Based Tags
tasks:
- name: Deploy to staging
ansible.builtin.include_tasks: deploy-staging.yml
tags: staging
- name: Deploy to production
ansible.builtin.include_tasks: deploy-production.yml
tags: production
ansible-playbook deploy.yml --tags staging
ansible-playbook deploy.yml --tags production
Phase-Based Tags
tasks:
- name: Install dependencies
ansible.builtin.apt:
name: "{{ packages }}"
tags: [install, setup]
- name: Configure application
ansible.builtin.template:
src: app.conf.j2
dest: /etc/app/app.conf
tags: [config, setup]
- name: Deploy application code
ansible.builtin.git:
repo: "{{ app_repo }}"
dest: /opt/app
tags: [deploy, update]
- name: Run migrations
ansible.builtin.command: /opt/app/manage.py migrate
tags: [deploy, migrate]
- name: Restart service
ansible.builtin.systemd:
name: app
state: restarted
tags: [deploy, restart]
# Full setup
ansible-playbook site.yml --tags setup
# Just deploy new code
ansible-playbook site.yml --tags deploy
# Only restart service
ansible-playbook site.yml --tags restart
See also: Ansible ignore_errors: Error Handling Best Practices (Complete Guide)
Tags with include_tasks and import_tasks
import_tasks (tags inherited)
- name: Import tasks (tags apply to all imported tasks)
ansible.builtin.import_tasks: database.yml
tags: database
# All tasks in database.yml get the "database" tag
include_tasks (tags on include only)
- name: Include tasks (tag only controls whether include runs)
ansible.builtin.include_tasks: database.yml
tags: database
# The include itself is tagged, but tasks inside can have their own tags
List and Preview Tags
# List all tags in a playbook
ansible-playbook site.yml --list-tags
# Preview which tasks would run
ansible-playbook site.yml --tags config --list-tasks
# Combine with --limit
ansible-playbook site.yml --tags deploy --limit web01 --list-tasks
Best Practices
Use consistent tag names across playbooks (packages, config, service, deploy)
Tag always sparingly — only for truly universal tasks like fact gathering
Use never for dangerous operations — cleanup, data deletion, debugging
Don't over-tag — if everything is tagged, tags lose their value
Document your tags in the playbook header or README
FAQ
What are Ansible tags?
Tags are labels you attach to tasks, blocks, roles, or plays. They let you selectively run (--tags) or skip (--skip-tags) specific parts of a playbook without modifying the YAML.
How do I run only specific tasks in an Ansible playbook?
Use --tags tag_name: ansible-playbook playbook.yml --tags config. Only tasks with that tag (plus tasks tagged always) will execute.
What does the "always" tag do in Ansible?
Tasks tagged always run regardless of which --tags you specify. Use it for essential tasks like gathering facts or displaying deployment information that should always execute.
What does the "never" tag do in Ansible?
Tasks tagged never are skipped during normal execution. They only run when explicitly requested with --tags tag_name where tag_name is another tag on that task.
Can I use multiple tags on one task?
Yes. Use a YAML list: tags: [config, nginx, setup]. The task runs if ANY of its tags match the --tags argument.
Conclusion
Ansible tags provide fine-grained control over playbook execution. Use them for phase-based deployment, environment targeting, and development workflows. Combine --tags and --skip-tags to run exactly the tasks you need.
Related Articles
• Ansible Playbook: Complete Guide • Ansible Playbook --limit: Run on Specific Hosts • How to Run Only One Task with Ansible TagsCategory: installation