Fallback value in Ansible

George Shuklin
OpsOps
Published in
1 min readJan 16, 2018

--

Jinja2 gave us ‘default’ filter. It works like this: ‘{{foo|default(“foo subsitute”)}}’. It works fine, but sometimes you need to check not against ‘defined/undefined’, but for ‘None’ value. Mostly it happens when you fill vars, but you have no answer for some variable at that time. You put there ‘None’. And then you want to treat None like this variable is not defined.

It’s easy: ‘{{(foo|default(None) or “foo substitute”)}}’.

If foo is not defined, it become None. If foo is None or become None, that ‘or’ replaces answer with “foo substitute”. ‘or’ is a python feature, and I advice to use parents around it all the time, or you may get some confusing results in more complicated cases.

Full example:

---
- hosts: all
gather_facts: no
tasks:
- debug: msg="{{(var1 or var2)}}"
- debug: msg="{{(var3|default(None) or var2)}}"
vars:
var1: '{{None}}'
var2: something
# no var3 is defined

P.S.

Originally, Jinja2 provides us with ‘omit’ value for default() filter, but it’s broken in Ansible. If you try to use ‘omit’, it will be treated as some bizarre object and you may left with something like this in your templates (after ‘join’):

_, _, o, m, i, t, _, p, l, a, c, e, _, h, o, l, d, e, r, _, _, 6, 2, a, 6, b, 0, 2, 6, a, 4, 3, e, 3, c, 3, 5, f, 0, 7, e, f, c, 3, 2, 9, 3, 5, 4, 8, b, 2, f, 1, 3, 3, f, 1, 4, 7, 4

--

--

George Shuklin
OpsOps

I work at Servers.com, most of my stories are about Ansible, Ceph, Python, Openstack and Linux. My hobby is Rust.