Operational

 

Intros

 

Assess your knowledge

http://bit.ly/salt_ops

 

Saltier Terms

 

Job

The complete set of tasks to be performed by the execution of a Salt command.

 

High Data

The data structure in a SLS file that represents a set of state declarations.

 

High State

The collection of states to be applied to a system.

 

Low State

The collection of processed states after requisites and order are evaluated.

 

Overstate

A system by which a Master can issue function calls to minions in a deterministic order.

 

Grain

A key-value pair which contains a fact about a system, such as its hostname, network addresses.

 

Pillar

A simple key-value store for user-defined data to be made available to a minion. Often used to store and distribute sensitive data to minions.

 

State Module

A module which contains a set of state functions.

 

State Function

A function contained inside a state module which manages the application of a particular state to a system. State functions frequently call out to one or more execution modules to perform a given task.

 

State Run

The application of a set of states on a set of systems.

 

Top File

Determines which SLS files should be applied to various systems and organizes those groups of systems into environments.

 

Install and deploy Salt

salt-bootstrap

 

salt-bootstrap

salt-bootstrap is the easiest method to install SaltStack.

There are many types of modules:

  • Multiple OS support
  • Highly extendable
  • Can install Salt Master / Minion
  • Can configure the Minion
  • Can use Github tags like packages

Download salt-bootstrap


wget -O install_salt.sh http://bootstrap.saltstack.org

Lab

Download the salt-bootstrap script to all machines

Example flags for Minions


sh install_salt.sh -A [ Master's IP or DNS Record ]

This will install the Minion and configure it to talk to the master

Example flags for Masters


sh install_salt.sh -M -N

This will install only the Master

Lab: Installation

  1. Install salt-minion on machine minion01 and minion02
  2. Install salt-master on the Master
 

Cliff Notes


wget  --no-check-certificate -O install_salt.sh http://bootstrap.saltstack.org
sh install_salt.sh -M -N
sh install_salt.sh -A sd-pipeline.com

salt-keys

Salt Keys

Salt Keys manages which machines are allowed / not allowed to communicate with the Salt Master.


salt-key

The -A flag will accept all pending keys...but -a [ HostName ] is best.

Lab

  1. Read the salt-key help file
  2. Accept the Minion's keys
 

Cliff Notes


salt-key -a lab1

Verify installation


salt-master --versions-report

If installed correctly, you will see something like:


Salt: 2014.1.0
Python: 2.7.6 (default, Mar 22 2014, 22:59:56)
Jinja2: 2.7.2
M2Crypto: 0.21.1
msgpack-python: 0.3.0
msgpack-pure: Not Installed
pycrypto: 2.6.1
PyYAML: 3.10
PyZMQ: 14.0.1
ZMQ: 4.0.4

Lab

Verify the Minion and Master installations.

 

Cliff Notes


salt-master --versions-report

Master Config Tour

Minion Config Tour

 

Using Execution Models

What is an Execution Module?

Execution Module

Execution modules are used when calling modules directly from the command line


salt '*' user.add fred uid gid groups home shell

Documentation

Documentation

Salt's documentation is embedded inside and can be reach via command-line.


salt '*' sys.doc

Or you can run -d, --doc on newer versions of Salt.

The best place for the docs is online at http://docs.saltstack.com


salt --doc

Installing a Package

Installing a Package

Installing a package from command-line very simple. Just use pkg.install


salt '*' pkg.install cowsay

Lab

Install cowsay on minion 01

Running Commands

Running Commands

Running arbitrary commands can come in handy for one time operations. This is done with the cmd.run module.

Execution Example:


salt '*' cmd.run 'cowsay HELLO EVERYBODY!'



salt \* cmd.run 'tail /var/log/syslog'

Lab

Disable your firewall using cmd.run on the minions

 

Cliff Notes


salt '*' cmd.run 'service iptables stop'

Output Printing Options

Output Formatting

Salt can print a range of formatted outputs using the --out flag

Example outputs:

grains, highstate, json, key, overstatestage, pprint, raw, txt, yaml

Lab

Add an user named "thatch" using cmd.run with JSON output

 

Cliff Notes


salt '*' user.add thatch --out json

 

Writing Salt States

YAML

 

YAML

YAML isn't Markup Language

  • Human readable
  • Superset of JSON
  • Basic Structures: List, Associative Array
  • The de-facto data structure for Salt States

Lists in YAML

Block format


- lions
- tigers
- bears

Inline format


[lions, tigers, bears]

Oh my

 

Associative Arrays in YAML

Block format


key: value
username: lovekittyvideos
password: can_haz_cheezburger

Inline format


{key: value, username: lovekittyvideos, password: can_haz_cheezburger}


Complex structures in YAML

Nested associative array


John Doe:
  age: 30

List of associative arrays


- {name: John Doe, age: 30}
- name: Jane Doe
  age: 32

Associative array of lists


men: [John, Frank]
women: 
  - Jane
  - Susie

State Files

 

What's in a Salt State?

A salt state consists of identifiers, state module and function declarations, and sometimes function parameters

  • Identifiers name the resources to operate on
  • State modules bundle functionality to manage a type of resource
  • State functions are used to define the desired state of the resource
  • Function parameters provide specific details for the state function

Basic Salt States

A state file to ensure mysql-server is installed

/srv/salt/mysql.sls

mysql-server:    # Identifier
  pkg:           # State module
    - installed  # State function

You may also supply the State module and function on a single line


mysql-server:     # Identifier
   pkg.installed  # State module and function on the same line

 

Salt States with Function Parameters

A state file to ensure the directory /tmp/test exists

/srv/salt/testfolder.sls

/tmp/test:           # Identifier
  file.directory:    # State module and function
    - user: root     # State function parameter
    - dir_mode: 644  # Another parameter


 

Applying a Salt State

Applying the /srv/salt/mysql.sls Salt State to all minions


salt '*' state.sls mysql

 

Lab

  1. Write a salt state /srv/salt/apache.sls that ensures apache is installed
  2. Apply this new state to minion01
 

Cliff Notes


salt 'minion01' state.sls apache

Organizing salt States

State files may be organized in folders

Our /srv/salt/mysql.sls could be moved to /srv/salt/mysql/init.sls and used in the same manner


salt '*' state.sls mysql

If we've put an additional state in /srv/salt/mysql/service.sls it can be ran as mysql.service


salt '*' state.sls mysql.service

 

External State Files

Salt has fileserver modules that can refer to remote state files

States can be referenced directly from version control systems

  • Git (gitfs)
  • Mercurial (hgfs)
  • Subversion (svnfs)

Jinja for State File Templating



 

Jinja

  • Templating framework for Python
  • Inspired by Django's templating language
 

Variables in Jinja

Use double curly brackets for variable substitution


Hello, {{ name }}.

Rendered template


Hello, Clarice.

 

Loops in Jinja

Use curly bracket and percent for control structures such as loops



{% for username in ['root', 'apache'] %}
- {{ username }}
{% endfor %}

Rendered template


- root

- apache


 

Jinja in a Salt State

Managing multiple users with a loop


{% for username in ['root', 'apache', 'thatch'] %}
{{ username }}:
  user.present
{% endfor %}

Rendered Salt State


root:
  user.present

apache:
  user.present

thatch:
  user.present

Targeting Minions with top.sls

 

Target minions with the top file


  • /srv/salt/top.sls is the "top file"

  • Generates the highstate, a collection of states to apply to a minion

  • Supports multiple environments, base is the default

Example top.sls file


base:         # Environment
  '*':        # Minion targeting; * matches all minions
    - mysql   # State to apply to all minions
  'web*':     # Target minions with names that start with 'web'
    - apache  # State to apply to select minions

Apply highstate to all minions


salt '*' state.highstate

Lab

  1. Write a topfile that will apply the apache state to minion01
  2. Run state.highstate to verify
 

Cliff Notes

/srv/salt/top.sls

base:
  'minion01':
    - apache

 

Ordering Execution

Require

Require

Used to load the dependent state before the depending current


mysql_install:
  pkg.installed:
    - name: mysql

mysql_config:
  file.managed:
    - name: /etc/my.cnf
    - source: salt://files/my.cnf
    - require:
      - pkg: mysql_install

Require_in

Does the reverse of require


mysql_install:
  pkg.installed:
    - name: mysql
    - require_in:
      - file: mysql_config

mysql_config:
  file.managed:
    - name: /etc/my.cnf
    - source: salt://files/my.cnf

 

Lab

  1. In your install apache state create a new state to ensure that apache is running
  2. Make sure that the service.running state is ran after the install of apache
 

Cliff Notes


install_apache:
  pkg.installed:
    - name: apache2

start_apache:
  service.running:
    - name: apache2
    - require:
      - pkg: install_apache

Watch

Watch

Statement used to monitor changes in other states


mysql_service_restart:
  service.restart:
    - name: mysqld
    - watch:
      - file: mysql_config

Prereq

Prereq

Allows for actions to be taken based on the expected results of a state that has not yet been executed


graceful_down:
  cmd.run:
    - name: service apache graceful
    - prereq:
      - file: site_code

apache_start:
  cmd.run:
    - name: service apache start
    - watch:
      - file: site_code

site_code:
  file.recurse:
    - name: /opt/site_code
    - source: salt://site/code

 

Lab

  1. In your states, have a state that will run the echo command before apache will be installed
  2. Create another state that will run a different echo command after apache gets installed
 

Cliff Notes


pre_echo_apache:
  cmd.run:
    - name: "echo 'apache will be installed'"
    - prereq:
      - pkg: install_apache

post_echo_apache:
  cmd.run:
    - name: "echo 'apache has been installed'"
    - watch:
      - pkg: install_apache


Include

 

Include

You can include whole sls files in your states

init.sls


include:
  - foo

foo.sls


bar_install:
  pkg.installed:
    - name: bar
    - require:
      - sls: foo

 

Lab

  1. Split your big state file in to separate directories with a init.sls file in it and include them in a single state
  2. Create seperate sls files for each of your states
  3. Remove your sates form the init.sls file and replace them with includes for the files you created
 

Cliff Notes

/srv/salt/apache/init.sls


include:
  - install_apache
  - create_users

Order

Order


mysql_install:
  pkg.installed:
    - name: mysql-server
    - order: 1

 

Leveraging Grains and Pillars

Grains

 

Grains

Information about the system the minion is running on or custom grains

  • Static info from minion start
  • Custom grains
  • /etc/salt/minion
  • /etc/salt/grains

docs.saltstack.com

Command Line Examples


salt '*' grains.ls
salt '*' grains.items
salt -G 'os:CentOS' test.ping

Top file example

/srv/pillar/top.sls


'role:web':
    - match: grain
    - webserver
'role:database':
    - match: grain
    - database

 

Lab

  1. List and view available grains
  2. Set a custom grain of role to your minions
 

Lab: Using Grains in States

"Targeting based on OS grain information"

  1. In your install apache state. set a jinja variable to the correct package name, using an if statement based on the os Grain.
  2. Use that variable in the install apache state to install the correct package depending on OS
 

Cliff Notes


{% if grains['os'] == 'Ubuntu' %}
{% set apache_package = 'apache2' %}
{% else %}
{% set apache_package = 'httpd' %}
{% endif %}

install_apache:
  pkg.installed:
    - name: {{ apache_package }}


Pillar

 

Pillar

Designed to offer global variables to minions

  • Managed like Salt State Tree
  • /srv/pillar
  • Storing sensitive data
 

Examples


salt '*' pillar.items
salt -P 'key:value' test.ping


{{ pillar['key'] }}

 

Example pillar sls file

example in pillar


bob_ross: 'happy little trees'

list_of_words:
  - its
  - so
  - fluffy

example in jinja


{{ pillar['bob_ross'] }}

example when rendered


happy little trees

 

Lab: Using Pillar

"Set pillar data based on OS grain and use that pillar data in the state created in the previous lab instead of the grain."

  1. Set up your pillar top file to target based on the os grain and use differnt pillar sls files for each OS
  2. Set the correct apache package name to a variable in the respective OS's pillar file
 

Cliff Notes: top.sls

/srv/pillar/top.sls


base:
  'os:Ubuntu':
    - match: grain
    - Ubuntu

  'os:CentOS':
    - match: grain
    - CentOS


 

Cliff Notes: pillar sls files

/srv/pillar/Ubuntu/init.sls


apache_package: apache2


 

Templating

Files

The File Module

  • create/remove
  • source
  • permissions
  • templating
  • variables

docs.saltstack.com

 

Ship a File


ship_this_file:
  file.managed:
    - name: /home/fred/shippedfile.txt
    - source: salt://webserver/files/shippingfile.txt
    - user: thatch
    - group: thatch
    - mode: '0644'

Directories can be managed


create_my_directories:
  file.directory:
    - name: /home/thatch/mydirs/dir1
    - user: thatch
    - group: thatch
    - mode: '0755'
    - makedirs: True

 

Lab: Game of Chowns!

  1. Create a state that will create a directory in the thatch users home directory called saltstuff
  2. Create a file on your master that you want to ship to the minions
  3. Create a state that will ship the file you just created to the saltstuff directory that you created
 

Cliff Notes


ship_salt_stuff_file:
  file.managed:
    - name: /home/thatch/saltstuff/saltfile.txt
    - source: salt://files/saltfile.txt
    - user: thatch
    - group: thatch
    - file_mode: '0744'
    - dir_mode: '0755'
    - makedirs: True

 

Where the Magic Happens

Bringing it all together. Pillar, Grains, and Jinja to template files.

Rule all the things!

 

Use a Template


ship_salt_stuff_file:
  file.managed:
    - name: /home/thatch/saltstuff/saltfile.txt.jinja
    - source: salt://files/saltfile.txt.jinja
    - user: thatch
    - group: thatch
    - mode: '0755'
    - makedirs: True
    - template: jinja
    - context:
        users_list:
          - fred
          - wilma
          - pebbles
          - bambam

 

Jinja in the index.html


{% for user in users_list %}
{{ user }}
{% endfor %}
 

Lab: Files with Context

  1. Create a state that will ship an index.html file to /var/www/html on the minions
  2. Modify your state so that the index.html is templated
  3. Pass it variables via context, make the variables a list of users
  4. fred, wilma, pebbles, bambam
  5. In the index.html file have it list out those users, exept for the user bambam
 

Cliff Notes


ship_salt_stuff_file:
  file.managed:
    - name: /var/www/html/index.html.jinja
    - source: salt://files/index.html.jinja
    - user: thatch
    - group: thatch
    - mode: '0755'
    - makedirs: True
    - template: jinja
    - context:
        users_list:
          - fred
          - wilma
          - pebbles
          - bambam

 

Cliff Notes


{% for user in users_list %}
{% if user == 'bambam' %}
{% else %}
{{ user }}
{% endif %} {% endfor %}

But who wants to set variables in every state?

Variables can use many different sources

  • Grains
  • Pillar
  • Jinja

Grains

You can access grains in your template by the {{ grains }} variable substitution


{{ grains['os'] }}

Pillar

You can access pillar data the same way!


{{ pillar['users_list'] }}

You could have done this in the index.html if you had a pillar value set


{% for user in pillar['users_list'] %}
{% if user == 'bambam' %}
{% else %}
{{ user }}
{% endif %} {% endfor %}
 

Lab: all together now!

  1. In pillar create a list of users that only Ubuntu minions will share
  2. In pillar create a different list of users that only CentOS minions will share
  3. Use that list of users in your templated index.html
  4. Also have your index.html display its OS
 

Cliff Notes

/srv/pillar/top.sls


base:
  'os:{{ grains['os'] }}':
    - match: grain
    - {{ grains['os'] }}

/srv/pillar/Ubuntu.sls


users_list:
  - fred
  - wilma
  - pebbles
  - bambam

 

Fleur De Sel

((( Really fancy salt )))

 

Salt Cloud

Spins up servers on the cloud, automatically installing the Salt Minion and approving the minions key.

Works with popular cloud APIs:

  • Openstack (ie. Rackspace Cloud Server)
  • Parallels
  • Softlayer
  • Amazon
 

Salt Mine

Runs arbitrary salt execution functions at a specified interval

  • Provides results to all minions
  • Useful for integrating live data in state runs and executions
 

Reactor

Provides a system where commands can be executed in response to events within the infrastructure

Examples of types of events:

  • Minion added to infrastructure
  • Highstate ran
  • Cloud-based server removed
 

Syndic

Like a master of masters, it allows you to create a hierarchal structure of control for large or sprawling infrastructure

  • Good for infrastructures with thousands of nodes
  • Good for infrastructures that span multiple regions or datacenters

Syndic Example Topology

 

Salt Returners

Stores the results of Salt jobs in an external backend

  • Redis
  • MongoDB
  • Postgres
  • SMTP
 

Salt Runners

Like execution modules but run on the master, interacting with minions using the salt client.

  • Handy for scripting large scale events
  • Written in python, structurally similar to other modules
  • Ran via salt-run
 

Assess your knowledge

http://bit.ly/salt_ops

 

A massive thanks to the content dev team...

Allen Oster

Bruce Stringer

Chris Caillouet

Chris Old

Eric Hernandez

Jason Swindle

Justin Phelps

Kenneth Wilke

Victor Palma


 


http://www.saltstack.com

Salt Operational

By Rackspace University

Salt Operational

  • 1,284