TL;Dr: yes indeed in the case explained in the question (the implicit tagging at the level of the ansible role, makes the tagging of the individual task/block inside of the role unnecessary and hence superfluous).
Longer information:
Ansible, sadly invites often overly complicated and contorted syntax and style. In this very case it was only an unnecessary duplicate tagging, combined with an equally not necessary using of the syntactical element of a block
(in ansible playbook).
How was the behaviour of ansible with regards to tagging verified/tested? => with a shell/bash sctipt:
I have resorted to this shell script that should test, how ansible tags
behave in relationship to this implicit inheritance with respect to roles.
the bash script will create an minimal ansible test case, which
contains two roles role1
and role2
, both being verbatim copies
with exception of the name (so to be able to tell them appart) and
with 2 tasks:
task(A)
is not explicitly tagged
task(B)
is explicitly tagged with the tag 'tag01'.
A necessary ansible playbook.yml
and host/inventory file inventory.ini
is also
created in the script:
#!/bin/bash
#make a temporary directory for test
TEMPDIR="$(mktemp -d)"
#change to temporary directory
cd "$TEMPDIR"
# create ansible hosts file "./inventory.ini"
# only host we need is the the local box (to be simple disregard any ssh overhead)
cat > inventory.ini <<'EOF'
[hosts]
localhost ansible_connection=local
EOF
# create ansilble role "role1"
# (to keep it simple, we have minimal role with only a tasks entry)
mkdir -p roles/role1/tasks
# (the content for the tasks/main.yml file are two tasks, with one task
# namely task(A) not being explicitly and the task(B) being explicitly
# tagged)
cat > roles/role1/tasks/main.yml <<'EOF'
---
# tasks file for role1 and role2
- name: "task(A) tagged not explicitly 'tag01'"
debug:
msg: "debug-msg: this is \"task(A) tag explicitly 'tag01'\" {{ role_name }} ."
- name: "task(B) tagged explicitly 'tag01'"
debug:
msg: "debug-msg: this is \"task(B) tagged explicitly 'tag01'\" {{ role_name }} ."
tags:
- tag01
EOF
# create ansible role "role2" as a verbatim copy of "role1"
cp -r roles/role1 roles/role2
# now create an ansible playbook that uses these two ansible roles
# (note that for the role "role1" we used "implicit tagging"
cat > playbook.yml <<'EOF'
---
- hosts: all
roles:
- role: "role1"
tags:
- "tag01"
- role: "role2"
EOF
# show the test setup
find .
# TEST 1:
# run "playbook.yml" one time "as is" ( i.e. no using of tags -> "all tasks"
# should be run)
echo "TEST1" | tee TEST1
ansible-playbook -i inventory.ini playbook.yml | tee -a TEST1
# TEST 2:
# run "playbook.yml" with --tags command line options ( meaning this time
# we limit the task to be run to only those that have the specific tag)
echo "TEST2" | tee TEST2
ansible-playbook -i inventory.ini --tags 'tag01' playbook.yml | tee -a TEST2
# TEST 3:
# run "playbook.yml" with --skip-tags command line options ( meaning this time
# we limit the task to be run all, but those to tags to be "skipped")
echo "TEST3" | tee TEST3
ansible-playbook -i inventory.ini --skip-tags 'tag01' playbook.yml | tee -a TEST3
# show path of temporary directory
echo "TEMPDIR is $TEMPDIR"
Having run this shell script it basically yields three results for
- Test 1 "TEST1",
ansible-playbook -i inventory.ini playbook.yml
: no tags usage => any implicit or explicit tagging is of no concurn all tasks for both roles role1
and role2
are run:
TEST1
PLAY [all] **************************************************************************
TASK [Gathering Facts] **************************************************************************
ok: [localhost]
TASK [role1 : task(A) tagged not explicitly 'tag01'] **************************************************************************
ok: [localhost] => {
"msg": "debug-msg: this is \"task(A) tag explicitly 'tag01'\" role1 ."
}
TASK [role1 : task(B) tagged explicitly 'tag01'] **************************************************************************
ok: [localhost] => {
"msg": "debug-msg: this is \"task(B) tagged explicitly 'tag01'\" role1 ."
}
TASK [role2 : task(A) tagged not explicitly 'tag01'] **************************************************************************
ok: [localhost] => {
"msg": "debug-msg: this is \"task(A) tag explicitly 'tag01'\" role2 ."
}
TASK [role2 : task(B) tagged explicitly 'tag01'] **************************************************************************
ok: [localhost] => {
"msg": "debug-msg: this is \"task(B) tagged explicitly 'tag01'\" role2 ."
}
PLAY RECAP **************************************************************************
localhost : ok=5 changed=0 unreachable=0 failed=0
- Test 2 "TEST2",
ansible-playbook -i inventory.ini --tags 'tag01' playbook.yml
: tags are used => implicit and explicit tagging matters. Since
tag01
is set for role1
at level of the role
both contained tasks task(A) and task(B)
are run. Contrastingly for role2
without the implictely inherited tagging only task(B)
is run. The output shows that:
TEST2
PLAY [all] **************************************************************************
TASK [Gathering Facts] **************************************************************************
ok: [localhost]
TASK [role1 : task(A) tagged not explicitly 'tag01'] **************************************************************************
ok: [localhost] => {
"msg": "debug-msg: this is \"task(A) tag explicitly 'tag01'\" role1 ."
}
TASK [role1 : task(B) tagged explicitly 'tag01'] **************************************************************************
ok: [localhost] => {
"msg": "debug-msg: this is \"task(B) tagged explicitly 'tag01'\" role1 ."
}
TASK [role2 : task(B) tagged explicitly 'tag01'] **************************************************************************
ok: [localhost] => {
"msg": "debug-msg: this is \"task(B) tagged explicitly 'tag01'\" role2 ."
}
PLAY RECAP **************************************************************************
localhost : ok=4 changed=0 unreachable=0 failed=0
- Lastly the Test 3 "TEST3" inverts all with
--skip-tags
where the implicit tagging for role1
causes the whole role to be skipped. For ansible-playbook -i inventory.ini --skip-tags 'tag01' playbook.yml
we have the following result:
TEST3
PLAY [all] **************************************************************************
TASK [Gathering Facts] **************************************************************************
ok: [localhost]
TASK [role2 : task(A) tagged not explicitly 'tag01'] **************************************************************************
ok: [localhost] => {
"msg": "debug-msg: this is \"task(A) tag explicitly 'tag01'\" role2 ."
}
PLAY RECAP **************************************************************************
localhost : ok=2 changed=0 unreachable=0 failed=0
In conclusion and to keep close with the topic of the question, the a tag for a task contained in a role, is superflous, if that very role
is (a) already tagged itself in the playbook
and hence makes all its task implicitly inherit the task and b) this is the only playbook
the role is used anyway (as it was the case here).
Although the ouput can be generated via executing the shell script provided here its output as a courtesy and for being complete:
.
./playbook.yml
./roles
./roles/role2
./roles/role2/tasks
./roles/role2/tasks/main.yml
./roles/role1
./roles/role1/tasks
./roles/role1/tasks/main.yml
./inventory.ini
TEST1
PLAY [all] **************************************************************************
TASK [Gathering Facts] **************************************************************************
ok: [localhost]
TASK [role1 : task(A) tagged not explicitly 'tag01'] **************************************************************************
ok: [localhost] => {
"msg": "debug-msg: this is \"task(A) tag explicitly 'tag01'\" role1 ."
}
TASK [role1 : task(B) tagged explicitly 'tag01'] **************************************************************************
ok: [localhost] => {
"msg": "debug-msg: this is \"task(B) tagged explicitly 'tag01'\" role1 ."
}
TASK [role2 : task(A) tagged not explicitly 'tag01'] **************************************************************************
ok: [localhost] => {
"msg": "debug-msg: this is \"task(A) tag explicitly 'tag01'\" role2 ."
}
TASK [role2 : task(B) tagged explicitly 'tag01'] **************************************************************************
ok: [localhost] => {
"msg": "debug-msg: this is \"task(B) tagged explicitly 'tag01'\" role2 ."
}
PLAY RECAP **************************************************************************
localhost : ok=5 changed=0 unreachable=0 failed=0
TEST2
PLAY [all] **************************************************************************
TASK [Gathering Facts] **************************************************************************
ok: [localhost]
TASK [role1 : task(A) tagged not explicitly 'tag01'] **************************************************************************
ok: [localhost] => {
"msg": "debug-msg: this is \"task(A) tag explicitly 'tag01'\" role1 ."
}
TASK [role1 : task(B) tagged explicitly 'tag01'] **************************************************************************
ok: [localhost] => {
"msg": "debug-msg: this is \"task(B) tagged explicitly 'tag01'\" role1 ."
}
TASK [role2 : task(B) tagged explicitly 'tag01'] **************************************************************************
ok: [localhost] => {
"msg": "debug-msg: this is \"task(B) tagged explicitly 'tag01'\" role2 ."
}
PLAY RECAP **************************************************************************
localhost : ok=4 changed=0 unreachable=0 failed=0
TEST3
PLAY [all] **************************************************************************
TASK [Gathering Facts] **************************************************************************
ok: [localhost]
TASK [role2 : task(A) tagged not explicitly 'tag01'] **************************************************************************
ok: [localhost] => {
"msg": "debug-msg: this is \"task(A) tag explicitly 'tag01'\" role2 ."
}
PLAY RECAP **************************************************************************
localhost : ok=2 changed=0 unreachable=0 failed=0
TEMPDIR is /tmp/tmp.cPE6a4gGiG