For loop only takes last element in list?

Viewed 111

Currently, I'm trying to disable and mask several network related system services using SaltStack under Ubuntu 20.04. Now, things got a bit confusing here. In the end, I need to disable several services, so I built a for loop accordingly, please see below:

init.sls:
stop_netplan_services:
  service.disabled:
    {% for services in [ 'systemd-resolved', 'systemd-networkd.socket', 'systemd-networkd', 'systemd-networkd-wait-online', 'networkd-dispatcher' ] %}
    - name: {{ services }}
    {% endfor %}
    - require:
      - dead_netplan_services

If I trigger my high state, only the last service in the list gets respected, talking about the networkd-dispatcher here. Everything else simply does not get applied. Why is 'systemd-resolved', 'systemd-networkd.socket' etc ... ignored in this for loop?

1 Answers

Repeated arguments in yaml states are ignored.

You need to generate separate states for each service. Also, the service.dead state has an enable argument, so you don't need service.disabled.

{% for service in [ 'systemd-resolved', 'systemd-networkd.socket', 'systemd-networkd', 'systemd-networkd-wait-online', 'networkd-dispatcher' ] %}
stop and disable {{ service }}:
  service.dead:
    - name: {{ service }}
    - enabled: false
{% endfor %}

That is the general solution, though some states have an explicit names or pkgs or similar argument. You can pass a list to that instead of generating multiple states.

Edit: as pointed out in the comments, names should work for every state:

disable_netplan_services:
  service.dead:
    - names:
      - systemd-resolved
      - systemd-networkd.socket
      - systemd-networkd
      - systemd-networkd-wait-online
      - networkd-dispatcher
    - enabled: false
Related