Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ansible 2: cannot use undef vars in templates

Tags:

ansible

jinja2

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?

like image 255
jlbroot Avatar asked Feb 22 '17 09:02

jlbroot


People also ask

How are parameters used in Ansible template files?

We need to have two parameters when using the Ansible Template module, such as: src: The source of the template file. It can be a relative and absolute path. dest: Dest is the destination path on the remote server.

What extension do the template files in Ansible have?

Ansible templates are typically saved as . tpl files and support the use of variables, loops, and conditional expressions.

How do I add VARS to Ansible playbook?

The include_vars module can be used in a playbook or role to load variables from a file. Simply set the value of include_vars to a local file to load the variables it contains: --- # ./hello_world. yml - name: print greeting hosts: "*" tasks: - include_vars: name_vars.

How do I create an Ansible template?

conf file in the /opt directory, simply replace the copy reference to template as shown below. When you do this, Ansible then invokes the template module to both transfer the template and replace the variables with static values. Once the above task in the playbook executes, Ansible will copy the app. conf.


2 Answers

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

like image 140
ecaepp Avatar answered Nov 04 '22 07:11

ecaepp


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.

like image 1
13dimitar Avatar answered Nov 04 '22 08:11

13dimitar