Issue with default value

Hey guys,

I’m trying to write an ansible playbook with the shell module. In the command, I’m want to use the eth1 interface if it exists. If the eth1 interface doesn’t exist, it should fallback to the loopback interface.

My initial approach was to use the defaulting undefined variables as follows:

shell: docker run -d -p {{ ansible_eth1.ipv4.address | default(127.0.0.1) }}:27017:27017 […] dockerfile/mongodb

Unfortunately, Ansible threw the following error:
fatal: [server] => One or more undefined variables: ‘ansible_eth1’ is undefined

I also tried versions of this, such as:

shell: docker run -d -p {{ ansible_eth1.ipv4.address | ansible_lo.ipv4.address }}:27017:27017 […] dockerfile/mongodb

That gave me another error:

failed: [server] => {“changed”: true, “cmd”: “docker run -d -p {# ansible_eth1.ipv4.address | ansible_lo.ipv4.address #}:27017:27017 […]”, “delta”: “0:00:00.021053”, “end”: “2014-11-01 17:22:04.457375”, “rc”: 127, “start”: “2014-11-01 17:22:04.436322”}
stderr: /bin/sh: 1: ansible_lo.ipv4.address: not found
2014/11/01 17:22:04 Invalid containerPort: {{

Could anyone help point me in the right direction?

I’ve also published this on Serverfault [1]:

http://serverfault.com/questions/641326/issues-with-ansibles-default-error-handling-in-a-playbook

Jinja2 is a little more picky about using dot notation as opposed to type notation as it pertains to using “default”

You might want to try:

ansible_eth1[“ipv4”][“address”] | default(“127.0.0.1”)

You may also need to place the default closer to ansible_eth1 as opposed to deeper nesting like it is currently.

Sorry to resurrect this old thread.

ansible_eth1[“ipv4”][“address”] | default(“127.0.0.1”)

I tried this and it didn’t work. Is it supposed to? Is there some other way of using default that would work? Would it make sense to fix the default filter to work in this case?

Cheers,
Paul

Try with
default(“127.0.0.1”, true)
It is not clear on the filter description, but without the second argument it does not perform a boolean evaluation, but just strict variable undefinition. That means that an empty string will not trigger the default. Actually, even if the variable you are testing is None, the default will not be used.

Javier Palacios

default(“127.0.0.1”, true)

Didn’t help.

It is not clear on the filter description, but without the second argument it does not perform a boolean evaluation, but just strict variable undefinition. That means that an empty string will not trigger the default. Actually, even if the variable you are testing is None, the default will not be used.

I’m sorry, I didn’t specify that I’m getting the same “One or more undefined variables” as Viktor was. The undefined variable can be in my case be on any level. So for ansible_eth1.ipv4.address any of ansible_eth1, ipv4 or address could be undefined.

Cheers,
Paul

default does not do multilevel variables, you need to have something
on each level for it to work, something like:

((ansible_eth1|default({})["ipv4"]|default({}))["address"] |
default("127.0.0.1")

((ansible_eth1|default({})[“ipv4”]|default({}))[“address”] |
default(“127.0.0.1”)

Ugh. I was expecting something like try: … except KeyError: …

Is there any chance of fixing default to work with multiple levels without so much typing? I think it would be a rather big usability improvement.

Cheers,
Paul

default is a fitler from the jinaj2 project, the 'fix' would have to
happen there