循环遍历状态文件中的变量并使用目标模板中的变量

循环遍历状态文件中的变量并使用目标模板中的变量

在 Ansible 中,我可以循环遍历字典/列表列表,然后在 Ansible 任务中使用循环变量,也可以在调用的模板中使用循环变量。

我正在尝试在 Salt 中执行相同操作,但似乎不可能。至少不是以我习惯的方式。

我的支柱中有以下内容。

routes:
  ens4f0np0:
    - address: 192.168.1.0
      netmask: 255.255.255.192
      gateway: 172.18.48.1
    - address: 172.16.2.0
      netmask: 255.255.255.224
      gateway: 172.18.48.1

我在我的状态文件中循环遍历它,仅使用键,即接口名称。

{% for interface in salt['pillar.get']('routes') %}
  file.managed:
    - name: /etc/sysconfig/network-scripts/route-{{ interface }}
    - user: root
    - group: root
    - mode: '0644'
    - source: salt://linux/network/files/routes.jinja
    - template: jinja
{% endfor %}

然后在模板中我想使用该接口,但在第一行我已经收到错误,因为该变量不存在。

# {{ interface }}
{% for route in salt['pillar.get']('routes:interface') %}
ADDRESS{{ loop.index }}={{ route.address }}
NETMASK{{ loop.index }}={{ route.netmask }}
GATEWAY{{ loop.index }}={{ route.gateway }}
{% endfor %}

当我删除第一行时,模板已创建,但为空。这是因为在路由结构中查找失败。当我将其放在那里时routes:ens4f0np0,它就可以正常工作。

但正如您所看到的,我需要状态文件的名称 ens4f0np0 来指向正确的网络脚本文件,然后在该文件中我需要接口名称作为使用正确变量列表的关键。

有人知道我该如何改进吗?或者复制我在 Ansible 中通常做的事情?

答案1

您需要将上下文传递给模板。例如:

{% for interface, routes in pillar["routes"].items() %}
/etc/sysconfig/network-scripts/route-{{ interface }}:
  file.managed:
    - user: root
    - group: root
    - mode: '0644'
    - source: salt://linux/network/files/routes.jinja
    - template: jinja
    - context:
        interface: {{ interface }}
        routes: {{ routes | tojson }}
{% endfor %}
# {{ interface }}
{% for route in routes %}
ADDRESS{{ loop.index }}={{ route.address }}
NETMASK{{ loop.index }}={{ route.netmask }}
GATEWAY{{ loop.index }}={{ route.gateway }}
{% endfor %}

还要注意,使用 pillar 存储通用数据会导致性能瓶颈。如果数据不是机密,则将其存储在状态树中。

相关内容