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
  user: is a state module name, there are plenty built in
    - 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

More examples


Thanks!

Q&A
Marsel Mavletkulov @marselester
Python Developer

SaltStack

By Marsel Mavletkulov