Salt, or SaltStack, is a remote execution tool and configuration management system, based on the community-sourced Salt platform. The remote execution capabilities allow administrators to run commands on various machines in parallel with a flexible targeting system. The configuration management functionality establishes a client-server model to quickly, easily, and securely bring infrastructure components in line with a given policy.
Salt provides many commands to take advantage of the components outlined above. There is some significant crossover in terms of functionality between these tools, but we’ve attempted to highlight their primary functions below.
For More Salt Posts on Salt@FoxuTech
Salt commands
- salt-master – daemon used to control the Salt minions
- salt-minion – daemon which receives commands from a Salt master.
- salt-key – management of Salt server public keys used for authentication.
- salt – main CLI to execute commands across minions in parallel and query them too.
- salt-ssh – allows to control minion using SSH for transport
- salt-run – execute a salt runner
- salt-call – runs module. Function locally on a minion, use – local if you don’t want to contact your master
- salt-cloud – VM provisioning in the cloud
- salt-api – daemons which offer an API to interact with Salt
- salt-cp – copy a file to a set of systems
- salt-syndic – daemon running on a minion that passes through commands from a higher master
- salt-proxy – Receives commands from a master and relay these commands to devices that are unable to run a full minion.
- spm – frontend command for managing salt packages.
Remote execution
First obvious thing we could do with our master/minion infrastructure is to run command remotely, for example we could run
# salt fox1 test.ping fox1: Â Â Â True
It confirm your fox1 minion is alive, he just responded True as expected from our test.ping function.
embedded documentation
To get more insight about this function, refer to its documentation
salt '*' sys.doc test.ping test.ping: Used to make sure the minion is up and responding. Not an ICMP ping. Returns ``True``. CLI Example: Â Â Â salt '*' test.ping
The test module contains other function, to list all of them
salt --vebose '*' sys.list_functions test
command structure
Salt command structure is composed below for reference,
command-line options –verbose, see below for more
target which minion to target
module.function which function to run on target, for example sys.list_functions
arguments which argument to pass to the function, we passed test in our example above
Command line options
As most Unix commands, Salt comes with lots of options available
--help see available command-line options --verbose or -v turns on verbosity -t TIMEOUT change timeout of the running command --async runs without waiting for a respond --show-timeout which minion timed out
remote execution tips & tricks
modules, state functions
salt '*' sys.list_modules         # List all the preloaded Salt modules salt '*' sys.list_functions       # List all the functions salt '*' sys.list_state_modules   # List all the state modules salt '*' sys.list_state_functions # List all the state functions
network
salt '*' network.ip_addrs         # Get IP of your minion salt '*' network.ping <hostname>  # Ping a host from your minion salt '*' network.traceroute <host> # Traceroute a host from your minion salt '*' network.get_hostname     # Get hostname salt '*' network.mod_hostname     # Modify hostname
more example in the documentation
minion status
salt-run manage.status            # What is the status of all my minions? (both up and down) salt-run manage.up                # Any minions that are up? salt-run manage.down # Any minions that are down?
jobs
salt-run jobs.active              # get list of active jobs salt-run jobs.list_jobs           # get list of historic jobs salt-run jobs.lookup_jid <job_id> # get details of this specific job
system
salt 'minion*' system.reboot      # Let's reboot all the minions that match minion* salt '*' status.uptime            # Get the uptime of all our minions salt '*' status.diskusage salt '*' status.loadavg salt '*' status.meminfo
packages
salt '*' pkg.list_upgrades        # get a list of packages that need to be upgrade salt '*' pkg.upgrade              # Upgrades all packages via apt-get dist-upgrade (or similar) salt '*' pkg.version htop         # get current version of the bash package salt '*' pkg.install htop         # install or upgrade bash package salt '*' pkg.remove htop
services
salt '*' service.status <service name> salt '*' service.available <service name> salt '*' service.stop <service name> salt '*' service.start <service name> salt '*' service.restart <service name> salt '*' ps.grep <service name>
commands
salt '*' cmd.run 'echo really Happy!' salt '*' cmd.run_all 'echo really Happy!'
Matching
Salt offers many ways to target specific minion in your environment, let’s review all of them
glob matching
It’s what we’ve been using so far, it’s like the glob matching of your Unix shell
salt 'fox-??' test.ping salt 'fox-0[1-9]' test.ping
Perl Regular expression matching
Perl is famous when it comes to regular expression, so Salt is able to use this powerful syntax
salt -E 'fox' test.ping salt -E 'fox-.*' test.ping salt -E '^fox-01$' test.ping salt -E 'fox-((01)|(02))' test.ping
List matching
Sometimes you want to restrict remote execution to a known list of servers
salt -L 'fox-01,fox-02,fox-03' test.ping
Grain and Pillar matching
Grains describe minions characteristics like operating system, release number, cpu_model, kernel, etc.… You can target nodes based on them
salt -G 'os:Ubuntu' test.ping
to list all the grains available for minions
salt '*' grains.items
To get the value of a grain
salt '*' grains.get osfullname
You can add your own
salt '*' grains.setval web frontend salt '*' grains.delval web
Pillar are similar but stored on the Master. Similarly, with Pillar you can
salt '*' pillar.items salt '*' pillar.get hostname
To target minion using Pillar
salt -I 'branch:fox*' test.ping
IP Addresses
Use -S to match against IP Addresses (IPv4 only for now)
salt -S 192.168.0.161 test.ping salt -S 10.0.0.0/16 test.ping
In state or pillar files matching looks like
'192.168.0.0/24':  - match: ipcidr  - internal
Compound
We’ve kept the most powerful matching capability for the end, it combines all the above
salt -C 'server-* and G@os:Ubuntu and not L@server-02' test.ping
The different letters for different matching method are
G Grains glob
E Perl regexp on minion ID
P Perl regexp on Grains
L List of Minion
I Pillar glob
S Subnet/IP address
R Range cluster
Nodegroups
If you have a set of nodes that you target often and don’t want to repeat yourself, you can declare a nodegroup within your master configuration. They are declared inside your /etc/salt/master configuration file using a compound statement
nodegroups: group1: 'L@saltstack-f01,saltstack-f02 or admin*.domain.name' group2: 'G@os:Debian and domain.name' group3: 'G@os:Debian and N@group1' group4: Â - 'G@fox:tech' Â - 'or' Â - 'G@fox:utech'
Your master then need to be restarted.
To then match a nodegroup on the CLI
salt -N group1 test.ping
Batch size
If you want to do a rolling upgrade, you can use
salt -G 'os:Debian' --batch-size 25% apache.signal restart
25% can also be an absolute number
–batch-size start on that many minion first
–batch-wait amount of time before working on the next batch
Curious about targeting?
Find more details on targeting on the official documentation
Automate your infrastructure
Built on top of Remote execution, Salt offer powerful Configuration Management capabilities. So far, we’ve been using execution modules which are iterative, for configuration management we’ll be transitioning to state modules which are declarative and idempotent.
To list the function of a given state module
salt '*' sys.list_state_functions pkg
Get a documentation on any of them
salt '*' sys.state_doc pkg.latest
Illustrate how state management works, lets create a state file (sls) which will install some useful packages on our system at /srv/salt/tools.sls
tools:  pkg.latest:    - pkgs:      - iftop      - vnstat      - htop      - iotop      - curl      - vim      - logwatch      - unattended-upgrades      - fail2ban
Apply the above state using
salt '*' state.sls tools
Applying each state one by one to a minion would not be really efficient, let me introduce top.sls files that use targeting to assign state to minions. The structure is simple, it starts with the environment name, it’s base by default and continue on with targets and state files name without their extension.
base: Â '*': Â Â Â - tools
To apply all states configured in your top.sls file just run
salt '*' state.apply
For a dry-run
salt '*' state.apply test=True
List of available state modules
Pillar
Not all minion should look the same, so Pillar were invented to attach keys/values to them to dynamically change their state based on their profile.
To use Pillar, you first need a directory to store them, so create a Pillar root directory which is by default
mkdir /srv/pillar
Create your first Pillar file named for example /srv/pillar/pillar_common.sls, it’s just a YAML file containing data
branch: trunk github: http://github.com/planetrobbie
In the above file you can also use Jinja2 tricks to setup different pillar value depending on grains
{% if grains['id'].startswith('dev') %} branch: trunk {% elif grains['id'].startswith('qa') %} branch: dev {% else %} branch: master {% endif %}
You can now create a /srv/pillar/top.sls file to attach pillar data file to minion using the targeting capabilities of Salt.
base: Â '*': Â Â Â Â - pillar_common
Now tell the minions to fetch their pillar data from the master with
salt '*' saltutil.refresh_pillar
Verify all minions have the corresponding data set, for example
salt '*' pillar.get branch
Now you can access Pillar data in your state file using the following Jinja2 syntax
{{ pillar['branch'] }}
more complex data structure can be accessed like this
{{ pillar['pkgs']['apache'] }}
You can also provides default value using the pillar.get function
{{ salt['pillar.get']('pkgs:apache', 'httpd') }}
To investigate further the pillar concept, consult this walkthrough