Salt SSH Getting Started
16th June 2018
Introduction
Salt SSH allows you to
execute commands and apply state to minions without having to install a
salt-minion.
The only requirement is for the minion to have python installed
unless using the -r
option to execute raw commands.
For reference the following software will be used in this post.
- salt-ssh - 2018.3.1 (Oxygen)
- Ubuntu (host) - 16.04
- Debian (guest) - 9.4
Installation
Create and change into a working directory named salt-ssh.
mkdir /home/bradmin/salt-ssh && cd /home/bradmin/salt-ssh
I will use pipenv to manage a virtual environment and the installation of salt-ssh. If you are not using pipenv you can use pip with a virtual environment to install salt-ssh.
pipenv install salt-ssh
Activate the virtual environment.
pipenv shell
Directories
By default Salt expects its configuration files to be located in the /etc/salt directory. I am running Salt SSH as a non-root user so there are a number of directories that need to be created which are writable for my user.
mkdir -p {config,salt/{files,templates,states,pillar,formulas,pki/master,logs}}
# Directory Structure
/home/bradmin/salt-ssh
├── config
└── salt
├── files
├── formulas
├── logs
├── pillar
├── pki
│ └── master
├── states
└── templates
Config
The master config file has the same declarations that you would define when using Salt in master mode. Create a master config file with the following contents that points Salt SSH to the location of the previously created directories.
# salt-ssh/config/master
file_roots:
base:
- "/home/bradmin/salt-ssh/salt"
cachedir: "/home/bradmin/salt-ssh/salt/cache"
pki_dir: "/home/bradmin/salt-ssh/salt/pki/master"
Roster
The roster file is used to define remote minions and their connection parameters. I am using Vagrant for this lab so I will reuse the Vagrant user credentials. Create a roster file with the following contents.
# salt-ssh/config/roster
minion:
host: "192.168.121.117"
user: "vagrant"
priv: "~/.vagrant.d/insecure_private_key"
Saltfile
The Saltfile allows you to set command line configuration option in a file instead of declaring them at runtime. Create a Saltfile with the following contents.
# salt-ssh/Saltfile
salt-ssh:
config_dir: "/home/bradmin/salt-ssh/salt/config"
roster_file: "/home/bradmin/salt-ssh/salt/config/roster"
ssh_log_file: "/home/bradmin/salt-ssh/salt/logs/salt-ssh-log.txt"
log_file: "/home/bradmin/salt-ssh/salt/logs/salt-log.txt"
For reference the final directory structure should look like the following.
# Directory Structure
/home/bradmin/salt-ssh
├── config
│ ├── master
│ └── roster
├── salt
│ ├── cache
│ ├── files
│ ├── formulas
│ ├── logs
│ ├── pillar
│ ├── pki
│ │ └── master
│ ├── state
│ └── templates
└── Saltfile
Testing
With the base configuration done, lest run a few tests. Salt SSH is controlled using the
salt-ssh
command. Aside from that you can use the same command line options
that are available with the regular salt
command.
salt-ssh '*' test.ping
# output
minion:
True
Note
The first time you execute salt-ssh
it will create SSH keys. This makes the
execution time take longer than normal but subsequent runs are much faster. You may also
need to accept the minions SSH key fingerprint. For more details see
here.
If you successfully connected lets try install a package.
salt-ssh '*' pkg.install cowsay --sudo
# output
minion:
----------
cowsay:
----------
new:
3.03+dfsg2-3
old:
cowsay-off:
----------
new:
3.03+dfsg2-3
old:
Alright as a final test, lets execute a command on the minion.
salt-ssh '*' cmd.run 'cowsay im a salty moo cow'
# output
minion:
____________________
< im a salty moo cow >
--------------------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
Troubleshooting
Most of the issues I ran into related to running Salt as a non-root users. You can run
salt-ssh
with the -l debug
flag to get a more detailed look
at the execution and errors if any.
salt-ssh '*' cmd.run 'df -h' -l debug
# output
[INFO ] Loading Saltfile from '/home/bradmin/salt-ssh/Saltfile'
[DEBUG ] Reading configuration from /home/bradmin/salt-ssh/Saltfile
[DEBUG ] Reading configuration from /home/bradmin/salt-ssh/config/master
[DEBUG ] Configuration file path: /home/bradmin/salt-ssh/config/master
[WARNING ] Insecure logging configuration detected! Sensitive data may be logged.
[DEBUG ] LazyLoaded flat.targets
[DEBUG ] LazyLoaded jinja.render
[DEBUG ] LazyLoaded yaml.render
[DEBUG ] compile template: ./config/roster
[DEBUG ] Jinja search path: ['/home/bradmin/salt-ssh/salt/cache/files/base']
[DEBUG ] LazyLoaded roots.envs
[DEBUG ] Could not LazyLoad roots.init: 'roots.init' is not available.
[DEBUG ] Updating roots fileserver cache
[PROFILE ] Time (in seconds) to render './config/roster' using 'jinja' renderer: 0.04327249526977539
[DEBUG ] Rendered data from file: ./config/roster:
minion:
host: "192.168.121.117"
user: "vagrant"
priv: "~/.vagrant.d/insecure_private_key"
[DEBUG ] Results of YAML rendering:
OrderedDict([('test', OrderedDict([('host', '192.168.121.117'), ('user', 'vagrant'), ('priv', '~/.vagrant.d/insecure_private_key')]))])
[PROFILE ] Time (in seconds) to render './config/roster' using 'yaml' renderer: 0.0015110969543457031
[DEBUG ] Matched minions: {'test': {'host': '192.168.121.117', 'user': 'vagrant', 'priv': '~/.vagrant.d/insecure_private_key'}}
[DEBUG ] LazyLoaded roots.envs
[DEBUG ] Could not LazyLoad roots.init: 'roots.init' is not available.
[DEBUG ] Updating roots fileserver cache
[DEBUG ] LazyLoaded local_cache.prep_jid
[DEBUG ] Adding minions for job 20180616115608058884: ['minion']
[DEBUG ] Could not LazyLoad cmd.run: 'cmd.run' is not available.
[DEBUG ] Performing shimmed, blocking command as follows:
cmd.run df -h
[DEBUG ] Executed SHIM command. Command logged to TRACE
[DEBUG ] Child Forked! PID: 27215 STDOUT_FD: 10 STDERR_FD: 12
[DEBUG ] VT: Salt-SSH SHIM Terminal Command executed. Logged to TRACE
[DEBUG ] RETCODE 192.168.121.117: 0
[DEBUG ] LazyLoaded nested.output
minion:
Filesystem Size Used Avail Use% Mounted on
udev 2.0G 0 2.0G 0% /dev
tmpfs 396M 5.4M 391M 2% /run
/dev/vda1 9.2G 1.4G 7.3G 17% /
tmpfs 2.0G 0 2.0G 0% /dev/shm
tmpfs 5.0M 0 5.0M 0% /run/lock
tmpfs 2.0G 0 2.0G 0% /sys/fs/cgroup
tmpfs 396M 0 396M 0% /run/user/1000
Summary
Salt SSH is a nice alternative for minions where it is not possible and/or convenient to install a salt-minion. Common uses for running Salt SSH include managing IOT devices and bootstrapping minions with Salt to manage them in master mode.