Score:1

Loop through variables in state file and use the vars in the target template as well

us flag

In Ansible I can loop through a list of dicts/lists and then use the loop vars in the Ansible task, but also in the template I call on.

I'm trying to do the same in Salt, but it seems like it's not possible. At least not in the way I'm used to.

I have the following in my Pillar.

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

I loop through it in my state file, using only the key, which is the interface name.

{% 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 %}

Then in the template I want to use the interface, but on the first line I already get an error, because that variable does not exist.

# {{ 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 %}

When I remove the first line, the template is created, but is empty. This is due to the fact that the lookup in the routes structure fails. When I put there routes:ens4f0np0, then it works fine.

But as you can see, I need the name ens4f0np0 for the state file to point to the right network-script file, and then in that file I need the interface name as the key to use the right list of variables.

Does anyone know how I can improve this? Or replicate what I usually do in Ansible?

Score:0
il flag

You need to pass the context to the template. For example:

{% 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 %}

Note also that using pillar for storing generic data will lead to a performance bottleneck. If the data is not secret, then store it in the state tree instead.

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.