Setup
I have several roles which declare role dependencies and sometimes use handlers from roles they depend on. A simplified version of my setup looks like this (This is the output of head inventory **/*.yml
and it shows all path names and the full contents of the files):
==> inventory <==
[app]
server1 ansible_host=192.168.2.113
[db]
server2 ansible_host=192.168.2.153
==> playbook.yml <==
- hosts: all
roles:
- { role: app, when: "inventory_hostname in groups['app']" }
- { role: db, when: "inventory_hostname in groups['db']" }
==> roles/app/handlers/main.yml <==
- name: app handler
command: echo app handler
==> roles/app/meta/main.yml <==
dependencies: [base]
==> roles/app/tasks/main.yml <==
- command: /bin/true
notify: [app handler, base handler]
==> roles/base/handlers/main.yml <==
- name: base handler
command: echo base handler
==> roles/base/tasks/main.yml <==
- command: /bin/true
==> roles/db/handlers/main.yml <==
- name: db handler
command: echo db handler
==> roles/db/meta/main.yml <==
dependencies: [base]
==> roles/db/tasks/main.yml <==
- command: /bin/true
notify: [db handler, base handler]
Now I run ansible-playbook -i inventory playbook.yml
which results in
PLAY [all] **********************************************************************
TASK [Gathering Facts] **********************************************************
ok: [server1]
ok: [server2]
TASK [base : command] ***********************************************************
skipping: [server2]
changed: [server1]
TASK [app : command] ************************************************************
skipping: [server2]
changed: [server1]
TASK [base : command] ***********************************************************
changed: [server2]
TASK [db : command] *************************************************************
skipping: [server1]
changed: [server2]
RUNNING HANDLER [base : base handler] *******************************************
skipping: [server2]
changed: [server1]
RUNNING HANDLER [app : app handler] *********************************************
changed: [server1]
RUNNING HANDLER [db : db handler] ***********************************************
changed: [server2]
PLAY RECAP **********************************************************************
server1 : ok=5 changed=4 unreachable=0 failed=0
server2 : ok=4 changed=3 unreachable=0 failed=0
Problem
My problem is that I expected both servers to execute the base handler. But apparently it is skipped on server2. If I add -v
to the ansible command I get the unhelpful comment that skipping: [server2] => {"changed": false, "skip_reason": "Conditional result was False"}
.
What also puzzles me is that the base role seems to be included twice and each server skips one or the other inclusion of the role respectively.
Question
- Is there any way I can ensure that the handlers are fired correctly?
EDIT
- Is it a bug that the handler is not fired or is that behavior documented somewhere?
/EDIT
minor questions
- Is there any way to declare dependencies in a way that does not yield many inclusions which are only picked up by one server and ignored by all others although the others will include the same role through their own dependencies at some other point? This results in a lot of skipped tasks when I have some more servers and roles. (after reading the docs on role inclusion I suspect not)
- Is there some other way to handle role dependencies and handlers with ansible? I came up with this setup after reading https://medium.com/@ibrahimgunduz34/parallel-playbook-execution-in-ansible-30799ccda4e0
Sidenote
I would like to avoid the group_by
technique described in the docs, or more generally executing each role in their own playbook for the correct subset of the servers only, because I have a lot of servers and I want to speed up the run of the playbook by using strategy: free
.