Salt
Salt is a remote execution and configuration management tool that I have been using to manage the many Linux servers and desktops I have. Its state system also replaces some of my notes as a self-documenting machine-readable description of how each item is configured.
Useful salt commands
Test connectivity:
salt '*' test.ping
Test what changes would be made if state.highstate were run:
salt '*' state.highstate test=True
View a node’s pillar data:
salt minionid pillar.raw
View what the master believes should be the node’s pillar data:
salt minionid pillar.items
Refresh the node’s pillar data:
salt minionid saltutil.refresh_pillar
Run salt, sorting by duration (with terse mode output):
salt minionid --state-output=terse --state-verbose=true state.highstate test=True | grep -o ' Name: .* Duration: [0-9.]\+ ms' | sed 's/ \(Name: .*\) - \(Function: .*\) - Result:.* \(Duration: [0-9.]* ms\)/\3 \2 \1/' | sort -k 2,2 -n
Run an individual state:
salt minionid --state-output=full --state-verbose=true state.apply linux.packages.dropbox test=True
Install SaltStack on Debian
Debian Squeeze needed SaltStack’s own repository and backports. Wheezy required just SaltStack’s own repository. (Update 2018-06-25: Stretch’s version in the main repositories is up to date enough to be usable.)
Install either the salt-minion or salt-master as appropriate:
apt-get install salt-minion
or
apt-get install salt-master
If you want to use salt-ssh then that will also need to be installed:
apt-get install salt-ssh
Master
Salt minions default to connecting to DNS hostname salt for the master. This is fine but it means that it needs adding to DNS before setting up a minion to manage DNS (as the minion needs to resolve salt to get it’s configuration to configure DNS including salt - it can be a bit of a catch-22) OR adding salt to /etc/hosts that then gets managed by salt with a version without that entry when the DNS has been configured.
The master listens on TCP ports 4505 and 4506 by default, so make sure the minions can connect to these through firewalls etc.
Tab \t
cannot be used to indent YAML - it must be spaces as the start of the line.
Configuration
Disable passing master configuration to minion
I disabled the default of passing the master configuration in the minion’s pillar by creating /etc/salt/master.d/pillar_opts.conf
:
pillar_opts: False
Only display changed/failed states in highstate output
I disabled the default of displaying all highstate results (as opposed to just those that have changed) by creating /etc/salt/master.d/highstate_output.conf
:
state_verbose: False
Improved directory structure
I don’t like the default directory layout (/srv/salt
and /srv/pillar
) so I fix it (to /srv/salt/states
and /srv/salt/pillar
).
-
Create
/etc/salt/master.d/file_roots.conf
:file_roots: base: - /srv/salt/states pillar_roots: base: - /src/salt/pillar
- Make the directories:
mkdir -p /srv/salt/{states,pillar}
-
Initialise as a git repository (so we can version control the states and pillar):
cd /srv/salt git init
Windows
Set the location of the Windows package repository in /etc/salt/master.d/windows.conf
:
# The default timeout is too short for Windows minions
timeout: 10
win_repo: /srv/salt/states/win/repo
win_repo_mastercachefile: /srv/salt/states/win/repo/winrepo.p
When packages are added to the repository the cache needs updating with this command:
salt-run winrepo.genrepo
External pillars
This was for work, where I wrote a pillar interface to xcat.
-
Start by creating
/etc/salt/master.d/extension_modules.conf
:extension_modules: /srv/salt/ext_modules
-
Create the directory:
mkdir -p /srv/salt/ext_modules/pillar
- Create the external pillar (see: http://docs.saltstack.com/topics/development/external_pillars.html), e.g.
/srv/salt/ext_modules/pillar/xcat.py
-
Enable is by creating ` /etc/salt/master.d/ext_pillar.conf`:
ext_pillar: - xcat
Minion
Connecting minion to a master
Before anything useful can accomplished it is necessary to get a minion and a master talking.
If the DNS for salt
is set correctly then the minion should automatically start talking to the master and their key will appear in the list of Unaccepted Keys
reported by salt-key
:
root@server:~# salt-key -l un
Unaccepted Keys:
minionid
This key can then be checked by comparing the one seen by the master:
root@server:~# salt-key -p minionid
Unaccepted Keys:
minionid: -----BEGIN PUBLIC KEY-----
MIICI...
-----END PUBLIC KEY-----
to the one on the minon:
root@server:~# cat /etc/salt/pki/minion/minion.pub
-----BEGIN PUBLIC KEY-----
MIICI...
-----END PUBLIC KEY-----
If they match, add the key to the master:
salt-key -a minionid
Finally communication between the pair can be tested:
salt minionid test.ping