Ansible Tags: Your Shortcut to Smarter Automation


Ansible Tutorial

Introduction to Ansible Tags

Ansible Tags are like labels or markers that you can attach to tasks in an Ansible playbook. Think of them as sticky notes you put on certain pages in a book to quickly find and refer to them later. In Ansible, these tags allow you to selectively execute specific tasks within a playbook. For example, if you have a large playbook with many tasks, but you only want to run a few of them, you can tag those tasks and tell Ansible to execute only the tasks with those specific tags. This makes managing and running complex automation scripts more efficient and flexible, as you can easily run or skip certain parts of the playbook as needed.

  • Tags are used at resource level to give a name to a specific resource
  • The --tags option is used with ansible-playbook to run only resources with a specific tag
  • When a task file is included in a playbook, it can be tagged in the include statement
  • When ansible-playbook --tags "tagname" is used, only resources marked with those tags will run. That would mean that if a resource at the same level doesn't have a tag then it won't run
  • Use --skip-tags 'tagname' to exclude resources with a specific tag
  • The special tag can be used to make sure a resource is always executed, unless specifically excluded with --skip-tags
  • The --tags option can take 3 specific tags as argument
    • tagged runs any tagged resource
    • untagged excludes all tagged resources
    • all runs all tasks (which is also the default behaviour when no tags have been specified)
NOTE:
You should take care of the indentation, tags should take the same amount of whitespace as used by the module definition i.e. module name or name under the tasks section (but without the hyphen).

 

Implementing Ansible Tags in Playbooks

1. Basic Tag Implementation

To implement Ansible Tags, you start by adding them to tasks in your playbook. It's like tagging a social media post to make it easily searchable. For instance, in an Ansible playbook, you might have a task for installing software and you could tag it with install. Here's an example:

- name: Install Apache
  yum:
    name: httpd
    state: present
  tags: install

In this example, the task to install Apache has the tag install. When you run your playbook, you can choose to only execute tasks with this tag.

2. Syntax of Ansible Tags

Ansible Tags follow a simple syntax. They are defined within a task using the tags: keyword, followed by the tag name. Tags can be a single word or a list of words. For example:

- name: Start Apache Service
  service:
    name: httpd
    state: started
  tags:
    - start
    - apache

Here, the task has two tags: start and apache. This allows for more flexibility as you can target this task with either tag.

3. Assigning Tags to Tasks and Roles

You can assign tags not only to individual tasks but also to entire roles in Ansible. A role is a collection of tasks, files, templates, and other components for a specific function (like configuring a database). To tag a whole role:

roles:
  - role: nginx
    tags: webserver

In this example, every task within the nginx role inherits the webserver tag.

4. Using Tags with Blocks

Blocks in Ansible are groups of tasks that share the same logic. You can apply tags to the entire block, which then applies to all tasks within that block. For example:

- name: Configure MySQL
  block:
    - name: Install MySQL
      yum:
        name: mysql-server
        state: present
    - name: Start MySQL Service
      service:
        name: mysql
        state: started
  tags: database

Here, both tasks in the block are tagged with database, so running this tag will execute the entire block.

 

Running and Controlling Playbooks with Ansible Tags

1. Running Specific Tasks with Tags

To run specific tasks within a playbook using Ansible Tags, you use the --tags option. This is useful when you only want to execute a subset of tasks. For instance:

ansible-playbook playbook.yml --tags "configuration"

In this command, only the tasks tagged with configuration in playbook.yml will be executed.

2. Skipping Tasks Using Tags

Ansible allows you to skip tasks with specific tags using the --skip-tags option. It's useful when you want to execute most of your playbook but skip a few tasks. For example:

ansible-playbook playbook.yml --skip-tags "testing"

This command will run all tasks in playbook.yml except those tagged with testing.

3. Listing All Defined Tags in a Playbook

To view all the tags used in a playbook, you can use the --list-tags option. This gives you an overview of all tags in your playbook, helping you plan which tags to run or skip. For example:

ansible-playbook playbook.yml --list-tags

4. Ensuring Certain Tasks Always or Never Run

Ansible Tags also allow you to ensure some tasks always run or never run regardless of other tags used. This is done using special tags like always or never. For instance:

- name: Check System Health
  command: /usr/bin/check_health
  tags: 
    - always

In this example, the health check task will always run, even if you specify other tags or use --skip-tags. This feature is essential for tasks that are critical to the operation of your playbook.

 

Best Practices and Strategies

1. Tag Inheritance and Execution Strategies

In Ansible, tags assigned to a role or an include are inherited by all tasks within that role or include. This means if you tag a role, every task in that role automatically gets that tag. For instance:

- include: wordpress.yml
  tags: 
    - web

Here, all tasks in wordpress.yml inherit the web tag. Execution strategy involves deciding when and where to use tags for efficient playbook runs.

2. Consistent Naming Conventions

It's crucial to use a consistent and intuitive naming convention for Ansible Tags. This helps in easily identifying and remembering the purpose of each tag. For example, use install, configure, test, etc., as tags for corresponding actions in your tasks.

3. Avoiding Over-Tagging

Over-tagging refers to adding too many tags, which can make your playbooks complicated and hard to manage. Stick to using tags only when they add value. For example, don't tag every task unless each has a distinct use case for being run separately.

4. Using Tags for Environment Specific Tasks

Ansible Tags are useful for distinguishing tasks that should only run in specific environments, like dev, test, or prod. For instance:

- name: Deploy to production server
  command: /deploy/production
  tags: 
    - prod

In this case, the deployment task is tagged with prod and will only be executed when running the playbook with the prod tag. This is especially useful for differentiating tasks based on the target environment.

 

Frequently Asked Questions (FAQs) on Ansible Tags

Can I use multiple tags for a single task in Ansible?

Yes, you can assign multiple tags to a single task. Use a list format in the tags: section. For example, tags: [setup, db].

How do I run multiple tags at once in Ansible?

To run multiple tags, separate them with commas in the --tags option like --tags "tag1,tag2".

What happens if I don't tag a task in Ansible?

Untagged tasks will always be executed unless specific tags are called for execution.

Can I tag an entire playbook in Ansible?

While you can't tag an entire playbook directly, you can tag each role or include in the playbook.

How do I use tags to run tasks only on certain hosts?

Combine tags with host patterns. For instance, specify the host and tag in the playbook command: ansible-playbook -l [host_pattern] --tags "tag1".

Are Ansible Tags case-sensitive?

Yes, Ansible Tags are case-sensitive. Setup and setup would be considered different tags.

Can I use special characters in Ansible Tags?

It's advisable to stick to alphanumeric characters and underscores for clarity and compatibility.

How does --skip-tags work in Ansible?

The --skip-tags option allows you to exclude tasks with specified tags from the playbook execution.

 

Practical Examples showcasing usage of Ansible Tags

Example-1: Adding Ansible tags to all the tasks

In this example I will prepare my sample playbook ansible-tags-1.yml with four tasks which will just print a message on the console. I will add a different tag with each task so we can use these individual tags to execute the mapping task

---
 - name: Ansible Tags
   hosts: localhost
   gather_facts: false
   tasks:
     - debug:
         msg: "This is first task"
       tags: first
     - debug:
         msg: "This is second task"
       tags: second
     - debug:
         msg: "This is third task"
       tags: third
     - debug:
         msg: "This is fourth task"
       tags: fourth

Now if I execute this playbook without any additional command line argument then all the tasks will be executed by default:

[ansible@controller ~]$ ansible-playbook ansible-tags-1.yml

PLAY [Ansible Tags] ************************************************************************************************

TASK [debug] *******************************************************************************************************
ok: [localhost] => {
    "msg": "This is first task"
}

TASK [debug] *******************************************************************************************************
ok: [localhost] => {
    "msg": "This is second task"
}

TASK [debug] *******************************************************************************************************
ok: [localhost] => {
    "msg": "This is third task"
}

TASK [debug] *******************************************************************************************************
ok: [localhost] => {
    "msg": "This is fourth task"
}

PLAY RECAP *********************************************************************************************************
localhost                  : ok=4    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

But we can control this behaviour by using tags, assuming we only wish to execute the first task so we can use "--tags first" with the same command:

[ansible@controller ~]$ ansible-playbook ansible-tags-1.yml --tags first

PLAY [Ansible Tags] ************************************************************************************************

TASK [debug] *******************************************************************************************************
ok: [localhost] => {
    "msg": "This is first task"
}

PLAY RECAP *********************************************************************************************************
localhost                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

So all other tasks are excluded from the play. We can add more tags to the list, for example to call task1 and task3 we will use:

[ansible@controller ~]$ ansible-playbook ansible-tags-1.yml --tags first,third

PLAY [Ansible Tags] ************************************************************************************************

TASK [debug] *******************************************************************************************************
ok: [localhost] => {
    "msg": "This is first task"
}

TASK [debug] *******************************************************************************************************
ok: [localhost] => {
    "msg": "This is third task"
}

PLAY RECAP *********************************************************************************************************
localhost                  : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

So we just need to give the mapping tag name to execute the respective task

 

Example-2: Exclude tasks using Ansible tags

Now in the above example we were executing the tasks by using the mapping tag name. But if you have 100s of tags and you only wish to exclude few of the tasks then it is not a good practice to provide all those tags through the command line.

In such case we can use --skip-tags to call all the other tags except the provided tags with --skip-tags. For example here I am executing all the tags except for the task mapped with tag fourth

[ansible@controller ~]$ ansible-playbook ansible-tags-1.yml --skip-tags fourth

PLAY [Ansible Tags] ************************************************************************************************

TASK [debug] *******************************************************************************************************
ok: [localhost] => {
    "msg": "This is first task"
}

TASK [debug] *******************************************************************************************************
ok: [localhost] => {
    "msg": "This is second task"
}

TASK [debug] *******************************************************************************************************
ok: [localhost] => {
    "msg": "This is third task"
}

PLAY RECAP *********************************************************************************************************
localhost                  : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

 

Example-3: Using same Ansible tag for multiple tasks

We can also use the same tag name for multiple tasks so that with a single tag name we can execute multiple tasks. I have updated my playbook to assign another tag name for my first and third task.

---
 - name: Ansible Tags
   hosts: localhost
   gather_facts: false
   tasks:
     - debug:
         msg: "This is first task"
       tags:
         - first
         - general
     - debug:
         msg: "This is second task"
       tags: second
     - debug:
         msg: "This is third task"
       tags:
         - third
         - general
     - debug:
         msg: "This is fourth task"
       tags: fourth

I have created an additional tag "general" for first and third task so now I can only use this tag if I want to execute first and third task instead of using two different tags all the time:

Let us verify this configuration

[ansible@controller ~]$ ansible-playbook ansible-tags-1.yml --tags general

PLAY [Ansible Tags] ************************************************************************************************

TASK [debug] *******************************************************************************************************
ok: [localhost] => {
    "msg": "This is first task"
}

TASK [debug] *******************************************************************************************************
ok: [localhost] => {
    "msg": "This is third task"
}

PLAY RECAP *********************************************************************************************************
localhost                  : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

 

Example-4: Disable one or more tasks using Ansible tags

We know that by default all the tasks from a play are executed but for some debugging purpose if you wish to disable a task then we can achieve this using tags. You can just assign the respective task "never" tag and that task will not be executed by default unless you specifically call the tag name of that task.

For example I have added never tag to my fourth task

---
 - name: Ansible Tags
   hosts: localhost
   gather_facts: false
   tasks:
     - debug:
         msg: "This is first task"
       tags:
         - first
         - general
     - debug:
         msg: "This is second task"
       tags: second
     - debug:
         msg: "This is third task"
       tags:
         - third
         - general
     - debug:
         msg: "This is fourth task"
       tags:
        - fourth
        - never

Let me execute the playbook without any command line arguments:

[ansible@controller ~]$ ansible-playbook ansible-tags-1.yml

PLAY [Ansible Tags] ************************************************************************************************

TASK [debug] *******************************************************************************************************
ok: [localhost] => {
    "msg": "This is first task"
}

TASK [debug] *******************************************************************************************************
ok: [localhost] => {
    "msg": "This is second task"
}

TASK [debug] *******************************************************************************************************
ok: [localhost] => {
    "msg": "This is third task"
}

PLAY RECAP *********************************************************************************************************
localhost                  : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

So the fourth task was not executed here. But we can execute the fourth task by using --tags fourth

[ansible@controller ~]$ ansible-playbook ansible-tags-1.yml --tags fourth

PLAY [Ansible Tags] ************************************************************************************************

TASK [debug] *******************************************************************************************************
ok: [localhost] => {
    "msg": "This is fourth task"
}

PLAY RECAP *********************************************************************************************************
localhost                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

In such case the never tag control is overwritten by the command line argument with a higher precedence.

 

Summary

Ansible tags offer a powerful way to manage and control the execution of tasks in your Ansible playbooks. They allow for selective running of tasks, making automation more efficient and tailored. Tags can be applied to individual tasks, roles, or blocks, and can be used to run, skip, or always execute certain tasks, providing flexibility in different environments. Best practices like consistent naming conventions, avoiding over-tagging, and using tags for environment-specific tasks help maintain efficient playbook management. For more in-depth information and official guidelines, you can refer to the Ansible Documentation on Tags.

 

What's Next

Next in our Ansible Tutorial we will learn about ansible blocks and rescue which can be used for error and recovery situations in real time environments

 

Deepak Prasad

Deepak Prasad

Deepak Prasad is the founder of GoLinuxCloud, bringing over a decade of expertise in Linux, Python, Go, Laravel, DevOps, Kubernetes, Git, Shell scripting, OpenShift, Networking, and Security. His extensive experience spans development, DevOps, networking, and security, ensuring robust and efficient solutions for diverse projects.

Certifications and Credentials:

  • Certified Kubernetes Application Developer (CKAD)
  • Go Developer Certification
  • Linux Foundation Certified System Administrator (LFCS)
  • Certified Ethical Hacker (CEH)
  • Python Institute PCAP (Certified Associate in Python Programming)
You can connect with him on his LinkedIn profile and join his Facebook and LinkedIn page.

Can't find what you're searching for? Let us assist you.

Enter your query below, and we'll provide instant results tailored to your needs.

If my articles on GoLinuxCloud has helped you, kindly consider buying me a coffee as a token of appreciation.

Buy GoLinuxCloud a Coffee

For any other feedbacks or questions you can send mail to admin@golinuxcloud.com

Thank You for your support!!

Leave a Comment