UNDEF Keyword in Ansible
Solution 1:
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.