How to Bulk Restart All Systemd Instantiated Service Instances Efficiently


3 views

Systemd's instantiated services (service@instance pattern) provide excellent modularity, but management becomes tricky when you need to operate on multiple instances simultaneously. The standard systemctl restart approach becomes verbose:

# Tedious individual restarts
systemctl restart autossh@foo
systemctl restart autossh@bar
systemctl restart autossh@blu

Method 1: Using Instance Patterns

While autossh@* doesn't work directly, systemd provides template-aware commands:

# Restart all instances of a template
systemctl restart 'autossh@*' --all

Method 2: Target-Based Management

Create a target unit that collects all instances:

# /etc/systemd/system/autossh-target.target
[Unit]
Description=Autossh Instances Target
Wants=autossh@foo.service autossh@bar.service autossh@blu.service

Then control them collectively:

systemctl restart autossh-target.target

Method 3: Shell Expansion

For ad-hoc operations using bash expansion:

for instance in foo bar blu; do
  systemctl restart "autossh@${instance}"
done

For reliable automation, use list-units with filtering:

# Restart all running instances
systemctl list-units 'autossh@*' --state=running --no-legend | \
awk '{print $1}' | \
xargs -r systemctl restart

As noted in the update, consider configuration management tools (Ansible/Puppet) when:

  • Instance counts exceed 10+
  • Dynamic instance creation is required
  • Complex inter-dependencies exist

Example Ansible playbook alternative:

- name: Manage autossh instances
  ansible.builtin.systemd:
    name: "autossh@{{ item }}"
    state: restarted
  loop: [foo, bar, blu]

Systemd's instantiated services (service@.service) are powerful for managing multiple instances from a single template. However, many administrators face difficulties when needing to perform bulk operations across all instances.

The intuitive approach using wildcards doesn't work as expected:

systemctl restart autossh@*  # This fails

Systemd treats the wildcard literally rather than expanding it to match all instances.

Method 1: Using systemctl list-units

Combine with bash command substitution:

systemctl restart $(systemctl list-units 'autossh@*' --no-legend | awk '{print $1}')

Method 2: Template-based Restart

For systemd v230+:

systemctl restart autossh@*

Note: Requires EnableUnitCommands=yes in systemd.conf

Method 3: Using systemd-run

Create a transient scope unit:

systemd-run --unit=restart-autossh --scope systemctl restart autossh@*

While instantiated services offer convenience, consider whether configuration management tools might be more appropriate:

# Ansible example
- name: Restart all autossh instances
  become: yes
  systemd:
    name: "autossh@{{ item }}"
    state: restarted
  loop:
    - foo
    - bar
    - blu

When dealing with many instances (50+), use parallel execution:

parallel --jobs 4 systemctl restart ::: autossh@foo autossh@bar autossh@blu
  • Verify instances exist: systemctl list-unit-files | grep autossh@
  • Check templating syntax in your service file
  • Ensure proper escaping of special characters in instance names