Introduction

  • A (very) quick introduction to Salt

  • David Douard (Logilab)

What is Salt?

  • Quite new (first release in March 2011)
  • Started by Thomas Hatch, now developped by SaltStack Inc. and the community
  • Apache license (with no hidden proprietary stuff)
  • Python
  • ZMQ for communication
  • very active community
  • very flexible and extensible
  • latest stable version is 0.17.4
  • next releases will be named following the periodic table of elements (2014.1 RC has been released a couple of weeks ago)

What is salt?

From the official web site:

SaltStack takes a new approach to infrastructure management by developing software that is easy enough to get running in seconds, scalable enough to manage tens of thousands of servers, and fast enough to control and communicate with them in milliseconds. SaltStack delivers a dynamic infrastructure communication bus used for orchestration, remote execution, configuration management and much more. The Salt open source project was launched in 2011 and today is the fastest-growing, most-active configuration management / systems management project in the world. SaltStack is the company responsible for keeping the Salt project healthy and dynamic. Salt remains 100% open.

So What is Salt?

  • a Remote Execution Framework

  • a Configuration Management System

  • a Cloud Provisionning Tool

  • a Virtual Machine Management Tool

  • a toolkit!

A remote execution framework

  • between a Master and Minions

  • All communications over ZMQ

    • PUB/SUB (master -> minions)
    • REQ/REP (minion -> master)
  • All communications are encrypted (AES256)

Possible topologies

  • no master at all (masterless, limited features)

  • master and minion on the same host

  • one master, N minions (the most common situation)

  • N masters, M minions (with syndic nodes)

image

Salt components: key management

  • Minion public key must be manually accepted on the master

    • May configure a pre-accepted key for mass deployment

    • May auto-accept keys for mass deployment

Salt components: remote execution

  • modules: the remote execution backbone; Python modules present on all minions;

  • returners: allow saving minion responses in various datastores; default is formatted text for CL usage; can be Redis, Mongo, SQL, JSON,...

  • targeting: how to reach minions; can be glob, regex, node groups, grains based; can be used for batching execution

  • grains: live data for the running system;can be used in the templating engine

Salt components: config management

  • states: express the expected state of a minion in a declarative manner; based on states modules (many available, easy to add/write) that use the remote execution components

  • renderers: allow to write state files using the language, templating engine, etc. you want

  • pillars: declare global values usefull to configure machines

Salt components: other tools

  • file server: used mainly by the configuration management system, but can be used for whatever you want

  • syndic: the key for a wide deployments

  • peer communications: allow minions to communication with other minions (disabled by defaut)

  • reactor system: make your infrastructure react to events

  • scheduling executions: schedule any kind of execution on the master or on minions

Remote Execution

root@master:~$ salt <target> <command> <options>
  • target: literal ID name, glob patterns, PCRE, list, grain-based selection, ...

  • command:

    • one of the many available commands in salt (more than 80 modules defining 400 commands)

    • easy to write custom modules (and easy to deploy and use)

    • any shell command via the cmd.run command

  • options: command specific arguments

Examples

root@salt:~# salt '*' grains.item oscodename
     cn1.openstack.mycompany.com:
       oscodename: wheezy
     cn2.openstack.mycompany.com:
       oscodename: wheezy
     postgres.mycompany.com:
       oscodename: wheezy
     kvm1.mycompany.com:
       oscodename: squeeze
     cn3.openstack.mycompany.com:
       oscodename: wheezy
     ci1.mycompany.com:
       oscodename: wheezy
     dev1.mycompany.com:
       oscodename: wheezy
     kvm2.mycompany.com:
       oscodename: wheezy
     webapp.mycompany.com:
       oscodename: wheezy
     fs.voip.mycompany.com:
       oscodename: wheezy

Examples

root@salt:~# salt '*.openstack.mycompany.com' pkg.version openssh-server
     cn1.openstack.mycompany.com:
         1:6.0p1-4
     cn2.openstack.mycompany.com:
         1:6.0p1-4
     postgres.openstack.mycompany.com:
         1:6.0p1-4
     cn3.openstack.mycompany.com:
         1:6.0p1-4

Configuration management

  • based on state files (like manifest in Puppet or recipe in chef)
  • simple syntax, it's just data (consisting in dicts, lists, strings and numbers)
  • several formats (not a DSL, default is yaml, can be plain Python)
  • templatable (via jinja2 by default, easy to use another template engine)
  • based on state classes (many available, easy to write yours)
  • a master is also a file server
  • states can be invoqued (applied) individually

Example

Ensure ntpd is running on every node (must be installed):

root@salt:~# salt '*' state.single service.running name=ntpd
     7dfea7e074f0:
     ----------
         State: - service
         Name:      ntp
         Function:  running
             Result:    True
             Comment:   Started Service ntp
             Changes:   ntp: True
     
     
     Summary
     ------------
     Succeeded: 1
     Failed:    0
     ------------
     Total:     1

State syntax

ntp:
       pkg:
         - installed
       service:
         - name: ntpd
         - running
         - watch:
       - file: /etc/ntp.conf
     
     /etc/ntp.conf:
       file:
         - managed
         - require:
       - pkg: ntp
         - source: salt://ntp/ntp.conf

State syntax explained

ntp:             <-- ID for a set of states
       pkg:           <-- state declaration
         - installed  <-- function of the state to run
       service:       <-- state declaration
         - name: ntpd <-- arguments for functions
         - running    <-- function to run (with argument)
         - watch:     <-- state dependency declaration
           - file: /etc/ntp.conf <-- ID of a another state
     
     /etc/ntp.conf:  <-- ID
       file:         <-- state decl
         - managed   <-- function
         - require:  <-- requisity statement
           - pkg: ntp <-- req. statement args
         - source: salt://ntp/ntp.conf <-- arguments

states directory

  • main file is top.sls

  • package/module organization (similar to Python):

    • package like: a directory with a init.sls file in it

top.sls file

  • Declare what state to apply to which minions:

    base:
           '*':
             - ssh
             - ntp
           'role:revproxy':
             - match: pillar
             - apache.vhost
           '*.openstack.mycompny.com':
             - openstack

top.sls file

  • all states matching a given minion:

    root@master:~# salt cn1.mycompany.com state.show_highstate
  • apply all declared states on a minion (dry run):

    root@master:~# salt cn1.mycompany.com state.highstate test=True
  • apply all declared states on a minion:

    root@master:~# salt cn1.mycompany.com state.highstate

Salt for Debian enthusiasts

  • there are Debian packages!

  • there is Debian Salt Team!
    • Joe Healy
    • Franklin G Mendoza
    • Andriy Senkovych
  • packages are available in wheezy-backports...

    • but are quite old (0.16.4)
    • however 0.17.4 is in jessie

Using salt on a Debian system

Using salt to configure a Debian system

  • once you have a minion running and properly configured, you may want

    • to install packages on the Debian system

    • to add custom reposiroty sources

    • to ensure services are running

    • to know details on your Debian system

Salt on Debian: install packages

  • the pkg virtual state can be used as is (distribution agnostic):

    root@master:~# salt '*' state.single pkg.installed name=vim
  • but package name may vary depending on the distribution

Salt on Debian: install packages

  • the pkg virtual salt module can be used to manage packaging installation:

    root@master:~# salt '*' pkg.install vim
         root@master:~# salt '*' pkg.install vim refresh=True
         root@master:~# salt '*' pkg.install vim fromrepo=wheezy-backports
         root@master:~# salt '*' pkg.version vim
         root@master:~# salt '*' pkg.upgrade_available vim
         root@master:~# salt '*' pkg.upgrade # apt-get dist-upgrade
         root@master:~# salt '*' pkg.remove vim
         root@master:~# salt '*' pkg.refresh_db
         root@master:~# salt '*' pkg.list_pkgs
         root@master:~# salt '*' pkg.list_repos
         root@master:~# salt '*' pkg.latest_version vim
         root@master:~# salt '*' pkg.file_list vim

Salt on Debian: add repositories

  • the pkgrepo state can be used to declare the presence of a Debian repository (can be used for ppa on ubuntu):
# logilab.sls
     include:
       - apt.pinning
     
     logilab-public-acceptance:
       pkgrepo.managed:
         - human_name: Logilab acceptance public Debian repository
         - name: deb http://download.logilab.org/acceptance {{ grains['oscodename'] }}/
         - key_url: http://download.logilab.org/logilab-dists-key.asc
         - gpgcheck: 1
         - require:
           - file: /etc/apt/preferences.d/logilab-pinning

Salt on Debian: services

  • nothing Debian specific either:

    ntp:
           pkg:
             - installed
           service:
             - name: ntpd
             - running
             - watch:
               - file: /etc/ntp.conf
         - require:
           - pkg: ntp
  • it will not monitor the service (this can be done either using tools like monit or using salt scheduler and reactionner systems)

Salt on Debian: status of the system

  • ask for grains:

    # ask for grains values
         root@master:~# salt minion grains.items
         [...]
         lsb_distrib_codename: wheezy
         lsb_distrib_description: Debian GNU/Linux 7.3 (wheezy)
         lsb_distrib_id: Debian
         lsb_distrib_os: GNU/Linux
         lsb_distrib_release: 7.3
         [...]
         os: Debian
         os_family: Debian
         osarch: amd64
         oscodename: wheezy
         osfullname: Debian
         osrelease: 7.3

Salt on Debian: status of the system

  • ask for service status:

    # status of a service
         root@master:~# salt minion  service.status <service name>
         root@master:~# salt minion  service.available <service name>
         root@master:~# salt minion  service.disable <service name>
         root@master:~# salt minion  service.disabled <service name>
         root@master:~# salt minion  service.enable <service name>
         root@master:~# salt minion  service.enabled <service name>
         root@master:~# salt minion  service.get_all
         root@master:~# salt minion  service.reload <service name>
         root@master:~# salt minion  service.start <service name>
         root@master:~# salt minion  service.restart <service name>
         root@master:~# salt minion  service.stop <service name>

Final thoughts

  • Salt is an awesome project for the Debian enthusiast: try it!

  • Salt is really a FOSS project (no proprietary modules, no "put your data in my hands" stuff, etc.)

  • Salt is production ready, but it needs more tests and stabilization: help the community write more tests!

  • We (Logilab) use it more and more, and like it more and more

  • We (Logilab) want to see it spread in France (like it does in the US)

  • Question?