# Simpler way to define many handlers?

**URL:** <https://forum.ansible.com/t/simpler-way-to-define-many-handlers/38370>\
**Category:** Ansible Project\
**Created:** [August 24, 2023, 3:46pm UTC](https://forum.ansible.com/t/simpler-way-to-define-many-handlers/38370 "2023-08-24T15:46:58Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![dnmvisser](https://avatars.discourse-cdn.com/v4/letter/d/8e8cbc/32.png) [@dnmvisser](https://forum.ansible.com/u/dnmvisser)\
**Post date:** [August 24, 2023, 3:46pm UTC](https://forum.ansible.com/t/simpler-way-to-define-many-handlers/38370/1 "2023-08-24T15:46:58Z")

</div>

Hii,

I have a lot of handlers to restart services, like this:

- name: smbd\_restart  
ansible.builtin.service:  
name: smbd  
state: restarted

- name: chronyd\_restart  
ansible.builtin.service:  
name: chronyd  
state: restarted

- name: udhcpd\_restart  
ansible.builtin.service:  
name: udhcpd  
state: restarted

- name: dhcpcd\_restart  
ansible.builtin.service:  
name: dhcpcd  
state: restarted

- name: lighttpd\_restart  
ansible.builtin.service:  
name: lighttpd  
state: restarted

- name: sshd\_restart  
ansible.builtin.service:  
name: sshd  
state: restarted

- name: networking\_restart  
ansible.builtin.service:  
name: networking  
state: restarted

- name: hostapd\_restart  
ansible.builtin.service:  
name: hostapd  
state: restarted

etc etc

Another pile of them are there for the ‘reload’ state.

According to [https://docs.ansible.com/ansible/latest/playbook\_guide/playbooks\_handlers.html#using-variables-with-handlers](https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_handlers.html#using-variables-with-handlers)  
variables in handler names will likely not work, and variable in listen topic for sure don’t work.

Is there perhaps another way to avoid having a ton of very similar) handlers?

thx

Dick

---

<div class="post-metadata">

**Author:** ![Pierre\_Daheron](https://avatars.discourse-cdn.com/v4/letter/p/b3f665/32.png) [@Pierre\_Daheron](https://forum.ansible.com/u/Pierre_Daheron)\
**Post date:** [August 24, 2023, 4:29pm UTC](https://forum.ansible.com/t/simpler-way-to-define-many-handlers/38370/2 "2023-08-24T16:29:40Z")

</div>

Hi,

only the name seems to change. You could try to list the names of your services and then use a loop. See [https://docs.ansible.com/ansible/latest/playbook\_guide/playbooks\_loops.html](https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_loops.html)  
for examples.

Best regards  
Pierre

---

<div class="post-metadata">

**Author:** ![utoddl](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/utoddl/32/249_2.png) [@utoddl](https://forum.ansible.com/u/utoddl)\
**Post date:** [August 24, 2023, 6:24pm UTC](https://forum.ansible.com/t/simpler-way-to-define-many-handlers/38370/3 "2023-08-24T18:24:47Z")

</div>

I can envision a handler wanting to know for example which of its many possible “listen” strings it was notified by. But therein lies madness, as it could be notified by many different strings. As implemented (last time I looked), a notification results in adding a task to a host’s list of handlers to be run eventually - if it isn’t already on the list. There’s no record kept of any context per notification. Without that sort of metadata, I don’t see a way to implement “smart handlers”.

So lets step back a second and figure out just which problem you want to solve. True, there’s a lot of redundancy in the handlers you cited, so it does feel like there should be a more elegant way to express it. However, they don’t change often, and any one of them is simple enough to maintain.

What I find most compelling about your case is,“Another pile of them are there for the ‘reload’ state” because now you’ve got a slight difference between a couple of places to keep in sync. If this were C instead of YAML, you bet I’d use a preprocessor macro or three.

But this is YAML, and Jinja2, and the marvelous python freakenstein monster that is Ansible. So — and I’m not recommending this, but it _is_ another way to handle it, which is what you asked for — you could use an ansible.builtin.template step to produce a “roles/dynarole/handlers/no-regrets.yml” that contains all your service handlers, then dynamically include that role so that (I think this is how it works) those handlers would then be available for notification from any subsequent tasks in that play. You could split the playbook into a play to generate the handlers files, then subsequent plays to dynamically include or statically import them. Or you could have a separate play/playbook with the sole purpose of generating the largely redundant handlers file that you only run when your table of desired handlers - or the template that consumes it - changes.

I can’t honestly argue that this is a good idea. But so far I haven’t come up with any other suggestions. It’s tempting to try it, if only to say, “Here’s a cool thing that isn’t at all wrong that I’ll never do again.”

Do let us know if you come up with anything!

---

<div class="post-metadata">

**Author:** ![Cody\_Fawcett](https://avatars.discourse-cdn.com/v4/letter/c/e5b9ba/32.png) [@Cody\_Fawcett](https://forum.ansible.com/u/Cody_Fawcett)\
**Post date:** [August 24, 2023, 8:32pm UTC](https://forum.ansible.com/t/simpler-way-to-define-many-handlers/38370/4 "2023-08-24T20:32:49Z")

</div>

in the task that triggers the handler, is there a way to register a variable and then do a debug in the playbook only when the handler condition is met?

another thought, if the task that triggered the handler is important to track create a specific handler for it, but let the rest just use a generic reload/restart etc…

---

<div class="post-metadata">

**Author:** ![vbotka](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/vbotka/32/359_2.png) [@vbotka](https://forum.ansible.com/u/vbotka)\
**Post date:** [August 24, 2023, 10:10pm UTC](https://forum.ansible.com/t/simpler-way-to-define-many-handlers/38370/5 "2023-08-24T22:10:28Z")

</div>

It is not, IMHO, if you want to do it in a single run of a playbook.

It is possible to create handlers from meta-data and template(s) and  
then import them. Similar to the concept of the \*configure\* script  
[https://en.wikipedia.org/wiki/Configure\_script](https://en.wikipedia.org/wiki/Configure_script)

I'm not saying Ansible should generally adopt this concept. I think,  
in some cases such configuration might make the project robuster,  
simpler, and easily extendable. FWIW, it's feasible to control some  
projects by structured meta-data only  
[https://ansible-config-light.readthedocs.io/en/latest/qsg.html](https://ansible-config-light.readthedocs.io/en/latest/qsg.html)

---

<div class="post-metadata">

**Author:** ![dnmvisser](https://avatars.discourse-cdn.com/v4/letter/d/8e8cbc/32.png) [@dnmvisser](https://forum.ansible.com/u/dnmvisser)\
**Post date:** [October 8, 2023, 8:45pm UTC](https://forum.ansible.com/t/simpler-way-to-define-many-handlers/38370/6 "2023-10-08T20:45:30Z")

</div>

I eventually settled on having a dedicated role that contains all the handlers we use, and nothing else:

$ tree roles/handlers  
roles/handlers  
├── README.md  
└── handlers  
└── main.yml

That is then include early on in the plays:

tasks:

- name: Ensure shared handler role is imported  
ansible.builtin.import\_role:  
name: handlers

It is a bit clunky but it does work and at least the handlers are defined only once.

Dick
