Reputation: 596
I'm trying to definitively understand how tags are applied at role execution in Ansible.
I read the docs at https://docs.ansible.com/ansible/latest/user_guide/playbooks_tags.html#adding-tags-to-roles and tried with a test role:
~/ansible/roles/internal/test/tasks > cat tag-foo.yml
---
- import_tasks: tag-foo.yml
tags:
- foo
- foo2
- import_tasks: tag-bar.yml
tags:
- bar
- import_tasks: always.yml
tags:
- always
- import_tasks: never.yml
tags:
- never
- nevermind
~/ansible/roles/internal/test/tasks > cat tag-foo.yml
---
- name: This is tag 'foo'
debug:
msg: This is tag 'foo'
~/ansible/roles/internal/test/tasks > cat tag-bar.yml
---
- name: This is tag 'bar'
debug:
msg: This is tag 'bar'
~/ansible/roles/internal/test/tasks > cat always.yml
---
- name: This is tag 'always'
debug:
msg: This is tag 'always'
~/ansible/roles/internal/test/tasks > cat never.yml
---
- name: This is tag 'never'
debug:
msg: This is tag 'never'
I created a test playbook file:
~/ansible > cat plays/test.yml
- hosts: all
tasks:
- name: Execute test role with all tags
import_role:
name: test
tags: foo2
- name: Execute test role with tag 'foo'
import_role:
name: test
tags:
- foo
What I don't understand is that if I execute the playbook with the foo tag, the role is executed both times and not only one time executing only the tasks from tag-foo.yml
and the tag-always.yml
:
~/ansible > ansible-playbook -i test.ini plays/test.yml -l test.domain.local -t foo
PLAY [all] ********************************************************************************************************************************************
TASK [Gathering Facts] ********************************************************************************************************************************
ok: [test.domain.local]
TASK [test : This is tag 'foo'] ***********************************************************************************************************************
ok: [test.domain.local] => {
"msg": "This is tag 'foo'"
}
TASK [test : This is tag 'always'] ********************************************************************************************************************
ok: [test.domain.local] => {
"msg": "This is tag 'always'"
}
TASK [test : This is tag 'foo'] ***********************************************************************************************************************
ok: [test.domain.local] => {
"msg": "This is tag 'foo'"
}
TASK [test : This is tag 'bar'] ***********************************************************************************************************************
ok: [test.domain.local] => {
"msg": "This is tag 'bar'"
}
TASK [test : This is tag 'always'] ********************************************************************************************************************
ok: [test.domain.local] => {
"msg": "This is tag 'always'"
}
TASK [test : This is tag 'never'] *********************************************************************************************************************
ok: [test.domain.local] => {
"msg": "This is tag 'never'"
}
PLAY RECAP ********************************************************************************************************************************************
test.domain.local : ok=7 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
What I want is to force tags from a single import_role
statement without necessarily specifying it in the ansible-playbook
command.
Edit: I tried to replace the import_role
statement with include_role
into the playbook adding the apply
option to apply the foo
tag:
- name: Execute test role with tag 'foo'
include_role:
name: test
apply:
tags:
- foo
And I replaced import_tasks
statement in the main.yml
file of the role with include_tasks
:
---
- include_tasks: tag-foo.yml
tags:
- foo
- foo2
- include_tasks: tag-bar.yml
tags:
- bar
- include_tasks: always.yml
tags:
- always
- include_tasks: never.yml
tags:
- never
- nevermind
But unfortunately nothing changed: the 'bar' task is executed anyway:
~/ansible > ansible-playbook -i test.ini plays/test.yml -l test.domain.local
PLAY [all] ********************************************************************************************************************************************
TASK [Gathering Facts] ********************************************************************************************************************************
ok: [test.domain.local]
TASK [Execute test role with tag 'foo'] ***************************************************************************************************************
TASK [test : include_tasks] ***************************************************************************************************************************
included: /Users/me/ansible/roles/internal/test/tasks/tag-foo.yml for test.domain.local
TASK [test : This is tag 'foo'] ***********************************************************************************************************************
ok: [test.domain.local] => {
"msg": "This is tag 'foo'"
}
TASK [test : include_tasks] ***************************************************************************************************************************
included: /Users/me/ansible/roles/internal/test/tasks/tag-bar.yml for test.domain.local
TASK [test : This is tag 'bar'] ***********************************************************************************************************************
ok: [test.domain.local] => {
"msg": "This is tag 'bar'"
}
TASK [test : include_tasks] ***************************************************************************************************************************
included: /Users/me/ansible/roles/internal/test/tasks/always.yml for test.domain.local
TASK [test : This is tag 'always'] ********************************************************************************************************************
ok: [test.domain.local] => {
"msg": "This is tag 'always'"
}
PLAY RECAP ********************************************************************************************************************************************
test.domain.local : ok=7 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Upvotes: 4
Views: 5558
Reputation: 11605
By using import_role
, it's static re-use, the tag doesn't condition the import, but is added to every tasks of the imported role.
To condition the execution of the role with a tag, you should use a dynamic re-use with the include_role
.
More documentation on import vs include: https://docs.ansible.com/ansible/latest/user_guide/playbooks_reuse.html#re-using-files-and-roles
Tags mechanism is made to be set through CLI.
If you want to define different behavior of role through playbook, vars
and when
are better option:
- include_role: my_role
vars:
only_foo: True
# in my_role:
- debug:
msg: Only on foo
when: only_foo
Upvotes: 2