如何在jinja2中附加到ansible的列表中

时间:2018-04-02 22:05:40

标签: templates ansible jinja2 ansible-template

下面是我写的在ansible中使用的jinja2模板。

data frame

以下是我想要的输出:

{% set port = 1234 %}
{% set server_ip = [] %}
{% for ip in host_ip  %}
{% do server_ip.append({{ ip }}:{{ port }}) %}
{% endfor %}
{% server_ip|join(', ') %}

但是当我运行ansible playbook时,它会抛出如下错误:

devices = 192.168.56.14:1234,192.168.56.13:1234,192.168.56.10:1234

任何帮助将不胜感激..

4 个答案:

答案 0 :(得分:12)

尝试以下代码:

{% set port = '1234' %}
{% set server_ip = [] %}
{% for ip in host_ip  %}
{{ server_ip.append( ip+":"+port ) }}
{% endfor %}
{{ server_ip|join(',') }}

你会得到:

  

192.168.56.14:1234,192.168.56.13:1234,192.168.56.10:1234

答案 1 :(得分:2)

对我有用:

- set_fact:
    devices: >-
      {% for ip in host_ip %}{{ ip }}:1234{% if not loop.last %},{% endif %}{% endfor %}

如果您仍然想使用do,请添加

jinja2_extensions = jinja2.ext.do

进入您的ansible配置文件并进行更改

{% do server_ip.append({{ ip }}:{{ port }}) %}` to `{% do server_ip.append({ip:port}) %}`

答案 2 :(得分:2)

我不喜欢任何答案,他们觉得太老套了(不得不担心输出 None 或使用其他技术产生虚假空白),但我想我已经找到了一个行之有效的解决方案。我从 this answer on a related question 中获得灵感,并意识到您可以为同一个变量多次调用 set,而且似乎不会招致任何惩罚。

它仍然有点 hacky,因为我不认为它打算像这样工作(再说一次,Jinja 中的几个设计决策让我摸不着头脑,所以谁知道呢)。 >

{% set server_ip = server_ip.append({{ ip }}:{{ port }}) %}

有趣的是,虽然该值确实附加到 server_ip,但该附加的返回值(我们现在非常清楚的是 None)并没有分配回 server_ip LHS。这让我发现声明的 LHS 方面似乎是一个空操作。

所以你也可以这样做并且附加工作:

{% set tmp = server_ip.append({{ ip }}:{{ port }}) %}

但是,如果您打印 tmp,则什么也没有显示。去图。

答案 3 :(得分:0)

为了避免使用 None 到处打印 {{ server_ip.append( ip+":"+port ) }}(只花了 20 分钟调试这个),如果你不想使用误导性的 {% set _ = server_ip.append( ip+":"+port ) %},你可以去回到 Python 基础知识并执行以下操作:


# Remember that [1, 2] + [3] = [1, 2, 3]

{% set server_ip = server_ip + [ip+":"+port] %}

在 99.9% 的情况下,这将完成工作。但是,在使用非常大列表的特殊情况下,内存使用量可能会有很小的性能下降:在上面的示例中,[1, 2] + [3] = [1, 2, 3][1, 2][1, 2, 3](初始列表和修改列表)将在内存中共存片刻,这与不在内存中创建额外对象的 append 方法相反。