How to use ansible tags in playbook with examples

Ansible tags are another great feature which can help you execute respective tasks from the playbook. By default all the tasks from the playbook are executed but with tags we can control this behaviour and execute only the tasks with the matching tags.

 

Understanding Tags

  • 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).

 

Example-1: Add 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 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 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 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.

 

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

 

Leave a Comment

Please use shortcodes <pre class=comments>your code</pre> for syntax highlighting when adding code.