Ansible 在剧本中的默认/错误处理问题

Ansible 在剧本中的默认/错误处理问题

我对 Ansible 及其默认值设置方式有些疑问。我试图实现的是将 Docker 容器绑定到 eth1(如果存在),否则使用 lo。

我最初的方法是使用默认未定义变量如下:

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'没有定义'条件。这样就不那么 DRY 了,因为我需要两个节。

- 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。

答案1

问题在于:

ansible_eth1.ipv4.address | default(127.0.0.1)

是不是如果ansible_eth1不是定义的变量,那么ansible_eth1.ipv4.address(甚至ansible_eth1.ipv4) 都不起作用。解决方案是将default过滤器应用于可能不存在的变量,即ansible_eth1

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

还请注意,除非您需要 shell 的某些功能(如管道或重定向),command否则最好使用而不是:shell

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

最后,请注意 Ansible 有一个码头工人模块,因此您可以直接在这里使用它。

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

相关内容