2
votes

I want an Ansible 2.6.2 task to use the value of variable var1 if it's set, otherwise a string containing variable var2. Only one of these will be set, however. If I use a simple {{ var1 | default(var2) }} it works, but when I try to append a string to var2 Ansible gives an error when var2 is undefined, even though var1 is:

FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: 'var2' is undefined\n\nThe error appears to have been in 'test.yml': line 13, column 7, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n msg: \"Simple default: {{ var1 | default(var2) }}\"\n - debug:\n ^ here\n"}

Playbook:

- hosts: all
  gather_facts: false
  connection: local
  vars:
    var1: "one"
#    var2: "two"
  tasks:
    - debug:
        # This works
        msg: "Simple default: {{ var1 | default(var2) }}"
    - debug:
        # This fails when var2 is undefined, even though var1 is
        msg: "Default with concatenation: {{ var1 | default(var2 + '?') }}"
3

3 Answers

3
votes

The error message is clear: parser requires a variable to be defined.

You can use the same default filter to provide default value instead of the var2:

msg: "Default with concatenation: {{ var1 | default(var2|default('') + '?') }}"
1
votes

OK, I found a way that works, thanks to another answer by techraf:

{{ var1 if var1 is defined else var2 + '?' }}

This works if either var1 or var2 is defined, but if both are undefined throws an error:

The task includes an option with an undefined variable. The error was: 'var2' is undefined...

I can add a third variable to this, too:

{{ var1 if var1 is defined else (var2 + '?' if var2 is defined else var3 + '!' ) }}

Dictionary version:

{{ mydict.key1 if mydict.get('key1') else mydict.key2 }}

(if mydict.key1 raises an error if key1 is not in mydict)

0
votes

Both doing the same (don't know which is more efficient)

Variables:

repo: hththt
file_name: file.txt

Templates:

url: "{{ url if url is defined else repo + '/files/' + file_name }}"

url: "{{ url | default(repo + '/files/'' + file_name) }}"