0

I'm having some issues with Ansible and the way it defaults to values. What I'm trying to accomplish is to bind a Docker container to on eth1, if it exists, otherwise use lo.

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: {{

Next up, I tried using the when and 'is not defined' condition instead. It's less DRY, as I need two stanzas then.

- name: Start Mongo on loopback
  shell: docker run -d -p {{ ansible_lo.ipv4.address }}:27017:27017 [...] dockerfile/mongodb
  when: ansible_eth1.ipv4.address is not defined

That gave me the following error:

error while evaluating conditional: ansible_eth1.ipv4.address is not defined

Any Ansible experts out there that can point me in the right direction?

Oh, and I'm running ton Ansible 1.7.2.

vpetersson
  • 861
  • 1
  • 11
  • 22

1 Answers1

6

The problem with this:

ansible_eth1.ipv4.address | default(127.0.0.1)

Is that if ansible_eth1 isn't a defined variable, then ansible_eth1.ipv4.address (or even ansible_eth1.ipv4) won't work. The solution is to apply the default filter to the variable that might not be there, which is ansible_eth1:

(ansible_eth1 | default(ansible_lo)).ipv4.address

Also note it's better practice to use command instead of shell unless you need some feature of the shell like pipe or redirection:

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

Finally, note that Ansible has a docker module, so you may be able to use that directly here.

docker: "ports={{ (ansible_eth1 | default(ansible_lo)).ipv4.address }}:27017:27017 ..."
Lorin Hochstein
  • 5,028
  • 15
  • 56
  • 72