Chris F
Chris F

Reputation: 16695

Ansible tags not recognized during a play?

$ ansible --version
ansible 2.10.8

I have a playbook called site.yml that just contains other playbooks. Some playbooks I only want to ron when I use a --tags update tag, but some playbooks I want to run all the time, but only certain tasks tagged appropriately. In my example below, I want all the tasks on the prepare-update.yml playbook to only run on update tag, while I want to run the postgresql.yml playbook all the time. I then want to control some tasks to run or not in my postgresql role

- import_playbook: prepare-update.yml
  tags: update
- import_playbook: postgresql.yml

the posgresql.yml playbook simply contains a postgresql role

---
- hosts: "{{ var_host | default('exa_site') }}"
  become_method: runas

  roles:
    - postgresql

Now my postgresql role's tasks/main.yml has

---
# tasks file for postgresql
- include_tasks: install_postgresql.yml
- include_tasks: run_postgresql_queries.yml
- include_tasks: install_pgadmin4.yml

and my install_postgresql.yml task has these tasks. As you can see I use 3 different tags, namely new_install, update, and uninstall

- block:
  - name: Download app
    win_get_url: ...
  - name: Install app
    win_shell: ...
  tags: new_install

- name: Start service
  win_service: ...
  tags:
  - new_install
  - update

- block:
  - name: Stop service
    win_service: ...
  - name: Delete service
    win_file: ...
  tags: uninstall

When I run the following, I expect some tasks to run based on their tags.

$ ansible-playbook -i hosts.yml -e var_host=my_host --tags new_install site.yml

However, I just get this, where nothing runs.

PLAY [10.227.x.x] *******************************************************

TASK [Gathering Facts] **************************************************
ok: [10.227.x.x]

PLAY RECAP **************************************************************
10.227.x.x               : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

Why are my tasks tagged as new_install not being run at all?

Upvotes: 2

Views: 5106

Answers (2)

Vladimir Botka
Vladimir Botka

Reputation: 68044

(The solution is described in the other answer by @β.εηοιτ.βε)

To understand the logic of this problem two points are important:

  1. Quoting from Includes: dynamic re-use

"Ansible processes included files and roles as they come up in a playbook."

  1. Quoting from Adding tags to includes

"... tags on an include_* task apply only to the include itself, not to any tasks within the included file or role."

As a result, when --tags are declared (on the command-line or otherwise) a play will skip any include_* statement if tags (declared on this include_* statement) do not match. In other words, in this case, a play does not know what's inside an include until the play reaches the include statement and will never learn because it will be skipped.

Upvotes: 1

β.εηοιτ.βε
β.εηοιτ.βε

Reputation: 39149

This happens because your include_tasks are skipped, since they do not contain any tags matching new_install.

What you can do, if you don't want to repeat your lower level tags on the include_tasks, is to tag them with the special tag always.

So, the main.yml task of your role becomes:

## Using a block, so we can tag them all at once.
- block:
    - include_tasks: install_postgresql.yml
    - include_tasks: run_postgresql_queries.yml
    - include_tasks: install_pgadmin4.yml
  tags: always

Another way would be to import your tasks, rather, as this is the main difference between import_* and include_* modules.

So, once again, the main.yml task of your role changes to:

- import_tasks: install_postgresql.yml
- import_tasks: run_postgresql_queries.yml
- import_tasks: install_pgadmin4.yml

Note the difference of wording in the synopsis of the two modules:

  • import_tasks: Imports a list of tasks to be added to the current playbook for subsequent execution. source
  • include_tasks: Includes a file with a list of tasks to be executed in the current playbook. source

So, when one "blindly" imports for further execution, the other include them and run them at the same time.
With that in mind, it makes sense that the latter, include_tasks would be skipped if missing the proper tag, when the first one would place the tasks in the playbook and then, at the execution of the playbook, the tags on the imported tasks would be evaluated has you were expecting it.

Upvotes: 5

Related Questions