Set Ansible variable to undefined through extra-vars or inventory variable

Rickkwa picture Rickkwa · Feb 28, 2017 · Viewed 18.3k times · Source

So I have an Ansible playbook that looks like

---
- hosts: mygroup
  tasks:
    - debug:
        msg: "{{ foo | default(inventory_hostname) }}"

My inventory file looks like

[mygroup]
127.0.0.1

Since foo is not defined anywhere, the debug prints 127.0.0.1 as expected.

But suppose my inventory file looks like

[mygroup]
127.0.0.1 foo=null

When I run the playbook, it prints out the string null. I also tried with foo=None and it prints an empty string. How can set the variable to null through inventory or extra-vars?

This may be useful when I want to unset a variable already defined in a playbook.

I am using Ansible version 2.1.1.0.

Answer

techraf picture techraf · Mar 1, 2017

Python (hence Ansible) differentiates between an undefined variable and a variable with the none value.

There is no way to "undefine" a variable once it has been defined.

In result even if you set the value to none, the condition you specified will never consider the variable as undefined.

You get a "" in the output log because this is how debug module displays the none-value, not because it's an empty string.

Solution 1

Use a ternary operator with the condition to check for the actual value of foo variable:

- debug:
    msg: "{{ ((foo is defined) and (foo != None)) | ternary(foo, inventory_hostname) }}"

Solution 2

Use a "wrapper" dictionary:

  1. Define a default value for the variable inside a "wrapper" dictionary:

    foodict:
      foo: bar
    
  2. In the play refer the variable as foodict.foo:

    ---
    - hosts: mygroup
      tasks:
        - debug:
            msg: "{{ foodict.foo | default(inventory_hostname) }}"
    
  3. Override the value in the inventory file by nullifying the "wrapper" dictionary:

    [mygroup]
    127.0.0.1 foodict=None