Salt Stack
Configuration management tool
Makes remote nodes
in defined states
node = minion
State
Configuration we want a minion to have
Rubyist guy:
is an expressive identifier
- present
is a function name
- name:
simon
is an argument and value of function
State
Ensures that the named user is absent
Bad guy:
user:
- absent
- name:
moriarty
State
Short form
simon:
is an identifier & «name» argument of function
user.present
is a module & function names are split by dot
moriarty:
user.absent
Functions use identifier as «name» argument
if it is not given explicitly
Nginx State
Ensures that Nginx package is installed
nginx:
pkg:
- installed
Nginx State
Ensures that last stable version of Nginx package is installed
Nginx official repository:
pkgrepo:
- managed
- name:
deb http://nginx.org/packages/ubuntu/ precise nginx
- key_url:
http://nginx.org/keys/nginx_signing.key
Nginx State
Ensures that last stable version of Nginx package is installed
nginx:
pkg:
- installed
- require:
- pkgrepo:
Nginx official repository
Requisite statements
Provides dependencies between states
require
makes sure that required state was finished before current state
watch
runs current state's watcher function for any change of watched state
They use the same syntax to point to particular state
«module name: ID»
Nginx State
Ensures that Nginx is installed and service is running
nginx:
pkg:
- installed
service:
- running
- watch:
- pkg:
nginx
- file:
/etc/nginx/nginx.conf
Nginx State
Downloads config from master and places it on minion
/etc/nginx/nginx.conf:
file:
- managed
- source:
salt://website/nginx.conf
- user:
root
- group:
root
- mode:
644
- template:
jinja
Nginx config fragment
File is rendered by Jinja template engine
# ...
server {
listen 80;
server_name example.com;
location /static/ {
alias {{ pillar['website_static_dir'] }};
}
# ...
}
# ...
Pillar
Defines global values which are available by «pillar» variable
website_static_dir:
/path/to/static/
How to run it
One master — N minions
Commands sent from master are broadcasted to minions via ZeroMQ PUB/SUB
State and Pillar files are stored on the master and transferred to the minions on demand
There might be hundreds or thousands minions
or it might be only one — masterless minion
Masterless minion
Bootstrap Salt
$ wget -O - http://bootstrap.saltstack.org | sudo sh
Tell minion not to use master
$ echo 'file_client: local' > /etc/salt/minion
Masterless minion
/etc/salt/minion
file_roots:
base:
name of environment
- /srv/salt
where to look for State files
pillar_roots:
base:
name of environment
- /srv/pillar
where to look for Pillar files
Top file
Top file is needed to bind minions to environments and assign State files to minions
base:
name of environment
'*':
is a wildcard, here it means «all minions»
- user
State file name, e.g., /srv/salt/user.sls
- website.nginx
/srv/salt/website/nginx.sls
/srv/salt/top.sls
Masterless minion
Run «highstate» command to execute top.sls
$ salt-call state.highstate
base
environment is used by default
$ salt-call state.highstate env=production
$ salt-call state.highstate env=development
More environments
/etc/salt/minion
file_roots:
base:
- /srv/salt/base
development:
- /srv/salt/dev
production:
- /srv/salt/prod
More environments
/etc/salt/minion
file_roots:
base:
- /srv/salt/base
development:
- /srv/salt/dev
first see here for State file
- /srv/salt/base
if file was not found then see here
production:
- /srv/salt/prod
- /srv/salt/base
More environments
/srv/salt/base/top.sls
development:
'*':
- user
/srv/salt/base/user.sls
- website.nginx
/srv/salt/dev/website/nginx.sls
production:
'*':
- user
/srv/salt/base/user.sls
- website.nginx
/srv/salt/prod/website/nginx.sls