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.