Check if key exists in a dict in Jinja2 template on ansible
Solution 1
The answer is simple and it showed on ansible error message. First of all I need to check if var is defined.
{% if interfaces.vlan1 is defined %}
{{ interfaces.vlan1.ip }}
{% else %}
{{ interfaces.vlan2.ip|default("127.0.3.1") }}
{% endif %}
This combination works well.
Solution 2
The best way to check if a key exists in a dictionary (in any Jinja2 context, not just with Ansible) is to use the in
operator, e.g.:
{% if 'vlan1' in interfaces %}
{{ interfaces.vlan1.ip |default(interfaces.vlan2.ip) }};
{% endif %}
Related videos on Youtube
Alex
Updated on October 31, 2020Comments
-
Alex over 3 years
I have a host_var in ansible with dict with all interfaces:
--- interfaces: vlan0: ip: 127.0.0.1 mask: 255.255.255.0 state: true vlan2: ip: 127.0.1.1 mask: 255.255.255.0 state: true
And I want to check if dict has a key vlan1 if ok put to template value vlan1.ip else put vlan2.ip.
{% if interfaces.vlan1 %} # and also I try {% if 'vlan1' in interfaces %} {{ interfaces.vlan1.ip }}; {% else %} {{ interfaces.vlan2.ip|default("127.0.0.1") }}; {% endif %};
But i have an error:
fatal: [127.0.0.1] => {'msg': "AnsibleUndefinedVariable: One or more undefined variables: 'dict object' has no attribute 'vlan1'", 'failed': True}
I found that it have to be work in Jinja2 but it seems to doesn't work in ansible. Maybe someone have another way for solving this problem? When I define vlan1 it works fine. Ansible version 1.9.2
I was trying to reproduce it in python and have no error if my dictionary have not key vlan1. thanks to @GUIDO
>>> from jinja2 import Template >>> b = Template(""" ... {% if interfaces.vlan1 %} ... {{ interfaces.vlan1.ip }} ... {% else %} ... {{ interfaces.vlan2.ip|default("127.0.3.1") }} ... {% endif %}""") >>> b.render(interfaces={'vlan3':{'ip':'127.0.1.1'},'vlan2':{'ip':'127.0.2.1'}}) u'\n\n127.0.2.1\n' >>> b.render(interfaces={'vlan1':{'ip':'127.0.1.1'},'vlan2':{'ip':'127.0.2.1'}}) u'\n\n127.0.1.1\n'
-
Alex over 8 yearsThank you. But I have another error:
fatal: [127.0.0.1] => {'msg': 'AnsibleUndefinedVariable: One or more undefined variables: float object has no element 0', 'failed': True}
-
larsks over 8 yearsMaybe
vlan2
is also not available? I could help more if you could post a playbook that reproduces the specific problem. -
Alex over 8 yearshost_var you can see in question. playbook is simple role:
- name: Configure named.conf.options template: src=named.conf.options.j2 dest=/etc/bind/named.conf.options backup=yes owner=root group=bind mode=0644 become: yes tags: bind notify: restart bind
In named.conf.options.j2 i use jinja template as described above. -
ryantuck about 8 yearsit seems like the
is defined
part is crucial. i haven't been able to make theif
logic work with just using{% if item.var %}
-
Alex about 8 years@RyanTuck The {% if item.var %} checks only if var is not Null and if it is not defined that raise an error. If you need all checks use it together {% if item.var is defined and item.var %}
-
Johann Burgess over 3 yearsYou cal also use
if x is not defined
. Thanks