如何在Jinja / Ansible中将变量作为变量生成?

时间:2018-08-09 20:16:41

标签: ansible jinja2

我需要动态生成一个字典并将其分配给Ansible var,以便每个主机都可以使用相同的数据,而不必在每个主机上都重新生成。这将通过任务和模板进行循环。可以通过将Jinja嵌套在这样的var定义中来构建列表:

var_list: >
  [
    {% set data = [] %}
    {% for host in groups['all'] %}
    {{ data.append(host) }}
    {% endfor %}
    {{ data }}
  ]

但是,我无法通过dict来做到这一点:

var_dict: >
  {
    {% set data = dict() %}
    {% for host in groups['all'] %}
    {{ data | combine({host: []}) }}
    {% endfor %}
    {{ data }}
  }

这会导致一个巨大的乱码:{u'host.subdom.dom.tld': []} {} ...

我期望的是将一个var设置为一个真正的dict对象,该对象可以单独引用其组件(例如{{ var_dict.host1[0] }}),其结构类似于以下JSON:

{
  "host1": [],
  "host2": []
}

有没有一种方法可以使它在分配给变量时扩展为适当的字典?还是有另一种方法可以从没有该awful set_fact hackery的循环中生成命令?

1 个答案:

答案 0 :(得分:1)

您的任何一个模板都已损坏(第一个模板生成嵌套列表,第二个模板使用此表达式{{ data | combine({host: []}) }}循环打印数据,data的值一直为空,直到结尾)。


Jinja2是一个模板引擎,您实际上不需要创建数据结构来稍后打印它们。您可以直接形成输出。

对于列表:

var_list: >
  [ {% for host in groups['all'] %}'{{ host }}',{% endfor %} ]

对于字典:

var_dict: >
  { {% for host in groups['all'] %}'{{ host }}': [],{% endfor %} }

由于您希望Ansible可以解释这些值,因此您无需注意尾随的逗号,否则会有loop.last