Mastering SaltStack - Second Edition - Joseph Hall - E-Book

Mastering SaltStack - Second Edition E-Book

Joseph Hall

0,0
41,99 €

-100%
Sammeln Sie Punkte in unserem Gutscheinprogramm und kaufen Sie E-Books und Hörbücher mit bis zu 100% Rabatt.

Mehr erfahren.
Beschreibung

Take charge of SaltStack to automate and configure your enterprise-grade environments

About This Book

  • Automate tasks effectively and take charge of your infrastructure
  • Effectively scale Salt to manage thousands of machines and tackle everyday problems
  • Explore Salt's inner workings and advance your knowledge of it

Who This Book Is For

This book is ideal for IT professionals and ops engineers who already manage groups of servers, but would like to expand their knowledge and gain expertise with SaltStack. This book explains the advanced features and concepts of Salt. A basic knowledge of Salt is required in order to get to grips with advanced Salt features.

What You Will Learn

  • Automate tasks effectively, so that your infrastructure can run itself
  • Start building more complex concepts
  • Master user-level internals
  • Build scaling strategies
  • Explore monitoring strategies
  • Learn how to troubleshoot Salt and its subcomponents
  • Explore best practices for Salt

In Detail

SaltStack is a powerful configuration management and automation suite designed to manage servers and tens of thousands of nodes. This book showcases Salt as a very powerful automation framework. We will review the fundamental concepts to get you in the right frame of mind, and then explore Salt in much greater depth. You will explore Salt SSH as a powerful tool and take Salt Cloud to the next level. Next, you'll master using Salt services with ease in your infrastructure. You will discover methods and strategies to scale your infrastructure properly. You will also learn how to use Salt as a powerful monitoring tool.

By the end of this book, you will have learned troubleshooting tips and best practices to make the entire process of using Salt pain-free and easy.

Style and approach

This book follows a step-by-step conversational tone. Topics are covered in detail through examples and a user-friendly approach.

Sie lesen das E-Book in den Legimi-Apps auf:

Android
iOS
von Legimi
zertifizierten E-Readern

Seitenzahl: 457

Veröffentlichungsjahr: 2016

Bewertungen
0,0
0
0
0
0
0
Mehr Informationen
Mehr Informationen
Legimi prüft nicht, ob Rezensionen von Nutzern stammen, die den betreffenden Titel tatsächlich gekauft oder gelesen/gehört haben. Wir entfernen aber gefälschte Rezensionen.



Table of Contents

Mastering SaltStack Second Edition
Credits
Foreword
About the Author
About the Reviewer
www.PacktPub.com
Why subscribe?
Preface
What this book covers
What you need for this book
Who this book is for
Conventions
Reader feedback
Customer support
Errata
Piracy
Questions
1. Essentials Revisited
Executing commands remotely
Master and minions
Targeting minions
Glob
Perl Compatible Regular Expression (PCRE)
List
Subnet
Grain
Grain PCRE
Pillar
Compound
Nodegroup
Using module functions
test.ping
test.echo
test.sleep
test.version
pkg.install
pkg.remove
file.replace
Other file functions
Various user and group functions
sys.doc
SLS file trees
SLS files
Tying things together with top files
Organizing the SLS directories
Using states for configuration management
Using include blocks
Ordering with requisites
require
watch
onchanges
onfail
use
prereq
Inverting requisites
Extending SLS files
The basics of grains, pillars, and templates
Using grains for minion-specific data
Centralizing variables with pillars
Managing files dynamically with templates
A quick Jinja primer
Summary
2. Diving into Salt Internals
Understanding the Salt configuration
Following the configuration tree
Looking inside /etc/salt/
Managing Salt keys
Exploring the SLS directories
Examining the Salt cache
The master job cache
The master-side minion cache
The external file server cache
The minion-side proc/ directory
External modules
The renderer
Rendering SLS files
Render pipes
Serving templated files
Understanding the loader
Dynamic modules
Execution modules
Cloud modules
Plunging into the state compiler
Imperative versus declarative
Requisites
High and low states
High states
Low states
Enforcing statefulness
name
result
changes
comment
Summary
3. Managing States
Handling multiple states
Including other SLS files
Spanning multiple environments
Using the base environment
Breaking out environments
Understanding master_tops
Using Salt Stack Formulas on GitHub
Examining the standard layout
formula name
pillar.example
README
LICENSE
FORMULA
Cloning formulas
Using the Salt Package Manager
Thinking of SPM as a package manager
Thinking of SPM as a repository manager
Configuring SPM repositories
Downloading repository metadata
Creating SPM repositories
Set aside a directory to hold packages
Share that directory
Populate the directory
Create the repository metadata
Building packages
version
release
summary
description
name
os
os_family
dependencies
optional
recommended
minimum_version
top_level_dir
license
Where to use SPM
SPM configuration
spm_conf_file
formula_path
pillar_path
reactor_path
spm_logfile
spm_default_include
spm_repos_config
spm_cache_dir
spm_build_dir
spm_build_exclude
spm_db
Summary
4. Exploring Salt SSH
Grappling with SSH
Remote shells
Using rosters
The flat roster
host
port
user
passwd
sudo
priv
timeout
thin_dir
Other built-in rosters
scan
cache
cloud
ansible
Building dynamic rosters
Using Salt SSH
Using a Saltfile
Salt versus Salt SSH
Architecture
Performance
Understanding the salt-thin agent
Building the thin package
Including extra modules
Deploying the thin package
Executing the thin package
The Salt SSH shim
Preparing for Salt states
Running Salt
Salt's running data
Using the raw SSH mode
Caching SSH connections
Summary
5. Managing Tasks Asynchronously
Looking at the event system
Reviewing the basics
The structure of event data
Watching event data
Installing the event listener
Using the event listener
Firing custom data
Namespacing events
Namespacing guidelines
Some common events
salt/auth
salt/key
salt/minion/minion_id/start
salt/job/job_id/new
salt/job/job_id/ret/minion_id
salt/presence/present
salt/presence/change
Common cloud events
salt/cloud/vm_name/creating
salt/cloud/vm_name/requesting
salt/cloud/vm_name/querying
salt/cloud/vm_name/waiting_for_ssh
salt/cloud/vm_name/deploying
salt/cloud/vm_name/created
salt/cloud/vm_name/destroying
salt/cloud/vm_name/destroyed
Salt API events
salt/netapi/url_path
Building reactors
Configuring reactors
Writing reactors
Calling execution modules
Calling runner modules
Calling wheel modules
Writing more complex reactors
Sending out alerts
Using webhooks
Reactors calling reactors
Using Thorium
A word on engines
Looking at Thorium basics
Enabling Thorium
Setting up the Thorium directory tree
Writing Thorium SLS files
Using requisites
Using the register
Looking forward
Using the queue system
Learning how queues work
Adding to the queue
Listing queues
Listing items in a queue
Processing queue items
Deleting items from a queue
Using queues with the reactor
Spreading out State runs
Dividing tasks among minions
Summary
6. Taking Advantage of Salt Information Systems
Understanding pillar_roots
Templating pillar_roots
Calling out to other modules
Using Salt's external pillars
Configuring the etcd pillar
Using git_pillar
Using the mysql pillar
Some final thoughts on external pillars
Using multiple external pillars
Caching pillar data
Understanding SDB
Securely storing passwords
Staying simple
Using SDB URIs
Configuring SDB
Performing SDB lookups
Getting data
Setting data
Deleting data
Comparing pillars and SDB
Where the data is generated
Differences in drivers
Salt Cloud and others
Summary
7. Taking Salt Cloud to the Next Level
Examining the Salt Cloud configuration
Global configurations
Provider and profile configuration
Providers
Profiles
Extending configuration blocks
Using SDB with Salt Cloud
Using SDB with OpenStack
Using SDB with AWS/EC2
Using SDB with other cloud providers
Building custom deploy scripts
Understanding the Salt Bootstrap script
Installing from prebuilt packages
Installing from Git
Looking back at legacy deploy scripts
Writing your own deploy scripts
Passing arguments to scripts
Using file maps
Taking a look at cloud maps
Using reactors with Salt Cloud
Setting up the event tags
Working with autoscale reactors
Cloud cache
Using cloud cache events
Setting up a schedule
Catching cloud cache events
Summary
8. Using Salt with REST
Looking at Salt's HTTP library
Why a Salt-specific library?
Using the http.query function
GET versus POST
Decoding return data
Using the http.query state
Using http.query with reactors
Understanding the Salt API
What is the Salt API?
Setting up the Salt API
CherryPy
Tornado
WSGI
Creating SSL certificates
Configuring authentication
The external authentication module
Taking your first steps with the Salt API
Issuing one-off commands
Working with webhooks
Reacting with Thorium
Security considerations
More complex authentication
Summary
9. Understanding the RAET and TCP Transports
Comparing RAET and ZeroMQ
Starting with HTTP
SSH - the old favorite
Using ZeroMQ
ZeroMQ and security
The need for RAET
Flow-based programming
The pieces of the puzzle
Black boxes
Shared storage
Concurrent scheduling
Driving with RAET
Configuring RAET
The RAET architecture
The basics
The RAET scheduler
Estates and yards
Looking at asynchronous programming
Cooks in a restaurant
Examining the TCP transport
Using the TCP transport
Summary
10. Strategies for Scaling
All about syndication
Different folks, different strokes
No need for micromanaging
Configuring syndication
High availability with multiple masters
Built-in high-availability configuration
Old-school high availability
The round-robin DNS
IP-based load balancing
Synchronizing files
Base configuration files
Synchronizing the nonexternal files
Using rsync
Using the event reactor
Incorporating external data sources
The external job cache
Using returners on the minions
Using the master job cache
External filesystems
GitFS
base
root
mountpoint
user and password
insecure_auth
pubkey, privkey, and passphrase
Other source-control backends
SVNFS
root and mountpoint
trunk
branches
tags
HGFS
S3FS
One environment per bucket
Multiple environments per bucket
AzureFS
External pillars
cmd_yaml/cmd_json
git
redis
mysql
Using the master API
The Salt keys
Configuration
The file and pillar roots
Using the wheel reactor
Using wheel with Thorium
Testing the load in the infrastructure
Using the minionswarm.py script
Swarm internals
Summary
11. Monitoring with Salt
Monitoring basics
Establishing a baseline
Reading the system vitals in Salt
status.loadavg
status.cpustats
status.meminfo
status.vmstats
disk.usage and status.diskusage
status.w
status.all_status and status.custom
Monitoring with returners
Deciding on a returner
Using monitoring states
Defining a monitoring state
Monitoring with web calls
Working with beacons
Monitoring file changes
Beacon intervals
Setting up alerts
Alerting in state files
Alerting from beacons
Watching file changes
Monitoring bad logins
Using aggregate data with Thorium
Summary
12. Exploring Best Practices
Future-proofing your infrastructure
Setting up your directories
Standard directory locations
.sls versus init.sls
Shallow versus deep
Subdividing further
The SLS efficiency
Includes and extends
Using includes
Using extends
Using templates to simplify SLS files
Working with loops
Decisions, decisions
Using the built-in states
Naming conventions
Generic names
Explicit names
Templates and variables
Nested variables
Referring to variables in templates
Summary
13. Troubleshooting Problems
What the...?
Addressing the problem source
Where is the trouble?
Master-to-minion communication
Network and CPU congestion
Checking minion load
Querying the Salt job data
Using debug and trace modes
info
warn
error
debug/trace
Running services in debug mode
Using salt-call locally
Working with YAML
YAML basics
dict
list
YAML idiosyncrasies
Spacing
Numbers
Booleans
List items
Troubleshooting YAML
Asking the community for help
The salt-users mailing list
Asking questions
The Salt issue tracker
Researching before posting
Formatting your issues
Requesting features
#salt on IRC
Final community thoughts
Summary

Mastering SaltStack Second Edition

Mastering SaltStack Second Edition

Copyright © 2016 Packt Publishing

All rights reserved. No part of this book may be reproduced, stored in a retrieval system, or transmitted in any form or by any means, without the prior written permission of the publisher, except in the case of brief quotations embedded in critical articles or reviews.

Every effort has been made in the preparation of this book to ensure the accuracy of the information presented. However, the information contained in this book is sold without warranty, either express or implied. Neither the author, nor Packt Publishing, and its dealers and distributors will be held liable for any damages caused or alleged to be caused directly or indirectly by this book.

Packt Publishing has endeavored to provide trademark information about all of the companies and products mentioned in this book by the appropriate use of capitals. However, Packt Publishing cannot guarantee the accuracy of this information.

First published: August 2015

Second edition: November 2016

Production reference: 1211116

Published by Packt Publishing Ltd.

Livery Place

35 Livery Street

Birmingham 

B3 2PB, UK.

ISBN 978-1-78646-739-3

www.packtpub.com

Credits

Author

Joseph Hall

Copy Editor

Madhusudan Uchil

Reviewer

Peng Yao

Project Coordinator

Judie Jose

Commissioning Editor

Kartikey Pandey

Proofreader

Safis Editing

Acquisition Editor

Namrata Patil

Indexer

Francy Puthiry

Content Development Editor

Amedh Pohad

Production Coordinator

Shantanu N. Zagade

Technical Editor

Mohit Hassija

Foreword

The Mastering SaltStack book is one of my favorite Salt books. This book will get you past the basics of Salt and into what makes it a truly powerful automation framework. Tools like Salt Reactor, Thorium and Salt-SSH allow you to get the most out of Salt. The best ways to take Salt to the next level are revealed in this book, in an easy-to-understand way that will help you solve your problems.

Joseph Hall is likely the best person to write this book. He is not only a close friend, but has also been involved with the Salt project from the very beginning, including the early design of the Salt States system. Joseph is the second person to write code for Salt (apart from me). He was the first engineer hired by SaltStack.

Thomas S. Hatch

Founder and CTO, SaltStack

About the Author

Starting as a support technician and progressing to being a web programmer, QA engineer, systems administrator, Linux instructor, and cloud engineer, Joseph Hall has touched just about every area of the modern technology world. He is currently a senior cloud and integrations engineer at SaltStack. Joseph enjoys working with some of the best minds in the business with his coworkers and SaltStack's partners. He is also the author of Extending SaltStack, Packt Publishing.

You can find him on LinkedIn at https://www.linkedin.com/in/techhat and on GitHub at https://github.com/techhat.

About the Reviewer

Peng Yao is an operations engineer. He is the founder and coordinator of the China SaltStack User Group. He translated Mastering SaltStack to Chinese.

www.PacktPub.com

For support files and downloads related to your book, please visit www.PacktPub.com.

Did you know that Packt offers eBook versions of every book published, with PDF and ePub files available? You can upgrade to the eBook version at www.PacktPub.com and as a print book customer, you are entitled to a discount on the eBook copy. Get in touch with us at [email protected] for more details.

At www.PacktPub.com, you can also read a collection of free technical articles, sign up for a range of free newsletters and receive exclusive discounts and offers on Packt books and eBooks.

https://www.packtpub.com/mapt

Get the most in-demand software skills with Mapt. Mapt gives you full access to all Packt books and video courses, as well as industry-leading tools to help you plan your personal development and advance your career.

Why subscribe?

Fully searchable across every book published by PacktCopy and paste, print, and bookmark contentOn demand and accessible via a web browser

Preface

I'm very excited to have been given the chance to put this book together. I've been given the rare opportunity to watch Salt grow from an idea in the brain of Tom Hatch to an award-winning open source project, and onward to the flagship product of an award-winning open source company. Salt has become an incredibly powerful framework, which I wish I'd had access to years ago.

Every day, I learn something new about Salt. This book is a collection of a number of those things, aimed at the advanced user. Don't see it as the last word on any of the topics that it covers. Instead, see it as a guide on your journey to use this tool to its fullest potential.

As you read through this book, I hope that the ideas and examples in it inspire you to update and innovate your infrastructure.

What this book covers

Chapter 1, Essentials Revisited, takes a step back to a few of the basics inside of Salt. These concepts are critical to understanding many of the concepts discussed in this book, and many of them will be explored further in later chapters.

Chapter 2, Diving into Salt Internals, goes in depth with the management of Salt’s own configuration files, how Salt’s loader system works, before finally discussing the state compiler.

Chapter 3, Managing States, builds upon the state concepts from the previous chapter and goes on to discuss how Salt states can be compiled together to form a more cohesive solution for your organization.

Chapter 4, Exploring Salt SSH, will provide you with a basic understanding of Salt’s SSH transport layer, before jumping into a more technical overview of the underlying components.

Chapter 5, Managing Tasks Asynchronously, explores some of the subsystems in Salt that are designed for handling tasks, which interact with each other to achieve an end goal.

Chapter 6, Taking Advantage of Salt Information Systems, looks at some of the subsystems in Salt that are designed entirely for data management. The functionality of these subsystems can be utilized by the master or minion, and sometimes both.

Chapter 7, Taking Salt Cloud to the Next Level, brings you an understanding of how Salt interacts with public clouds and how you can extend that interaction to achieve a more cohesive infrastructure definition.

Chapter 8, Using Salt with REST, covers using Salt to communicate over HTTP, both as a client and as a server. With these APIs in place, Salt can either be a cog in another system or be the system that manages the cogs.

Chapter 9, Understanding the RAET and TCP Transports, follows a very technical discussion of various transport layers, both inside and outside of Salt. If you are looking to move beyond the ZeroMQ transport, this chapter is for you.

Chapter 10, Strategies for Scaling, explores a number of subsystems designed to allow Salt to manage large-scale data centers. Even if you are managing a small infrastructure now, I would encourage you to take a look at the options available here: they may just help you rethink your existing infrastructure anyway.

Chapter 11, Monitoring with Salt, explores many of the ways that Salt can be used to extend your own monitoring system and even bring its own monitoring tools to the party.

Chapter 12, Exploring Best Practices, helps you know how to most effectively use Salt in a way that will not only lead to easy management for you, but also for those who work with or follow you.

Chapter 13, Troubleshooting Problems, talks about some of the ways that things can go wrong in Salt and what to do when that happens.

What you need for this book

While this book covers a lot of ground, the focus is on Salt. It is recommended that you use the latest version of Salt available to you, though most of the information is also relevant to older versions.

A number of other products and services are mentioned in this book and its examples. While the examples will be useful with those products and services, they are designed to still be generic enough to demonstrate the intended information without requiring the purchase or installation of or subscription to third-party entities.

Any hardware or platform that can support Salt may be used for the examples in this book that pertain to minion operations. The Salt master is not yet supported in a Windows environment, so any master-oriented examples will require a Linux or Unix environment.

Who this book is for

This book is ideal for IT professionals and ops engineers who already manage groups of servers but would like to expand their knowledge and gain expertise with SaltStack. This book explains the advanced features and concepts of Salt. A basic knowledge of Salt is required in order to get to grips with advanced Salt features.

Conventions

In this book, you will find a number of text styles that distinguish between different kinds of information. Here are some examples of these styles and an explanation of their meaning.

Code words in text, database table names, folder names, filenames, file extensions, pathnames, dummy URLs, user input, and Twitter handles are shown as follows: "Unix distributions will often use the /usr/local/etc/salt/ directory instead, while Windows uses the C:\salt\ directory ."

A block of code is set as follows:

name: apache os: RedHat, Debian, Ubuntu, Suse, FreeBSD os_family: RedHat, Debian, Suse, FreeBSD version: 201607 release: 1 minimum_version: 2015.8 top_level_dir: apache summary: Formula for installing Apache description: Formula for installing the Apache web server optional: mod_perl recommended: mod_ssl

Any command-line input or output is written as follows:

# mkdir -p /srv/salt/devenv/

New terms and important words are shown in bold. Words that you see on the screen, for example, in menus or dialog boxes, appear in the text like this: "On the main screen of the repository, you will see a button titled Clone or download."

Note

Warnings or important notes appear in a box like this.

Tip

Tips and tricks appear like this.

Reader feedback

Feedback from our readers is always welcome. Let us know what you think about this book-what you liked or disliked. Reader feedback is important for us as it helps us develop titles that you will really get the most out of. To send us general feedback, simply e-mail [email protected], and mention the book's title in the subject of your message. If there is a topic that you have expertise in and you are interested in either writing or contributing to a book, see our author guide at www.packtpub.com/authors.

Customer support

Now that you are the proud owner of a Packt book, we have a number of things to help you to get the most from your purchase.

Errata

Although we have taken every care to ensure the accuracy of our content, mistakes do happen. If you find a mistake in one of our books-maybe a mistake in the text or the code-we would be grateful if you could report this to us. By doing so, you can save other readers from frustration and help us improve subsequent versions of this book. If you find any errata, please report them by visiting http://www.packtpub.com/submit-errata, selecting your book, clicking on the Errata Submission Form link, and entering the details of your errata. Once your errata are verified, your submission will be accepted and the errata will be uploaded to our website or added to any list of existing errata under the Errata section of that title.

To view the previously submitted errata, go to https://www.packtpub.com/books/content/support and enter the name of the book in the search field. The required information will appear under the Errata section.

Piracy

Piracy of copyrighted material on the Internet is an ongoing problem across all media. At Packt, we take the protection of our copyright and licenses very seriously. If you come across any illegal copies of our works in any form on the Internet, please provide us with the location address or website name immediately so that we can pursue a remedy.

Please contact us at [email protected] with a link to the suspected pirated material.

We appreciate your help in protecting our authors and our ability to bring you valuable content.

Questions

If you have a problem with any aspect of this book, you can contact us at [email protected], and we will do our best to address the problem.

Chapter 1.  Essentials Revisited

Salt is a very powerful remote automation framework. Before we delve into the more advanced topics that this book covers, it would be wise to go back and review a few essentials. In this chapter, we will cover the following topics:

Using remote executionBasic SLS file tree structureUsing states for configuration managementBasics of grains, pillars, and templates

This book assumes that you already have root access on a device with a common distribution of Linux installed. The machine used in the examples in this book is running Ubuntu 14.04, unless stated otherwise. Most examples should run on other major distributions, such as recent versions of Fedora, RHEL 5/6/7, Suse, or Arch Linux.

Executing commands remotely

The underlying architecture of Salt is based on the idea of executing commands remotely. This is not a new concept; all networking is designed around some aspect of remote execution. This could be as simple as asking a remote web server to display a static Web page, or as complex as using a shell session to interactively issue commands against a remote server.

Under the hood, Salt is a more complex example of remote execution. But whereas most Internet users are used to interacting with only one server at a time (so far as they are aware), Salt is designed to allow users to explicitly target and issue commands to multiple machines directly.

Master and minions

Salt is based around the idea of a master, which controls one or more minions. Commands are normally issued from the master to a target group of minions, which then execute the tasks specified in the commands and return any resulting data back to the master.

Targeting minions

The first facet of the salt command is targeting. A target must be specified with each execution, which matches one or more minions. By default, the type of target is a glob, which is the style of pattern matching used by many command shells. Other types of targeting are also available, by adding a flag. For instance, to target a group of machines inside a particular subnet, the -S option is used:

# salt -S 192.168.0.0/24 test.ping

The following are most of the available target types, along with some basic usage examples. Not all target types are covered here; Range, for example, extends beyond the scope of this book. However, the most common types are covered.

Glob

This is the default target type for Salt, so it does not have a command line option. The minion ID of one or more minions can be specified, using shell wildcards if desired.

When the salt command is issued from most command shells, wildcard characters must be protected from shell expansion:

# salt '*' test.ping# salt \* test.ping

When using Salt from an API or from other user interfaces, quoting and escaping wildcard characters is generally not required.

Perl Compatible Regular Expression (PCRE)

Short Option: -E

Long Option: --pcre

When more complex pattern matching is required, a Perl Compatible Regular Expression (PCRE) can be used. This type of targeting was added to the earliest versions of Salt, and was meant largely to be used inside shell scripts. However, its power can still be realized from the command line:

# salt -E '^[m|M]in.[e|o|u]n$' test.ping

List

Short Option: -L

Long Option: --list

This option allows multiple minions to be specified as a comma-separated list. The items in this list do not use pattern matching such as globbing or regular expressions; they must be declared explicitly:

# salt -L web1,web2,db1,proxy1 test.ping

Subnet

Short Option: -S

Long Option: --ipcidr

Minions may be targeted based on a specific IPv4 or an IPv4 subnet in CIDR notation:

# salt -S 192.168.0.42 test.ping# salt -S 192.168.0.0/16 test.ping

As of Salt version 2016.3, IPv6 addresses cannot be targeted by a specific command line option. However, there are other ways to target IPv6 addresses. One way is to use grain matching.

Grain

Short Version: -G

Long Version: --grain

Salt can target minions based on individual pieces of information that describe the machine. This can range from the OS to CPU architecture to custom information (covered in more detail later in this chapter). Because some network information is also available as grains, IP addresses can also be targeted this way.

Since grains are specified as key/value pairs, both the name of the key and the value must be specified. These are separated by a colon:

# salt -G 'os:Ubuntu' test.ping# salt -G 'os_family:Debian' test.ping

Some grains are returned in a multi-level dictionary. These can be accessed by separating each key of the dictionary with a colon:

# salt -G 'ip_interfaces:eth0:192.168.11.38'

Grains which contain colons may also be specified, though it may look strange. The following will match the local IPv6 address (::1). Note the number of colons used:

# salt -G 'ipv6:::1' test.ping

Grain PCRE

Short Version: (not available)

Long Version: --grain-pcre

Matching by grains can be powerful, but the ability to match by a more complex pattern is even more so.

# salt --grain-pcre 'os:red(hat|flag)' test.ping

Pillar

Short Option: -I

Long Option: --pillar

It is also possible to match based on pillar data. Pillars are described in more detail later in the chapter, but for now we can just think of them as variables that look like grains.

# salt -I 'my_var:my_val' test.ping

Compound

Short Option: -C

Long Option: --compound

Compound targets allow the user to specify multiple target types in a single command. By default, globs are used, but other target types may be specified by preceding the target with the corresponding letter followed by the @ sign:

Letter

Target

G

Grains

E

PCRE minion ID

P

PCRE grains

L

List

I

Pillar

J

Pillar PCRE

S

Subnet/IP address

R

SECO range

The following command will target the minions that are running Ubuntu, have the role pillar set to web, and are in the 192.168.100.0/24 subnet.

# salt -C 'G@os:Ubuntu and I@role:web and [email protected]/24' test.ping

Boolean grammar may also be used to join target types, including and, or, and not operators.

# salt -C 'min* or *ion' test.ping# salt -C 'web* or *qa and G@os:Arch' test.ping

Nodegroup

Short Option: -N

Long Option: --nodegroup

While nodegroups are used internally in Salt (all targeting ultimately results in the creation of an on-the-fly nodegroup), it is much less common to explicitly use them from the command line. Node groups must be defined as a list of targets (using compound syntax) in the Salt master's configuration before they can be used from the command line. Such a configuration might look like the following:

nodegroups: webdev: 'I@role:web and G@cluster:dev' webqa: 'I@role:web and G@cluster:qa' webprod: 'I@role:web and G@cluster:prod'

Once a nodegroup is defined and the master configuration reloaded, it can be targeted from Salt:

# salt -N webdev test.ping

Using module functions

After a target is specified, a function must be declared. The preceding examples all use the test.ping function but, obviously, other functions are available. Functions are actually defined in two parts, separated by a period:

<module> . <function>

Inside a Salt command, these follow the target, but precede any arguments that might be added for the function:

salt <target> <module>.<function> [arguments...]

For instance, the following Salt command will ask all minions to return the text, "Hello world":

salt '*' test.echo 'Hello world'

A number of execution modules ship with the core Salt distribution, and it is possible to add more. Version 2016.3 of Salt ships with around 400 execution modules. Not all modules are available for every platform; in fact, by design, some modules will only be available to the user if they are able to detect the required underlying functionality.

For instance, all functions in the test module are necessarily available on all platforms. These functions are designed to test the basic functionality of Salt and the availability of minions. Functions in the Apache module, however, are only available if the necessary commands are located on the minion in question.

Execution modules are the basic building blocks of Salt; other modules in Salt use them for their heavy lifting. Because execution modules are generally designed to be used from the command line, an argument for a function can usually be passed as a string. However, some arguments are designed to be used from other parts of Salt. To use these arguments from the command line, a Python-like data structure is emulated using a JSON string.

This makes sense, since Salt is traditionally configured using YAML, and all JSON is syntactically-correct YAML. Be sure to surround the JSON with single quotes on the command line to avoid shell expansion, and use double quotes inside the string. The following examples will help.

A list is declared using brackets:

'["item1","item2","item3"]'

A dictionary is declared using braces (that is, curly brackets):

'{"key1":"value1","key2":"value2","key3":"value3"}'

A list can include a dictionary, and a dictionary can include a list:

'[{"key1":"value1"},{"key2":"value2"}]' '{"list1":["item1","item2"],"list2":["item3","item4"]}'

There are a few modules which can be considered core to Salt, and a handful of functions in each that are widely used.

test.ping

This is the most basic Salt command. Ultimately, it only asks the minion to return True. This function is widely used in documentation because of its simplicity, and to check whether a minion is responding. Don't worry if a minion doesn't respond right away; that doesn't necessarily mean it's down. A number of variables could cause a slower-than-usual return. However, successive failed attempts may be cause for concern.

test.echo

This function does little more than the test.ping command; it merely asks the minion to echo back a string that is passed to it. A number of other functions exist that perform similar tasks, including test.arg, test.kwarg, test.arg_type, and test.arg_repr.

test.sleep

A slightly more advanced testing scenario may require a minion to sleep for a number of seconds before returning True. This is often used to test or demonstrate the utilities that make use of the jobs system. The test.rand_sleep function is also useful for test cases where it is desirable to check the return from a large number of minions, with the return process spread out.

test.version

In a large enough infrastructure, a number of minions are bound to be running in a different version of Salt than others. When troubleshooting issues specific to certain versions of Salt, it helps to be able to take a quick look at the Salt version on each minion. This is the simplest way to check that. Checking the version of other packages that are maintained by the system packaging system can be performed with pkg.version.

pkg.install

Every package manager in Salt (as of version 2016.3) supports installing a package. This function can be as simple as asking for a single package name, or as complex as passing through a list of packages, each with a specific version. When using an execution module, you generally do not need to specify more than just a single package name, but inside the state module (covered later) the advanced functionality becomes more important.

pkg.remove

This matches the pkg.install function, allowing a certain package to be removed. Because versions are not so important when removing packages, this function doesn't get so complex. But it does allow passing a list of packages to be removed (using the pkgs argument) as a Python list. From the command line, this can be done using a JSON string.

file.replace

The sed command is one of the oldest members of the Unix administrator's toolkit. It has been the go-to command largely for tasks that involve editing files inline, and performing search and replace tasks. There have been a few attempts over the years to duplicate the functionality of the sed command. Initially, the file.sed function simply wrapped the Unix sed command. The file.psed function provided a Python-based replacement. However, sed is more than just a find/replace tool; it is a full language that can be problematic when used incorrectly. The file.replace function was designed from the ground up to provide the find/replace functionality that most users need, while avoiding the subtle nuances that can be caused by wrapping sed.

Other file functions

A number of common Unix commands have been added to the file function. The following functions complement the Unix command set for managing files and their metadata: file.chown, file.chgrp, file.get_mode, file.set_mode, file.link, file.symlink, file.rename, file.copy, file.move, file.remove, file.mkdir, file.makedirs, file.mknod, and a number of others.

Various user and group functions

The Unix toolset for managing users and groups is also available in Salt and includes user.add, user.delete, user.info, group.add, group.delete, group.info, user.chuid, user.chgid, user.chshell, user.chhome, user.chgroups, and many, many more.

sys.doc

By design, every public function in every execution module must be self-documenting. The documentation that appears at the top of the function should contain a description just long enough to describe the general use of the function, and must include at least one CLI example demonstrating the usage of that function.

This documentation is available from the minion using the sys.doc function. Without any arguments, it will display all the functions available on a particular minion. Adding the name of a module will show only the available functions in that module, and adding the name of a function will show only the documentation for that function, if it is available. This is an extremely valuable tool, both for providing simple reminders of how to use a function and for discovering which modules are available.

SLS file trees

There are a few subsystems in Salt that use an SLS file tree. The most common one of course is /srv/salt/, which is used for Salt states. Right after states are pillars (/srv/pillar/), which use a different file format but the same directory structure. Let's take a moment to talk about how these directories are put together.

SLS files

SLS stands for Salt State, which was the first type of file inside Salt to use this kind of file structure. While SLS files can be rendered in a number of different formats, by far the widest use is the default, YAML. Various templating engines are also available to help form the YAML (or other data structure) and again, the most popular is the default, Jinja.

Keep in mind that Salt is all about data. YAML is a serialization format that in Python, represents a data structure in a dictionary format. When thinking about how SLS files are designed, remember that they are a key/value pair: each item has a unique key, which is used to refer to a value. The value can in turn contain a single item, a list of items, or another set of key/value pairs.

The key to a stanza in an SLS file is called an ID. If no name inside the stanza is explicitly declared, the ID is copied to the name. Remember that IDs must be globally unique; duplicate IDs will cause errors.

Tying things together with top files

Both the state and the pillar system use a file called top.sls to pull the SLS files together and serve them to the appropriate minions, in the appropriate environments.

Each key in a top.sls file defines an environment. Typically, a base environment is defined, which includes all the minions in the infrastructure. Then other environments are defined that contain only a subset of the minions. Each environment includes a list of the SLS files that are to be included. Take the following top.sls file:

base: '*': - common - vim qa: '*_qa': - jenkins web: 'web_*': - apache2

With this top.sls, three environments have been declared: base, qa, and web. The base environment will execute the common and vim states across all minions. The qa environment will execute the jenkins state across all the minions whose ID ends with _qa. The web environment will execute the apache2 state across all the minions whose ID starts with web_.

Organizing the SLS directories

SLS files may be named either as an SLS file themselves (that is, apache2.sls) or as an init.sls file inside a directory with the SLS name (that is, apache2/init.sls).

Note

Note that apache2.sls will be searched for first; if it is not there, then apache2/init.sls will be used.

SLS files may be hierarchical, and there is no imposed limit on how deep directories may go. When defining deeper directory structures, each level is appended to the SLS name with a period (that is, apache2/ssl/init.sls becomes apache2.ssl). It is considered best practice by developers to keep a directory more shallow; don't make your users search through your SLS tree to find things.

Using states for configuration management

The files inside the /srv/salt/ directory define the Salt states. This is a configuration management format that enforces the state that a minion will be in: package X needs to be installed, file Y needs to look a certain way, service Z needs to be enabled and running, and so on. For example:

apache2: pkg: - installed service: - running file: - name: /etc/apache2/apache2.conf

States may be saved in a single SLS file, but it is far better to separate them into multiple files, in a way that makes sense to you and your organization. SLS files can use include blocks that pull in other SLS files.

Using include blocks

In a large SLS tree, it often becomes reasonable to have SLS files include other SLS files. This is done using an include block, which usually appears at the top of an SLS file:

include: - base - emacs

In this example, the SLS file in question will replace the include block with the contents of base.sls (or base/init.sls) and emacs.sls (or emacs/init.sls). This imposes some important restrictions on the user. Most importantly, the SLS files that are included may not contain IDs that already exist in the SLS file that includes them.

It is also important to remember that include itself, being a top-level declaration, cannot exist twice in the same file. The following is invalid:

include: - base include: - emacs

Ordering with requisites

State SLS files are unique among configuration management formats in that they are both declarative and imperative. They are imperative, as each state will be evaluated in the order in which it appears in the SLS file. They are also declarative because states may include requisites that change the order in which they are actually executed. For instance:

web_service: service.running: - name: apache2 - require: - pkg: web_package web_package: pkg.installed: - name: apache2

If a service is declared, which requires a package that appears after it in the SLS file, the pkg states will be executed first. However, if no requirements are declared, Salt will attempt to start the service before installing the package, because its codeblock appears before the pkg codeblock. The following will require two executions to complete properly:

web_service: service.running: - name: apache2 web_package: pkg.installed: - name: apache2

Requisites point to a list of items elsewhere in the SLS file that affect the behavior of the state. Each item in the list contains two components: the name of the module and the ID of the state being referenced.

The following requisites are available inside Salt states and other areas of Salt that use the state compiler.

require

The require requisite is the most basic; it dictates that the state that it is declared in is not executed until every item in the list that has been defined for it has executed successfully. Consider the following example:

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

In this example, a file will be copied to the minion first, then a package installed, then the service started. Obviously, the service cannot be started until the package that provides it is installed. But Debian-based operating systems such as Ubuntu automatically start services the moment they're installed, which can be problematic if the default configuration files aren't correct. This state will ensure that Apache is properly configured before it is even installed.

watch

In the preceding example, a new minion will be properly configured the first time. However, if the configuration file changes, the apache2 service will need to be restarted. Adding a watch requisite to the service will force that state to perform a specific action when the state that it is watching reports changes.

apache2: ...SNIP... service: - running - require: - pkg: apache2 - watch: - file: apache2 ...SNIP...

The watch requisite is not available for every type of state module. This is because it performs a specific action, depending on the type of module. For instance, when a service is triggered with a watch, Salt will attempt to start a service that is stopped. If it is already running, it will attempt either a reload: True, service.full_restart, or service.restart, as appropriate.

As of version 2016.3, the following states modules support using the watch requisite: service, pkg, cmd, event, module, mount, supervisord, docker, dockerng, etcd, tomcat, and test.

onchanges

The onchanges requisite is similar to watch, except that it does not require any special support from the state module that is using it. If changes happen, which should only occur when a state completes successfully, then the list of items referred to with onchanges will be evaluated.

onfail

In a simple state tree, the onfail requisite is less commonly used. However, a more advanced state tree, which is written to attempt alerting the user, or to perform auto-correcting measures, can make use of onfail. When a state is evaluated and fails to execute correctly, every item listed under onfail will be evaluated. Assuming that the PagerDuty service is properly configured via Salt and an apache_failure state has been written to use it, the following state can notify the operations team if Apache fails to start:

apache2: service: - running - onfail - pagerduty: apache_failure

use

It is possible to declare default values in one state and then inherit them into another state. This typically occurs when one state file has an include statement that refers to another file.

If an item in the state that is being used has been redeclared, it will be overwritten with the new value. Otherwise, the item that is being used will appear unchanged. Requisites will not be inherited with use; only non-requisite options will be inherited. Therefore, in the following SLS, the mysql_conf state will safely inherit the user, group, and mode from the apache2_conf state, without also triggering Apache restarts:

apache2_conf: file: - managed - name: /etc/apache2/apache2.conf - user: root - group: root - mode: 755 - watch_in: - service: apache2 mysql_conf: file: - managed - name: /etc/mysql/my.cnf - use: - file: apache2_conf - watch_in: - service: mysql

prereq

There are some situations in which a state does not need to run, unless another state is expected to make changes. For example, consider a web application that makes use of Apache. When the codebase on a production server changes, Apache should be turned off, so as to avoid errors with the code that has not yet finished being installed.

The prereq requisite was designed exactly for this kind of use. When a state makes use of prereq, Salt will first perform a test run of the state to see if the items referred to in the prereq are expected to make changes. If so, then Salt will flag the state with the prereq as needing to execute.

apache2: service: - running - watch: - file: codebase codebase: file: - recurse ...SNIP... shutdown_apache: service: - dead - name: apache2 - prereq: - file: codebase

In the preceding example, the shutdown_apache state will only make changes if the codebase state reports that changes need to be made. If they do, then Apache will shutdown, and then the codebase state will execute. Once it is finished, it will trigger the apache2 service state, which will start up Apache again.

Inverting requisites

Each of the aforementioned requisites can be used inversely, by adding _in at the end. For instance, rather than state X requiring state Y, an SLS can be written so that state X declares that it is required by state Y, as follows:

apache2: pkg: - installed - require_in: - service: apache2 service: - running

It may seem silly to add inverses of each of the states but there is in fact a very good use case for doing so: include blocks.

SLS files cannot use requisites that point to a code that does not exist inside them. However, using an include block will cause the contents of other SLS files to appear inside the SLS file. Therefore, generic (but valid) configuration can be defined in one SLS file, included in another, and modified to be more specific with a use_in requisite.

Extending SLS files

In addition to an include block, state SLS files can also contain an extend block that modifies SLS files that appear in the include block. Using an extend block is similar to a use requisite, but there are some important differences.

Whereas a use or use_in requisite will copy defaults to or from another state, the extend block will only modify the state that has been extended.

# cat /srv/generic_apache/init.sls apache2_conf: file: - managed - name: /etc/apache2/apache2.conf - source: salt://apache2/apache2.conf (In django_server/init.sls) include: - generic_apache extend: apache2_conf: file: - source: salt://django/apache2.conf (In image_server/init.sls) include: - generic_apache extend: apache2_conf: file: - source: salt://django/apache2.conf

The preceding example makes use of a generic Apache configuration file, which will be overridden as appropriate for either a Django server or a web server that is only serving images.

The basics of grains, pillars, and templates

Grains and pillars provide a means of allowing user-defined variables to be used in conjunction with a minion. Templates can take advantage of those variables to create files on a minion that are specific to that minion.

Before we get into details, let me start off by clarifying a couple of things: grains are defined by the minion which they are specific to, while pillars are defined on the master. Either can be defined statically or dynamically (this book will focus on static), but grains are generally used to provide data that is unlikely to change, at least without restarting the minion, while pillars tend to be more dynamic.

Using grains for minion-specific data

Grains were originally designed to describe the static components of a minion, so that execution modules could detect how to behave appropriately. For instance, minions which contain the Debian os_family grain are likely to use the apt suite of tools for package management. Minions which contain the RedHat os_family grain are likely to use yum for package management.

A number of grains will automatically be discovered by Salt. Grains such as os, os_family, saltversion, and pythonversion are likely to be always available. Grains such as shell, systemd, and ps are not likely to be available on, for instance, Windows minions.

Grains are loaded when the minion process starts up, and then cached in memory. This improves minion performance, because the Salt-minion process doesn't need to rescan the system for every operation. This is critical to Salt, because it is designed to execute tasks immediately, and not wait several seconds on each execution.

To discover which grains are set on a minion, use the grains.items function:

salt myminion grains.items

To look at only a specific grain, pass its name as an argument to grains.item:

salt myminion grains.item os_family

Custom grains can be defined as well. Previously, static grains were defined in the minion configuration file (/etc/salt/minion on Linux and some Unix platforms):

grains: foo: bar baz: qux

However, while this is still possible, it has fallen out of favor. It is now more common to define static grains in a file called grains (/etc/salt/grains on Linux and some Unix platforms). Using this file has some advantages:

Grains are stored in a central, easy-to-find locationGrains can be modified by the grains execution module

That second point is important: whereas the minion configuration file is designed to accommodate user comments, the grains file is designed to be rewritten by Salt as necessary. Hand-editing the grains file is fine, but don't expect any comments to be preserved. Other than not including the grains top-level declaration, the grains file looks like the grains configuration in the minion file:

foo: bar baz: qux

To add or modify a grain in the grains file, use the grains.setval function:

salt myminion grains.setval mygrain 'This is the content of mygrain'

Grains can contain a number of different types of values. Most grains contain only strings, but lists are also possible:

my_items: - item1 - item2

In order to add an item to this list, use the grains.append function:

salt myminion grains.append my_items item3

In order to remove a grain from the grains file, use the grains.delval function:

salt myminion grains.delval my_items

Centralizing variables with pillars

In most instances, pillars behave in much the same way as grains, with one important difference: they are defined on the master, typically in a centralized location. By default, this is the /srv/pillar/ directory on Linux machines. Because one location contains information for multiple minions, there must be a way to target that information to the minions. Because of this, SLS files are used.

The top.sls file for pillars is identical in configuration and function to the top.sls file for states: first an environment is declared, then a target, then a list of SLS files that will be applied to that target:

base: '*': - bash

Pillar SLS files are much simpler than state SLS files, because they serve only as a static data store. They define key/value pairs, which may also be hierarchical.

skel_dir: /etc/skel/ role: web web_content: images: - jpg - png - gif scripts: - css - js

Like state SLS files, pillar SLS files may also include other pillar SLS files.

include: - users

To view all pillar data, use the pillar.items function:

salt myminion pillar.items

Take note that in older versions of Salt, when running this command, by default the master's configuration data will appear as a pillar item called master. This can cause problems if the master configuration includes sensitive data. To disable this output, add the following line to the master configuration:

pillar_opts: False

Fortunately, this option defaults to False as of Salt version 2015.5.0. This is also a good time to mention that, outside the master configuration data, pillars are only viewable to the minion or minions to which they are targeted. In other words, no minion is allowed to access another minion's pillar data, at least by default. It is possible to allow a minion to perform master commands using the peer system, but that is outside the scope of this chapter.

Managing files dynamically with templates

Salt is able to use templates, which take advantage of grains and pillars, to make the state system more dynamic. A number of other templating engines are also available, including (as of version 2016.3) the following:

jinjamakowempycheetahgenshi

These are made available via Salt's rendering system. The preceding list only contains renderers that are typically used as templates to create configuration files and the like. Other renderers are available as well, but are designed more to describe data structures:

yamlyamlexjsonjson5msgpackpypyobjectspydsl

Finally, the following Renderer can decrypt GPG data stored on the master, before passing it through another renderer:

gpg

By default, state SLS files will be sent through the Jinja renderer, and then the yaml renderer. There are two ways to switch an SLS file to another renderer. First, if only one SLS file needs to be rendered differently, the first line of the file can contain a shabang line that specifies the renderer:

#!py

The shabang can also specify multiple Renderers, separated by pipes, in the order in which they are to be used. This is known as a render pipe. To use Mako and JSON instead of Jinja and YAML, use:

#!mako|json

To change the system default, set the renderer option in the master configuration file. The default is:

renderer: yaml_jinja

It is also possible to specify the templating engine to be used on a file that created the minion using the file.managed state:

apache2_conf: file: - managed - name: /etc/apache2/apache2.conf - source: salt://apache2/apache2.conf - template: jinja

A quick Jinja primer

Because Jinja is by far the most commonly-used templating engine in Salt, we will focus on it here. Jinja is not hard to learn, and a few basics will go a long way.

Variables can be referred to by enclosing them in double-braces. Assuming a grain is set called user, the following will access it:

The user {{ grains['user'] }} is referred to here.

Pillars can be accessed in the same way:

The user {{ pillar['user'] }} is referred to here.

However, if the user pillar or grain is not set, the template will not render properly. A safer method is to use the salt built-in to cross-call an execution module:

The user {{ salt['grains.get']('user', 'larry') }} is referred to here. The user {{ salt['pillar.get']('user', 'larry') }} is referred to here.

In both of these examples, if the user has not been set, then larry will be used as the default.

We can also make our templates more dynamic by having them search through grains and pillars for us. Using the config.get function, Salt will first look inside the minion's configuration. If it does not find the requested variable there, it will check the grains. Then it will search pillar. If it can't find it there, it will look inside the master configuration. If all else fails, it will use the default provided.

The user {{ salt['config.get']('user', 'larry') }} is referred to here.