Understanding Ansible and Jinja2's default() filter
I have been using Ansible at work for the past month to set up some infrastructure. I wanted to express the following in the setup script:
ansible_ssh_user: "{{ lookup('env', 'SSH_USER') }}"
but wanted to set the user to ubuntu
if SSH_USER
was not set.
For some reason, this would not work:
ansible_ssh_user: "{{ lookup('env', 'SSH_USER') | default('ubuntu') }}"
Ansible provides several functions that can extract various string values from
the environment. You are most likely to encounter lookup()
. The behavior of
lookup()
is defined by what plugin is used (based on the first parameter).
The env
plugin returns an empty string when the requested environment
variable is not set. An empty string is False-y in Python. Why wasn’t this
working?
The default()
filter provided by Jinja2 treats the special class Undefined
differently from False-y Python values. By default, default()
will only
return its first argument if the prior expression evaluates to Undefined
.
The second boolean parameter asks the function to also accept Python False-y
values as undefined and return the default value. This can be seen in the source code
So the fix is:
ansible_ssh_user: "{{ lookup('env', 'SSH_USER') | default('ubuntu', true) }}"