Ansible not executing handlers from dependency roles for all hosts

1.2k Views Asked by At

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.

0

There are 0 best solutions below