8
votes

At ansible 1.9 I have some roles which I can make use of undefined variables (error_on_undefined_vars = False at ansible.cfg) in templates with no issues in the way:

template.yml:

{{ var1 }}{{ var2 }}{{ var3 }}

If any of these vars are not defined, then nothing is substituted. So, you can just indicate in your playbook some of these vars and not others, as desired.

But I found, after upgrading to ansible 2.2.0.0 , that if any of these vars are not defined, them none of the template's vars are substituted and the resulted template is: {{ var1 }}{{ var2 }}{{ var3 }}

E.g.:

playbook:

- hosts: myhost
   vars:
     var1=1
     var3=3
   roles:
     - myrole

tasks:

- name: copy template
  become: true
  template: src=test.j2 dest=/tmp/test owner=user group=user

After running this playbook, the resulting /tmp/test run with ansible 1.9 is

13

and with ansible 2.2.0.0 is

{{ var1 }}{{ var2 }}{{ var3 }}

So, none vars are substituted.

But if:

playbook:

- hosts: myhost
   vars:
     var1=1
     var2=2
     var3=3
   roles:
     - myrole

After running this playbook, the resulting /tmp/test run with ansible 1.9 / 2.2.0.0 is

123

Has anyone dealed with this behavior before?

2

2 Answers

2
votes

There are Jinja filters that can be used to help assist when variables are undefined.

You could try using the default filter to set set a value when it is not defined

{{ var1 }}{{ var2 | default(None) }}{{ var3 }}

This will set var2 to "" if var 2 is undefined. This is how I handle most variables I have that might not need to be defined for a paricular host in play.

You could also test using the omit Jinja filter which will just omit the variable from being used.

{{ var1 }}{{ var2 | default(omit) }}{{ var3 }}

For full list of Jinja filters see https://docs.ansible.com/ansible/latest/user_guide/playbooks_filters.html

1
votes

One of the things you could do is to put the variable in a conditional check whether it is defined or not. Or put the block of variables, if you need all of them defined in order to be set. Your template should look like this:

{% if var1 is defined and var2 is defined and var3 is defined %}
        {{ var1 }}{{ var2 }}{{ var3 }}
{% endif %}

If you have all three variables defined, the template will get copied with 123 inside. If you have even one undefined variable, the file will be copied without the above variables block.