Ansible tagging strategies

Ansible is great to get started with IT Automation extremely fast. Its simplicity made it the most commonly adapted config management tool. But once our playbooks grow we need some more advanced techniques like tagging to maintain the speed.

A prerequisite for tagging is that we have to work out a strategy on how we want to use them. And that strategy has to be consistent with all our tasks. A tagging strategy always involves two steps.

Set tags

There are 3 types of tags that we can use.

Normal tag

Normal tags that can be used standalone or in conjunction with “always” or “never”

Always

Tasks with the “always” tag will always be executed unless we skip them explicitly. That allows us to work with a blacklisting strategy.

Never

Tasks with the “never” tag will never be executed unless we call them explicitly. That allows us to work with a whitelisting strategy.

Use tags

When we run our playbook we have to be consistent with our strategy. We can either call tasks explicitly with the --tags option or we can skip tags with the --skip-tags option.

To make that more clear let’s try that with a simple example.

---
- name: Tagging examples
  gather_facts: no
  hosts: localhost
  tasks:
    - debug:  
        msg: "Task 1"
      tags: 
        - task1
    - debug:  
        msg: "Task 2"
      tags: 
        - task2
    - debug:  
        msg: "Task 3"
      tags: 
        - task3          

The default behaviour is to run all tags (which equals --tags all)

$ ansible-playbook playbook.yml
PLAY [Tagging examples] ***********************************************************************************************

TASK [debug] **********************************************************************************************************
ok: [localhost] => {
    "msg": "Task 1"
}

TASK [debug] **********************************************************************************************************
ok: [localhost] => {
    "msg": "Task 2"
}

TASK [debug] **********************************************************************************************************
ok: [localhost] => {
    "msg": "Task 3"
}

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

Now we execute the same playbook with a whitelisting strategy.

$ ansible-playbook playbook.yml --tags=task3
PLAY [Tagging examples] ***********************************************************************************************

TASK [debug] **********************************************************************************************************
ok: [localhost] => {
    "msg": "Task 3"
}

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

Let’s try it with a blacklisting strategy.

$ ansible-playbook playbook.yml --skip-tags=task3

[Tagging examples] ***********************************************************************************************

TASK [debug] **********************************************************************************************************
ok: [localhost] => {
    "msg": "Task 1"
}

TASK [debug] **********************************************************************************************************
ok: [localhost] => {
    "msg": "Task 2"
}

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

Now let us modify our playbook and add “always” and “never” tags.

---
- name: Tagging examples
  gather_facts: no
  hosts: localhost
  tasks:
    - debug:  
        msg: "Task 1"
      tags: 
        - task1
        - always
    - debug:  
        msg: "Task 2"
      tags: 
        - task2
    - debug:  
        msg: "Task 3"
      tags: 
        - task3
        - never

Now we run the same commands again.

Default behaviour:

$ ansible-playbook playbook.yml 
PLAY [Tagging examples] ***********************************************************************************************

TASK [debug] **********************************************************************************************************
ok: [localhost] => {
    "msg": "Task 1"
}

TASK [debug] **********************************************************************************************************
ok: [localhost] => {
    "msg": "Task 2"
}

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

Whitelisting:

$ ansible-playbook playbook.yml --tags=task3


Tagging examples] ***********************************************************************************************

TASK [debug] **********************************************************************************************************
ok: [localhost] => {
    "msg": "Task 1"
}

TASK [debug] **********************************************************************************************************
ok: [localhost] => {
    "msg": "Task 3"
}

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

Blacklisting:

PLAY [Tagging examples] ***********************************************************************************************

TASK [debug] **********************************************************************************************************
ok: [localhost] => {
    "msg": "Task 1"
}

TASK [debug] **********************************************************************************************************
ok: [localhost] => {
    "msg": "Task 2"
}

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

Settings tags is quite easy as most things in Ansible are. But that simplicity does not mean we do not have to think about what we are doing on a higher level. Without a clear tagging strategy we can easily mess things up even though they are simple.

Contact