Operational
Intros
Assess your knowledge
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
- Install salt-minion on machine minion01 and minion02
- 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
- Read the salt-key help file
- 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
- Write a salt state /srv/salt/apache.sls that ensures apache is installed
- 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
- Write a topfile that will apply the apache state to minion01
- 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
- In your install apache state create a new state to ensure that apache is running
- 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
- In your states, have a state that will run the echo command before apache will be installed
- 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
- Split your big state file in to separate directories with a init.sls file in it and include them in a single state
- Create seperate sls files for each of your states
- 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
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
- List and view available grains
- Set a custom grain of role to your minions
Lab: Using Grains in States
"Targeting based on OS grain information"
- In your install apache state. set a jinja variable to the correct package name, using an if statement based on the os Grain.
- 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."
- Set up your pillar top file to target based on the os grain and use differnt pillar sls files for each OS
- 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
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!
- Create a state that will create a directory in the thatch users home directory called saltstuff
- Create a file on your master that you want to ship to the minions
- 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
- Create a state that will ship an index.html file to /var/www/html on the minions
- Modify your state so that the index.html is templated
- Pass it variables via context, make the variables a list of users
- fred, wilma, pebbles, bambam
- 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!
- In pillar create a list of users that only Ubuntu minions will share
- In pillar create a different list of users that only CentOS minions will share
- Use that list of users in your templated index.html
- 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
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
Salt Operational
By Rackspace University
Salt Operational
- 1,284