在 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 存储通用数据会导致性能瓶颈。如果数据不是机密,则将其存储在状态树中。