有关Ansible在剧本中的默认/error handling问题

我在Ansible中遇到了一些问题,以及它默认值的方式。 我试图完成的是绑定一个Docker容器到eth1,如果存在,否则使用lo。

我最初的做法是使用默认的未定义variables如下:

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

不幸的是,Ansible抛出了以下错误。

 fatal: [server] => One or more undefined variables: 'ansible_eth1' is undefined 

我也试过这个版本,比如:

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

这给了我另一个错误:

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

接下来,我尝试使用when和'not defined'条件代替。 它不那么干,因为我需要两节然后。

 - 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 

这给了我以下错误:

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

任何Ansible专家都可以指引我正确的方向吗?

哦,我正在运行Ansible 1.7.2。

这个问题:

 ansible_eth1.ipv4.address | default(127.0.0.1) 

如果ansible_eth1不是定义的variables,那么ansible_eth1.ipv4.address (甚至ansible_eth1.ipv4 )将不起作用。 解决scheme是将defaultfilter应用于可能不存在的variables,该variables是ansible_eth1

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

另外请注意,最好使用command而不是shell command ,除非需要像pipe道或redirect这样的shell的某些function:

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

最后,请注意Ansible有一个docker模块,所以你可以直接在这里使用。

 docker: "ports={{ (ansible_eth1 | default(ansible_lo)).ipv4.address }}:27017:27017 ..."