Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.

like image 353
Rickkwa Avatar asked Feb 28 '17 17:02

Rickkwa


People also ask

How do you define extra vars 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 declare variables in Ansible inventory?

Variable Name Rules Ansible has a strict set of rules to create valid variable names. Variable names can contain only letters, numbers, and underscores and must start with a letter or underscore. Some strings are reserved for other purposes and aren't valid variable names, such as Python Keywords or Playbook Keywords.

How can variables be defined within a role in Ansible?

Ansible uses variables to manage differences between systems. With Ansible, you can execute tasks and playbooks on multiple different systems with a single command. To represent the variations among those different systems, you can create variables with standard YAML syntax, including lists and dictionaries.


1 Answers

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
    
like image 125
techraf Avatar answered Oct 10 '22 23:10

techraf