Using tags to express Ansible tasks dependencies

Everything is simple when we write a playbook that does one thing. We have a powerful tool for expressing dependencies: the task order. But sometimes we want more than one target. We want to deploy something, then cleanup something. Or even build something else. For example, we may want a standard CI/CD workflow:
Build a Docker image from source.
Push the image to a registry.
Update a K8s deployment with the new image.
The playbook structure would be:
- name: Build image...
- name: Push to a registry...
- name: Update deployment...
Now, your boss comes and says "don't publish anything before I tell you so". We add tags to run tasks separately:
- name: Build image...
tags: [build]
- name: Push to registry...
tags: [publish]
- name: Update deployment...
tags: [deploy]
Almost there. We can do everything we want, but we need to specify multiple tags. You can create a serious mess this way. So, the third and final approach is to populate a tag to every tag we're dependent on:
- name: Build image...
tags: [build, publish, deploy]
- name: Push to registry...
tags: [publish, deploy]
- name: Update deployment...
tags: [deploy]
Here you go. If you want to deploy all - use tag 'deploy'. For build only - 'build'. That would be it, except for one caveat. We don't want to run unnecessary tasks. Theoretically - it shouldn't be a problem. Ansible modules are meant to be idempotent. It means - we can run a task any number of times we want - the result should be the same. But sometimes we're wasting our time. Then it would be good to have a 'when' clause to check whether running a task is really necessary.
And one bonus thing. If you create a complex playbook with multiple targets, having a default workflow, without tags makes no sense. For example, you don't want to build something then destroy it. In that case - use a default tag guard:
pre_tasks:
- name: Default tag guard
assert:
that: "'all' not in ansible_run_tags"
msg: No default tasks here.
Thanks for the audience. I hope I managed to write something which is not obvious for everyone.



