Tags not applied in Ansible included role

ansibleansible-playbook

I created a simple Ansible playbook:

---
- hosts: all

  tasks:
    - name: Install Icinga2 on Windows
      include_role:
        name: my.icinga2.role
        apply:
          tags:
            - install-icinga2

The role contains this tasks file:

---
- include_tasks: vars.yml
  tags: ['always']

- include_tasks: install.yml
  tags: ['install-icinga2-stack', 'install-icinga2']

- include_tasks: ido-install.yml
  when: icinga2_ido_enable == true
  tags: ['install-icinga2-stack', 'install-icinga2-ido']  

- include_tasks: configure.yml
  tags: ['install-icinga2-stack']

[...]

This is the result when I execute the playbook:

me@ansible:~/ansible$ ansible-playbook plays/icinga2-client-win.yml -i staging.ini --limit windows


PLAY [all] ***************************************************************************************************

TASK [Gathering Facts] ***********************************************************************************************************
ok: [my.windows.client]

TASK [Include variables for Icinga 2] ********************************************************************************************
ok: [my.windows.client]

TASK [set_fact] ******************************************************************************************************************
skipping: [my.windows.client]

TASK [set_fact] ******************************************************************************************************************
ok: [my.windows.client]

TASK [Install Icinga2 Client and connect it to the master server] ****************************************************************

TASK [my.icinga2.role : include_tasks] ***************************************************************************************
included: /home/me/ansible/roles/internal/my.icinga2.role/tasks/vars.yml for my.windows.client

TASK [my.icinga2.role : Set default fact for mysql command] ******************************************************************
ok: [my.windows.client]

TASK [my.icinga2.role : Set fact for mysql command if auth params are given] *************************************************
skipping: [my.windows.client]

TASK [my.icinga2.role : Set Monitoring Plugins for old Debian Versions] ******************************************************
skipping: [my.windows.client]

TASK [my.icinga2.role : include_tasks] ***************************************************************************************
included: /home/me/ansible/roles/internal/my.icinga2.role/tasks/install.yml for my.windows.client

TASK [my.icinga2.role : include_tasks] ***************************************************************************************
skipping: [my.windows.client]

TASK [my.icinga2.role : include_tasks] ***************************************************************************************
skipping: [my.windows.client]

TASK [my.icinga2.role : include_tasks] ***************************************************************************************
included: /home/me/ansible/roles/internal/my.icinga2.role/tasks/install-Windows.yml for my.windows.client

TASK [my.icinga2.role : set_fact] ********************************************************************************************
ok: [my.windows.client]

TASK [my.icinga2.role : set_fact] ********************************************************************************************
skipping: [my.windows.client]

TASK [my.icinga2.role : Install Icinga 2] ************************************************************************************
changed: [my.windows.client]

TASK [my.icinga2.role : include_tasks] ***************************************************************************************
skipping: [my.windows.client]

TASK [my.icinga2.role : include_tasks] ***************************************************************************************
included: /home/me/ansible/roles/internal/my.icinga2.role/tasks/configure.yml for my.windows.client

TASK [my.icinga2.role : Check if Icinga 2 API are already activated] *********************************************************
[ This should not be included! ]

RUNNING HANDLER [my.icinga2.role : Restart Icinga2 on Windows] ***************************************************************
    to retry, use: --limit @/home/me/ansible/plays/icinga2-client-win.retry

PLAY RECAP ***********************************************************************************************************************
my.windows.client   : ok=10   changed=1    unreachable=0    failed=1 

Why the configure.yml role task file is included as it should be included only if I apply the install-icinga2-stack tag and I'm applying the install-icinga2 one?

Further I realise that the ido-install.yml role task file is not included just because the icinga2_ido_enable variable is not true in this playbook (and its default is false), not because one of its tags is not applied (which should be what I want).

Where I'm wrong?

Best Answer

The application of tags in include_role means that tags

will be applied to the tasks within the include.

In other words, the tasks in the included role will inherit the applied tags. It's a misunderstanding to expect that the applied tags will select the tasks. To select the tasks use --tags and --skip-tags on the command line, or in Ansible configuration settings, use the TAGS_RUN and TAGS_SKIP options.

One important fact is not mentioned explicitly in the documentation of include_role. The parameter apply tags works only if the whole task is tags: always. This is only shown in the examples.

    - name: Apply tags to tasks within included file
      include_role:
        name: install
        apply:
          tags:
            - install
      tags:
        - always

Example

Let's have role1 with the 2 tasks

    shell> cat roles/role1/tasks/main.yml 
    - debug:
        msg: 'This is task 2'
      tags: task2
    
    - debug:
        msg: 'This is task 3'
      tags: task3

and a playbook

    shell> cat play1.yml 
    - hosts: localhost
      tasks:
        - debug:
            msg: 'This is task 1'
          tags: task1

        - include_role:
            name: role1
            apply:
              tags: role1
          tags: always

If we run the playbook without any options all tasks are included

    shell> ansible-playbook play1.yml | grep msg
        "msg": "This is task 1"
        "msg": "This is task 2"
        "msg": "This is task 3"

See other variations below

    shell> ansible-playbook play1.yml --tags task1 | grep msg
        "msg": "This is task 1"
    shell> ansible-playbook play1.yml --tags task2 | grep msg
        "msg": "This is task 2"
    shell> ansible-playbook play1.yml --tags role1 | grep msg
        "msg": "This is task 2"
        "msg": "This is task 3"
    shell> ansible-playbook play1.yml --skip-tags role1 | grep msg
        "msg": "This is task 1"
    shell> ansible-playbook play1.yml --tags role1 --skip-tags task2 | grep msg
        "msg": "This is task 3"

Note. The listing of tags does not work as expected.

    shell> ansible-playbook play1.yml --list-tags
    playbook: play1.yml
      play #1 (localhost): localhost    TAGS: []
          TASK TAGS: [always, task1]

(For the record: include_role with apply tags does not work #52063)

Related Topic