Reputation: 8797
Can I notify the handler in another role? What should I do to make ansible find it?
The use case is, e.g. I want to configure some service and then restart it if changed. Different OS have probably different files to edit and even the file format can be different. So I would like to put them into different roles (because the file format can be different, it can't be done by setting group_vars). But the way to restart the service is the same, using service
module; so I'd like to put the handler to common
role.
Is anyway to achieve this? Thanks.
Upvotes: 78
Views: 64008
Reputation: 748
I had a similar issue, but needed to take many actions in the other dependent roles
.
So rather than invoking the handler
- we set a fact like so:
- name: install mylib to virtualenv
pip: requirements=/opt/mylib/requirements.txt virtualenv={{ mylib_virtualenv_path }}
sudo_user: mylib
register: mylib_wheel_upgraded
- name: set variable if source code was upgraded
set_fact:
mylib_source_upgraded: true
when: mylib_wheel_upgraded.changed
Then elsewhere in another role
:
- name: restart services if source code was upgraded
command: /bin/true
notify: restart mylib server
when: mylib_source_upgraded
Upvotes: 4
Reputation: 83
Currently I'm using ansible v2.10.3 and it supports to call handlers
on different roles. This was because the handlers
are visible on the play-level, as per Ansible Docs says. You can see the docs mentioned that in the bottom-most point.
handlers are play scoped and as such can be used outside of the role they are defined in.
FYI, I tested the solution i.e. calling other role's handlers
and it works! No need to import or else, just make sure that the roles are in the same playbook execution.
To illustrate:
roles/vm/handlers/main.yaml
---
- name: rebootvm
ansible.builtin.reboot:
reboot_timeout: 600
test_command: whoami
roles/config-files/tasks/main.yaml
---
- name: Copy files from local to remote
ansible.builtin.copy:
dest: /home/ubuntu/config.conf
src: config.conf
backup: yes
force: yes
notify:
- rebootvm
So when the config file (i.e. config.conf
) changed, Ansible will send it to the remote location and it will notify the handler rebootvm
, then the VM is rebooted.
P.S. I don't know what version exactly Ansible support this.
Edit: code indentation fix
Upvotes: 2
Reputation: 3583
You may import additional handlers from YourRole/handlers/main.yml
file by using import_tasks
.
So, if MyRole
needs to call handlers in some OtherRole
, roles/MyRole/handlers/main.yml
will look like this:
- import_tasks: roles/OtherRole/handlers/main.yml
Of course roles/MyRole/handlers/main.yml
may include additional handlers as well.
This way if I want to run MyRole
without running tasks from the OtherRole
, ansible will be able to correctly import and run handlers from the OtherRole
Upvotes: 11
Reputation: 14116
You can also call handlers of a dependency role. May be cleaner than including files or explicitly listing roles in a playbook just for the purpose of role to role relationship. E.g.:
roles/my-handlers/handlers/main.yml
---
- name: nginx restart
service: >
name=nginx
state=restarted
roles/my-other/meta/main.yml
---
dependencies:
- role: my-handlers
roles/my-other/tasks/main.yml
---
- copy: >
src=nginx.conf
dest=/etc/nginx/
notify: nginx restart
Upvotes: 82
Reputation: 3234
You should be able to do that if you include the handler file.
Example:
handlers:
- include: someOtherRole/handlers/main.yml
But I don't think its elegant.
A more elegant way is to have a play that manages both roles, something like this:
- hosts: all
roles:
- role1
- role2
This will make both roles able to call other handlers.
But again I would suggest to make it all in one role and separate files and use a conditional include http://docs.ansible.com/playbooks_conditionals.html#conditional-imports
Hope that helps
Upvotes: 36