Operational
Assess your knowledge
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.
salt-bootstrap
salt-bootstrap
salt-bootstrap is the easiest method to install SaltStack.
There are many types of modules:
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
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
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
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
YAML
YAML
YAML isn't Markup Language
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
Basic Salt States
A state file to ensure mysql-server is installed
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
/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
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
Jinja for State File Templating
Jinja
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
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
Cliff Notes
/srv/salt/top.sls
base:
'minion01':
- apache
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
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
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
Cliff Notes
/srv/salt/apache/init.sls
include:
- install_apache
- create_users
Order
Order
mysql_install:
pkg.installed:
- name: mysql-server
- order: 1
Grains
Grains
Information about the system the minion is running on or custom 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
Lab: Using Grains in States
"Targeting based on OS grain information"
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
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."
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
Files
The File Module
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!
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
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
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!
Cliff Notes
/srv/pillar/top.sls
base:
'os:{{ grains['os'] }}':
- match: grain
- {{ grains['os'] }}
/srv/pillar/Ubuntu.sls
users_list:
- fred
- wilma
- pebbles
- bambam
((( 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:
Salt Mine
Runs arbitrary salt execution functions at a specified interval
Reactor
Provides a system where commands can be executed in response to events within the infrastructure
Examples of types of events:
Syndic
Like a master of masters, it allows you to create a hierarchal structure of control for large or sprawling infrastructure
Syndic Example Topology
Salt Returners
Stores the results of Salt jobs in an external backend
Salt Runners
Like execution modules but run on the master, interacting with minions using the salt client.
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