Ansible handler with when condition

So I have this playbook

- hosts: localhost
  gather_facts: no
  vars:
    this_thing_is_true: true
    use_handler: false

  tasks:
    - debug:
        msg: 'Notifying handlers'
      changed_when: this_thing_is_true
      notify:
        - me

  handlers:
    - name: me
      debug:
        msg: 'I have been notified'
      when: use_handler is true

And when I run it, as expected, the handler doesn’t run.

# ansible-playbook handler.yml

PLAY [localhost] ***************************************************************

TASK [debug] *******************************************************************
changed: [localhost] => {
    "msg": "Notifying handlers"
}

RUNNING HANDLER [me] ***********************************************************
skipping: [localhost]

I can activate the handler by changing the use_handler variable in the playbook.

 # ansible-playbook handler.yml  
PLAY [localhost] ***************************************************************

TASK [debug] *******************************************************************
changed: [localhost] => {
    "msg": "Notifying handlers"
}

RUNNING HANDLER [me] ***********************************************************
ok: [localhost] => {
    "msg": "I have been notified"
}

However, I thought this would also activate the handler … but it doesn’t.

# ansible-playbook -e use_handler=true handler.yml


PLAY [localhost] ***************************************************************

TASK [debug] *******************************************************************
changed: [localhost] => {
    "msg": "Notifying handlers"
}

RUNNING HANDLER [me] ***********************************************************
skipping: [localhost]

Am I doing something wrong?

The problem is that it’s impractical to pass a bool into a run with key=value style extra variables on the command line. To set a bool, you’ll need to use JSON. Behold:

[utoddl@tango ansible]$ ansible localhost -e use_handler=true -m debug -a '{"msg": "{{ use_handler | type_debug }}"}'
localhost | SUCCESS => {
    "msg": "str"
}
[utoddl@tango ansible]$ ansible localhost -e '{"use_handler": true}' -m debug -a '{"msg": "{{ use_handler | type_debug }}"}'
localhost | SUCCESS => {
    "msg": "bool"
}

See this:

Use the JSON format if you need to pass non-string values such as Booleans, integers, floats, lists, and so on.

2 Likes

Thank you very much.

I will also note that this construct also worked, since it uses a string and not a boolean

  when: use_handler == 'true'

While that does work, if you plan to use strings, I’d recommend you make them look like strings rather than Booleans. We spent days one time disentangling a rat’s nest of strings, bools, and strings-as-bools. The amazing thing is that it worked as long as we didn’t fix any single obvious error!

Anyway, consider something like

when: handler_state | default('disabled') == 'enabled'

It’s easy to get right on the command line in either key=value or JSON form, and doesn’t tax your brain to read later.

Cheers.

4 Likes

I want to add (because I learned that the hard way) that you should always transform your “bool” variable with the bool filter in the playbook. If one day you decide to use AWX/AAP, your variable will always be a string even if you thought you send a bool.

So the correct way to write your line:

when: use_handler is true

is:

when: use_handler | bool is true

Or even better (and supported since Ansible 2.10):

when: use_handler is truthy(convert_bool=True)

From the documentation: Tests — Ansible Documentation

4 Likes

Is that practically any different from:

when: use_handler | bool

I’ve been using this form, I’ll add is true if that might make a difference in some circumstances?

They are not functionally different.

ansible-lint will berate you mercilessly for the redundant is true bit.

If you stick with bools rather than strings, use Laurent’s suggestion and use the truthy test.

(In fact, consider marking that post as the solution. It makes the admins happy, and @laurent-indermuehle could use the quatloos.)

1 Like

As one Python poem taught me: Explicit is better than implicit.

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.