Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ansible Handler notify vs register

So after reading Ansible docs, I found out that Handlers are only fired when tasks report changes, so for example:

some tasks ...
notify: nginx_restart

# our handler
- name: nginx_restart

vs

some tasks ...
register: nginx_restart

# do this after nginx_restart changes
when: nginx_restart|changed

Is there any difference between these 2 methods? When should I use each of them? For me, register seems to have more functionality here, unless I am missing something...

like image 232
huygn Avatar asked Nov 26 '15 06:11

huygn


People also ask

What is notify and Handler in Ansible?

In Ansible, a handler refers to a particular task that executes when triggered by the notify module. Handlers perform an action defined in the task when a change occurs in the remote host. Handlers are helpful when you need to perform a task that relies on a specific task's success or failure.

What is use of notify in Ansible?

Notifying handlersNotifying the same handler multiple times will result in executing the handler only once regardless of how many tasks notify it. For example, if multiple tasks update a configuration file and notify a handler to restart Apache, Ansible only bounces Apache once to avoid unnecessary restarts.

What is the purpose of handlers in Ansible?

In Ansible, handlers are typically used to start, reload, restart, and stop services. If your playbook involves changing configuration files, there is a high chance that you'll need to restart a service so that the changes take effect.

What is register in Ansible?

Ansible register is a way to capture the output from task execution and store it in a variable. This is an important feature, as this output is different for each remote host, and the basis on that we can use conditions loops to do some other tasks. Also, each register value is valid throughout the playbook execution.


3 Answers

There are some differences and which is better depends on the situation.

Handlers will only be visible in the output if they have actually been executed. Not notified, there will be no skipped tasks in Ansibles output. Tasks always have output no matter if skipped, executed with change or without. (except they are excluded via tags/skip-tags)

Handlers can be called from any role. This gets handy if you have more complex roles which depend on each other. Let's say you have a role to manage iptables but which rules you define is actually depending on other roles (e.g. database role, redis role etc...) Each role can add their rules to a config file and at the end you notify the iptables role to reload iptables if changed.

Handlers by default get executed at the end of the playbook. Tasks will get executed immediately where they are defined. This way you could configure all your applications and at the end the service restart for all changed apps will be triggered per handler. This can be dangerous though. In case your playbook fails after a handler has been notified, the handler will actually not be called. If you run the playbook again, the triggering task may not have a changed state any longer, therefore not notifying the handler. This results in Ansible actually not being idempotent. Since Ansible 1.9.1 you can call Ansible with the --force-handler option or define force_handlers = True in your ansible.cfg to even fire all notified handlers after the playbook failed. (See docs)

If you need your handlers to be fired at a specific point (for example you configured your system to use an internal DNS and now want to resolve a host through this DNS) you can flush all handlers by defining a task like:

- meta: flush_handlers

A handler would be called only once no matter how many times it was notified. Imagine you have a service that depends on multiple config files (for example bind/named: rev, zone, root.db, rndc.key, named.conf) and you want to restart named if any of these files changed. With handlers you simply would notify from every single task that managed those files. Otherwise you need to register 5 useless vars, and then check them all in your restart task.

Personally I prefer handlers. It appears much cleaner than dealing with register. Tasks triggered per register was safer before Ansible 1.9.1.

like image 199
udondan Avatar answered Oct 17 '22 00:10

udondan


On the Ansible Variables page, you can see how register works.

Another major use of variables is running a command and using the result of that command to save the result into a variable.

Registered variables are just like facts:

Effectively registered variables are just like facts.

This is very different from notify, which triggers handlers. It does not save or store variables or facts.

like image 26
Felipe Alvarez Avatar answered Oct 16 '22 22:10

Felipe Alvarez


with ignore_errors: True you can avoid the failed handler from stopping other handlers defined after it continue to run

like image 3
Bruce Zu Avatar answered Oct 16 '22 22:10

Bruce Zu