Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ansible: pass variable to a handler

I use an "eye" as a supervisor and on changes in templates have to runs something like this:

eye load service.rb
eye restart service.rb

I want to define this as a single handler for all the apps and call it like

eye reload appname

And in a handler operate like this:

- name: reload eye service
command: eye load /path/{{ service }}.rb && eye restart {{ service }}

But I can't find a way to pass variable to a handler. Is it possible?

like image 790
hryamzik Avatar asked Oct 20 '14 22:10

hryamzik


People also ask

How do you pass variables in Ansible?

To pass a value to nodes, use the --extra-vars or -e option while running the Ansible playbook, as seen below. This ensures you avoid accidental running of the playbook against hardcoded hosts.

How do you use the handler in Ansible?

In a nutshell, handlers are special tasks that only get executed when triggered via the notify directive. Handlers are executed at the end of the play, once all tasks are finished. In Ansible, handlers are typically used to start, reload, restart, and stop services.

What is difference between tasks and handlers in Ansible?

Handlers are just like regular tasks in an Ansible playbook (see Tasks) but are only run if the Task contains a notify keyword and also indicates that it changed something. For example, if a config file is changed, then the task referencing the config file templating operation may notify a service restart handler.


1 Answers

Don't do this. I understand your desire to use Ansible as a programming tool, where 'handler' is a 'function' you 'call', but it's not.

You can invent a dozen of tricks to do what you want, but result would be a total mess, hard to read and even harder to debug.

The key issue is that ansible does not support 'argument passing' to anything (except for modules). All tricks you read about or invent by yourself will change global variable. If you ever wrote at least bit in any language , you know, that program where every function is using global variables (for read and write, and to pass arguments) is fundamentally flawed.

So, how to do this in a very good and readable Ansible?

Yes, just wrote a separate handler for each service. It's the cleanest and simplest Ansible. Easy to read, easy to change.

BTW: if you have to actions in a chain, do not join them with '&&'.

Use two separate handlers:

- foo:
  notify:
    - eye reload
    - eye restart foo

(note, that order of handlers is defined in the handlers list, not the 'notify' list).

Btw, if you have few services you will save on multiple reload operations - 'eye reload' would be called once.

like image 59
George Shuklin Avatar answered Oct 19 '22 19:10

George Shuklin