Using the File Roster

The File Roster allows you to easily manage the list of devices through an SLS file - that being any combination of the available Roster modules: Jinja+YAML, YAML, JSON, pure Python, JSON5, HJSON, etc.

By default, the Roster file is /etc/salt/roster, but you can have a different path by configuring roster_file (or --roster-file on the command line) to point to an alternative absolute path, e.g.,


roster: file
roster_file: /path/to/roster/file

For starters, let’s consider the following simple Roster SLS file:


device1: {}
device2: {}

To check that everything is properly configured, you can execute:

$ salt-sproxy \* --preview-target
- device1
- device2

As always, you’ll need to provide the connection credentials, in the Pillar. That is, you can have a structure as the following Pillar top file:


    - proxy

And the connection credentials - example using NAPALM:


  proxytype: napalm
  driver: junos
  hostname: {{ }}
  password: superS3kure

With this configuration, device1 will try to connect to, and device2 to, respectively, using the NAPALM Junos driver.

If you want more specific connection options per device, you can manage that in the Roster SLS file (under each device you can specify any connection argument to override the details from the proxy Pillar), e.g.,


  driver: eos
  password: m0reS3kure

Using the previous example, device1 will connect to using the NAPALM EOS driver for Arista, while device2 uses a different password.

In a similar way, you can provide static Grains per device, under the grains key, e.g.,


    site: site1
    site: site2

If you prefer to manage a JSON structure instead:


  "device1": {
    "grains": {
      "site": "site1"
  "device2": {
    "grains": {
      "site": "site2"

With that clarified, let’s make the Roster SLS file more dynamic, and instead of managing the list of devices manually, have it auto-generated:


{%- for i in range(50) %}
device{{ i }}:
    site: site{{ i }}
{%- endfor %}

The example above provides a list of 50 devices. Although probably too simplistic for real-world usage, it may be sufficient to exemplify the use-case.

Remember that being interpreted as an SLS, you can also invoke Salt functions, using the __salt__ global variable. For example, to retrieve and build the list of devices dynamically using an HTTP query, you can do, e.g.,

{%- set ret = __salt__.http.query('', decode=true) %}
{%- for device in ret.dict.results %}
{{ }}:
    site: {{ }}
{%- endfor %}

Ultimately, for higher complexity, consider using the pure Python Renderer whenever you need to put more business logic in selecting the devices you need to manage.