如何使用Ansible动态注册变量?

时间:2015-01-02 18:25:40

标签: yaml ansible

我想定义一个Ansible角色并注册动态变量:

---
- name: Check for {{ package }}
  stat: path=/opt/packages/{{ package }}
  register: "{{ package | regex_replace('-', '_') }}"
- name: Install {{ package }} {{ package_version }}
  command: "custom-package-installer {{ package }} {{ package_version }}"
  when: "not {{ package | regex_replace('-', '_') }}.stat.exists"

用法如下:

- include: install_package.yml package=foo package_version=1.2.3

然而,Ansible并不承认有条件:

TASK: [example | Install foo 1.2.3] *********************************** 
fatal: [my-server] => error while evaluating conditional: not foo.stat.exists

FATAL: all hosts have already failed -- aborting

如何动态定义变量,展开{{ }}

3 个答案:

答案 0 :(得分:5)

无法注册动态变量。占位符{{ var }}无法注册。然而,有一种更清洁的方式来执行我认为你想要实现的目标:Ansible: it's a fact

简短摘要:

您可以编写一个简单的脚本来打印JSON,如:

#!/bin/python #or /bin/bash or any other executable
....

print """{ "ansible_facts": {
              "available_packages": ["a", "b", "c"]
               }
          }"""

并将其放入计算机上的本地事实文件夹中(作为.fact结尾的可执行脚本):

Your second task would then look like:

- name: Install {{ package }} {{ package_version }}
  command: "custom-package-installer {{ package }} {{ package_version }}"
  when: "not package in ansible_facts['available_packages']"

Ansible docs on facts

答案 1 :(得分:2)

在这种情况下,您不需要动态变量,执行:

---
- name: Check for {{ package }}
  stat: path=/opt/packages/{{ package }}
  register: current_package

- name: Install {{ package }} {{ package_version }}
  command: "custom-package-installer {{ package }} {{ package_version }}"
  when: not current_package.stat.exists

非常好......

答案 2 :(得分:-1)

与许多事情一样,如果你真的想这样做,这是可能的,但是本身在ansible中它是不受支持的。

也就是说,ansible是用python编写的,你可以直接在python代码中调用playbooks。我这样做的方法是动态生成剧本,然后分两步执行。

实际上,就像拥有动态剧本一样。总结一下......

  1. 使用适当的逻辑生成剧本。
  2. 使用ansible执行playbook。