UNDEF Keyword in Ansible

Viewed 483

In Ansible, I am trying to use UNDEF keyword for a undefined variable in Ansible to overwrite with a default value when the variable itself is not defined based on the link provided here reference document for Ansible

And to my dismay, did not see any practical example of a playbook or a role using this. Is there anyone has practical example which uses UNDEF keyword for a variable and defining with a default value when the variable is not defined?

I have already used not defined and undefined when conditions using jinja 2 templating. This is more about the UNDEF keyword itself.

1 Answers

You are kind of mixing two things here:

  • The possibility to have a custom hint in the error Ansible would raise when a variable is undefined, with the undef keyword.
  • The possibility to define a default when a variable is not defined.

Those two concepts are mutually exclusive, basically, because a variable having a default should never be undefined and should never cause Ansible to raise an error.
Although, depending on where you place your default, the way Ansible process variable could make the undef take precedence, and, so if you call a role containing an undef, then the error will always be raised.

As an example, a role variable file containing:

demo_variable: "{{ undef(hint='Please provide a demo variable') | default('Defeat `undef` purpose') }}"

makes nearly no sense, as the default will always take precedence.


Here is a simple role using the undef keyword.

roles/demo/vars/main.yml:

demo_variable: "{{ undef(hint='Please provide a demo variable') }}"

roles/demo/tasks/main.yml:

- debug:
    msg: "{{ demo_variable }}"

Playbook:

- hosts: localhost
  gather_facts: no

  roles:
    - role: demo      

If used as is, this will raise:

The task includes an option with an undefined variable. 
The error was: {{ undef(hint='Please provide a demo variable') }}: Please provide a demo variable
  
The error appears to be in '/usr/local/ansible/roles/demo/tasks/main.yml': line 1, column 3, 
but may be elsewhere in the file depending on the exact syntax problem.

As opposed to an undefined variable not using the undef keyword that would have raised:

The task includes an option with an undefined variable. 
The error was: 'demo_variable' is undefined
 
The error appears to be in '/usr/local/ansible/roles/demo/tasks/main.yml': line 1, column 3, 
but may be elsewhere in the file depending on the exact syntax problem.

If you want a default, on the other hand, you'll have to drop the definition of the variable, including the undef keyword out of the variable/main.yml file of the role and have a tasks/main.yml that would read:

- debug:
    msg: "{{ demo_variable | default('Defeat `undef` purpose') }}"

And this would then give the expected:

TASK [demo : debug] *********************************************************
ok: [localhost] => 
  msg: Defeat `undef` purpose

when the variable is not defined at the level of the playbook calling this role.

Related