The purpose of this tutorial is to demonstrate how quickly you can configure a system to be managed by Salt States. For detailed information about the state system please refer to the full states reference.
This tutorial will walk you through using Salt to configure a minion to run the Apache HTTP server and to ensure the server is running.
Before continuing make sure you have a working Salt installation by following the instructions in the Salt install guide.
Stuck?
The Salt Project community can help offer advice and help troubleshoot technical issues as you're learning about Salt. One of the best places to talk to the community is on the Salt Project Slack workspace.
States are stored in text files on the master and transferred to the minions on
demand via the master's File Server. The collection of state files make up the
State Tree
.
To start using a central state system in Salt, the Salt File Server must first
be set up. Edit the master config file (file_roots
) and
uncomment the following lines:
file_roots:
base:
- /srv/salt
Note
If you are deploying on FreeBSD via ports, the file_roots
path defaults
to /usr/local/etc/salt/states
.
Restart the Salt master in order to pick up this change:
pkill salt-master
salt-master -d
On the master, in the directory uncommented in the previous step,
(/srv/salt
by default), create a new file called
top.sls
and add the following:
base:
'*':
- webserver
The top file is separated into environments (discussed
later). The default environment is base
. Under the base
environment a
collection of minion matches is defined; for now simply specify all hosts
(*
).
Targeting minions
The expressions can use any of the targeting mechanisms used by Salt — minions can be matched by glob, PCRE regular expression, or by grains. For example:
base:
'os:Fedora':
- match: grain
- webserver
sls
file¶In the same directory as the top file, create a file
named webserver.sls
, containing the following:
apache: # ID declaration
pkg: # state declaration
- installed # function declaration
The first line, called the ID declaration, is an arbitrary identifier. In this case it defines the name of the package to be installed.
Note
The package name for the Apache httpd web server may differ depending on
OS or distro — for example, on Fedora it is httpd
but on
Debian/Ubuntu it is apache2
.
The second line, called the State declaration, defines which of the Salt
States we are using. In this example, we are using the pkg state
to ensure that a given package is installed.
The third line, called the Function declaration, defines which function
in the pkg state
module to call.
Renderers
States sls
files can be written in many formats. Salt requires only
a simple data structure and is not concerned with how that data structure
is built. Templating languages and DSLs are a dime-a-dozen and everyone
has a favorite.
Building the expected data structure is the job of Salt Renderers and they are dead-simple to write.
In this tutorial we will be using YAML in Jinja2 templates, which is the
default format. The default can be changed by editing
renderer
in the master configuration file.
Next, let's run the state we created. Open a terminal on the master and run:
salt '*' state.apply
Our master is instructing all targeted minions to run state.apply
. When this function is executed without any SLS
targets, a minion will download the top file and attempt to
match the expressions within it. When the minion does match an expression the
modules listed for it will be downloaded, compiled, and executed.
Note
This action is referred to as a "highstate", and can be run using the
state.highstate
function.
However, to make the usage easier to understand ("highstate" is not
necessarily an intuitive name), a state.apply
function was added in version 2015.5.0, which
when invoked without any SLS names will trigger a highstate.
state.highstate
still exists and
can be used, but the documentation (as can be seen above) has been updated
to reference state.apply
, so keep
the following in mind as you read the documentation:
state.apply
invoked without any
SLS names will run state.highstate
state.apply
invoked with SLS names
will run state.sls
Once completed, the minion will report back with a summary of all actions taken and all changes made.
Warning
If you have created custom grain modules, they will not be available in the top file until after the first highstate. To make custom grains available on a minion's first highstate, it is recommended to use this example to ensure that the custom grains are synced when the minion starts.
SLS File Namespace
Note that in the example above, the SLS file
webserver.sls
was referred to simply as webserver
. The namespace
for SLS files when referenced in top.sls
or an Include declaration
follows a few simple rules:
The .sls
is discarded (i.e. webserver.sls
becomes
webserver
).
Each subdirectory under the configured file_roots (default:
/srv/salt/
) is represented with a dot (following the Python
import model) in Salt states and on the command line.
webserver/dev.sls
on the filesystem is referred to as
webserver.dev
in Salt
Because slashes are represented as dots, SLS files can not contain
dots in the name (other than the dot for the SLS suffix). The SLS
file webserver_1.0.sls
can not be matched, and webserver_1.0
would match the directory/file webserver_1/0.sls
A file called init.sls
in a subdirectory is referred to by the path
of the directory. So, webserver/init.sls
is referred to as
webserver
.
If both webserver.sls
and webserver/init.sls
happen to exist,
webserver/init.sls
will be ignored and webserver.sls
will be the
file referred to as webserver
.
Troubleshooting Salt
If the expected output isn't seen, the following tips can help to narrow down the problem.
Salt can be quite chatty when you change the logging setting to
debug
:
salt-minion -l debug
By not starting the minion in daemon mode (-d
)
one can view any output from the minion as it works:
salt-minion
Increase the default timeout value when running salt. For example, to change the default timeout to 60 seconds:
salt -t 60
For best results, combine all three:
salt-minion -l debug # On the minion
salt '*' state.apply -t 60 # On the master
This tutorial focused on getting a simple Salt States configuration working.
Part 2 will build on this example to cover more advanced
sls
syntax and will explore more of the states that ship with Salt.