cross-role notifications

HI!

In the spirit of encapsulation I've implemented different roles installing different
components.

Now the roles also ensure that OS packages (.deb or .rpm) and specific Python modules
(pip install) are installed and automagically updated.
(I don't want to start a debate whether one wants automatic upgrades or not. I simply
want that.)

Within the roles OS package / PIP updates will notify the approriate handlers and
services managed within the same role will be restarted.

But some updates might also require restart of a service managed in a subsequently
invoked role which does not receive the notifications.
(In puppet I'd simply _subscribe_ to the resource to "pull" the notification.)

How to handle this case in ansible?

Ciao, Michael.

Ansible doesn't have something like subscribe so you'll have to use notify.
But you can notify a handler in another role since they are global.

Kai Stian Olstad wrote:

AFAIK the role design is built so you could reuse roles in more than
one place. E.g. create a role that just installs nginx, and is set as
a dependency for the roles creating a webserver with nginx, a load
balancer with nginx, etc. This way you would have to put together the
installation steps in only one role, not in multiple roles.

The solution to your notify dilemma maybe a delegate_to in the
handler. Or duplicating the handler in your role.

Maybe we could help better if we knew what problem you are solving, or
what applications need your to call your handler in another role...

Johannes

The same challenge you have with subscribe in Puppet, you'll need to use the other resources name.

You can always create the handler in the role so you don't need to use the other roles handler, that's what I do to make them independent.

Kai Stian Olstad wrote:

Kai Stian Olstad wrote:

But some updates might also require restart of a service managed in a subsequently
invoked role which does not receive the notifications.
(In puppet I'd simply _subscribe_ to the resource to "pull" the notification.)

How to handle this case in ansible?

Ansible doesn't have something like subscribe so you'll have to use notify.
But you can notify a handler in another role since they are global.

But then a role has to know the handler names in the other role which somewhats
contradicts the concept of modular design.

The same challenge you have with subscribe in Puppet, you'll need to use the other
resources name.

Yes. But the resource name would be the OS package's name which the relevant roles would
know anyway. (I'm not a puppet fan though.)

You can always create the handler in the role so you don't need to use the other roles
handler, that's what I do to make them independent.

I'll try explain better.

Assume a play invoking two roles A and B:

role A
  - installs pkg1 with notifying "restart srv1" in case of a package update
  - enables and initially starts service srv1
  - has handler "restart srv1" which restarts service srv1

role B
  - installs *pkg1* with notifying "restart srv2" in case of a package update
  - enables and initially starts service srv2
  - has handler "restart srv2" which restarts service srv2

When role A gets played the handler "restart srv1" will receive the notification of pkg1
update but in role B there will be no such pkg1 update anymore and thus no notification
to handler "restart srv2" and therefore srv2 continous to run based on outdated software
(which I'd like to avoid).

Or can I have handlers with same name "restart srv1 and srv2" in more than role and all
gets notified?

Ciao, Michael.

Johannes Kastl wrote:

But then a role has to know the handler names in the other role
which somewhats contradicts the concept of modular design.

AFAIK the role design is built so you could reuse roles in more than
one place. E.g. create a role that just installs nginx, and is set as
a dependency for the roles creating a webserver with nginx, a load
balancer with nginx, etc. This way you would have to put together the
installation steps in only one role, not in multiple roles.

Yes I know. But the world is a bit more complicated.

Two different roles could require and thus update the same OS packages (in my case Python
modules). Completely *different* services managed in different roles would have to be
restarted.

The solution to your notify dilemma maybe a delegate_to in the
handler. Or duplicating the handler in your role.

Maybe we could help better if we knew what problem you are solving, or
what applications need your to call your handler in another role...

See also my other recent posting.

Ciao, Michael.

If you have handlers with the same name only one of them will be notified (see the note in the link bellow).
But in Ansible 2.2 notify has a listen: feature.

If you add listen: 'restart srv" to the handlers "restart srv1" and "restart srv2", then you can use notify: 'restart srv" instead and both of them will get notified.
And if you remove role A or role B it will still work.

Read more about listen: here
https://docs.ansible.com/ansible/playbooks_intro.html#handlers-running-operations-on-change

Kai Stian Olstad wrote:

But in Ansible 2.2 notify has a listen: feature.

If you add listen: 'restart srv" to the handlers "restart srv1" and "restart srv2",
then you can use notify: 'restart srv" instead and both of them will get notified.
And if you remove role A or role B it will still work.

Thanks for this hint! I'll give it a try.

Ciao, Michael.