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.,
/etc/salt/master
roster: file
roster_file: /path/to/roster/file
For starters, let’s consider the following simple Roster SLS file:
/etc/salt/roster
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:
/srv/pillar/top.sls
base:
'*':
- proxy
And the connection credentials - example using NAPALM:
/srv/pillar/proxy.sls
proxy:
proxytype: napalm
driver: junos
hostname: {{ opts.id }}.example.com
password: superS3kure
With this configuration, device1
will try to connect to
device1.example.com
, and device2
to device2.example.com
,
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.,
/etc/salt/roster
device1:
driver: eos
hostname: different-hostname-for-device1.example.com
device2:
password: m0reS3kure
Using the previous example, device1
will connect to
different-hostname-for-device1.example.com
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.,
/etc/salt/roster
:
device1:
grains:
site: site1
device2:
grains:
site: site2
If you prefer to manage a JSON structure instead:
/etc/salt/roster
:
{
"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:
/etc/salt/roster
:
{%- for i in range(50) %}
device{{ i }}:
grains:
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('https://netbox.live/api/dcim/devices/', decode=true) %}
{%- for device in ret.dict.results %}
{{ device.name }}:
grains:
site: {{ device.site.slug }}
{%- 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.