The coolest features in Salt 2019.2 Fluorine
26 minute read Updated:
It started as a series of tweets about a few exciting features I’ve found in Salt Fluorine git branch. Then the release was postponed from 2018.11 to 2019.2, and that gave me enough time to consolidate these tweets (and lots of other features) into a full-blown blog post. It is not a replacement for the official release notes, but I hope you will enjoy it!
UPDATE (2020.05.20): the 2019.2.5 bugfix release is available and is strongly recommended.
A list of the most exciting features in Salt 2019.2 Fluorine
- Network automation
- Multiple SaltSSH versions
- Terraform roster for SaltSSH
- Ansible playbooks and inventory
- CLI exit codes
- Loadable matchers
- Loadable serializers
- Docker proxy minion
- Other Docker improvements
- Using proxy minion from the CLI
- Grains in grains
- SaltSSH key password
- Configurable module environment
- Wtmp/btmp beacon improvements
- Cross-platform file monitoring
- Redis SDB module
- Google Chat module
- SMTP attachments
- Jira integration
- KMS decryption renderer
- Enhancements in package modules
- New Azure ARM modules
- Cloud map improvements
- Other cloud improvements
- Windows runas improvements
- Windows Advanced Audit policies
- LXD module/state
- Libvirt improvements
- NI Linux RT improvements
- SmartOS improvements
- GlusterFS improvements
- Vault improvements
- Zabbix improvements
- Nifty tricks
- Other notable features
Want to read about the upcoming Argon release?
I’m always hesitant to commit to writing another post like this one (it takes a lot of time!). However, I get bits of motivation to do so when people subscribe to the mailing list:
Powered by Mailgit
Network automation
My network management skills are rusty, but I used to work in this field around 2004-2009. I had to deal with Cisco and Huawei gear, and the CLI experience was awful. However, I still remember my excitement when I got the chance to work with Juniper hardware and Junos in particular. It felt like proper Unix, had version control (with diffs!), atomic commit/rollback support and tons of other well-thought-out features.
Many configuration management tools are evolving in this direction, unifying change management processes across different networking equipment from different vendors. With Salt, it is possible to have version control, code reviews, automatic rollouts, and other nice features, even for network devices that do not support this out of the box. Things have improved a lot, so I ALMOST want to work in this field again 😀
There are lots of network-related features in Salt Fluorine. Below is a brief list, please refer to the docs for a complete description.
- Netbox pillar - PRs #46559 by Kris Steinhoff and #48910 by Mircea Ulinic
- New functions to interact with the Netbox API - PR #48916 by @Ichabond
- Netmiko proxy and execution modules - PR #48260
- NAPALM improvements - PRs #48264, #48290, #48313, #48337, #48707, #48739, #48948, #48879
- Proxy and execution modules for Arista switches - PR #48356
- Proxy and execution modules for Cisco Nexus switches - PR #48541
- PeeringDB.com API integration module - PR #48688
- Ciscoconfparse execution module - PR #48733
commit_in
,commit_at
,revert_in
andrevert_at
- PRs #48779 and #48909- A module for Cisco IOS configuration manipulation - PR #48859
- More flexible handling of Cisco NX OS prompts - PR #48378 by C. R. Oldham
- An execution module to SCP files on devices - PR #48861
- Netconfig state helpers - PR #48927
- Network template rendering changes - PR #48945
- New functions for CIMC module/state (
hostname
,logging_levels
,power_configuration
anduser
) - PR #46222 by @spenceation
Details
- Mostly contributed by: Mircea Ulinic @mirceaulinic @mirceaulinic
- Documentation: Network Automation
- There is a free O’Reilly ebook called Network Automation at Scale by Seth House and Mircea Ulinic . It was written in 2017 and does not cover the features mentioned above, but still can serve as a good introduction into the topic.
- Also see the blog post: Extending NAPALM’s capabilities in the Salt environment
Multiple SaltSSH versions
This is a clever hack to allow SaltSSH work across different major Python versions and use multiple versions of Salt. The only necessary condition is that your states should be compatible with all the versions you want to use.
To use SaltSSH across Python 2.7 - Python 3.x, you need to install Salt packages for both versions of the interpreter on a master machine. Using multiple Salt versions is trickier - to do that you need to install them into isolated folders, including all necessary dependencies:
ssh_ext_alternatives:
2016.3: # Namespace, can be actually anything.
py-version: [2, 6] # Constraint to specific interpreter version
path: /opt/2016.3/salt # Main Salt installation
dependencies: # List of dependencies and their installation paths
jinja2: /opt/jinja2
yaml: /opt/yaml
tornado: /opt/tornado
msgpack: /opt/msgpack
certifi: /opt/certifi
singledispatch: /opt/singledispatch.py
singledispatch_helpers: /opt/singledispatch_helpers.py
markupsafe: /opt/markupsafe
backports_abc: /opt/backports_abc.py
Details
- Contributed by: Bo Maryniuk @isbm
- PR: #46684
- Documentation: SaltSSH major updates
Terraform roster for SaltSSH
It looks like Salt has lost the battle for multi-cloud infrastructure provisioning (especially for non-VM resource types). It is hard to beat the vast amount of different providers in Terraform, its speed, excellent vendor support program and even things like fast GCP feature development using Magic Modules. So, the only sensible strategy left is to provide good interoperability with Terraform, in order to use both tools in tandem.
With the terraform-provider-salt you can keep your infrastructure-as-code self-contained in a single directory and use Terraform + salt-ssh
combo to provision and configure your nodes:
$ terraform apply
$ salt-ssh '*' state.highstate
This is done by creating a mapping between the Terraform resources and salt-ssh roster entries:
resource "libvirt_domain" "domain" {
name = "domain-${count.index}"
memory = 1024
disk {
volume_id = "${element(libvirt_volume.volume.*.id, count.index)}"
}
network_interface {
network_name = "default"
hostname = "minion${count.index}"
wait_for_lease = 1
}
cloudinit = "${libvirt_cloudinit.init.id}"
count = 2
}
resource "salt_host" "example" {
host = "${libvirt_domain.domain.network_interface.0.addresses.0}
}
Also, you can use local_file
Terraform resource to render simple pillar files:
resource "local_file" "pillar_database_cluster" {
filename = "${path.module}/srv/pillar/terraform_database_cluster.sls"
content = <<EOF
terraform:
database_master_ip: ${salt_host.master.host}
EOF
}
NOTE: please do not confuse the terraform-provider-salt with the built-in salt-masterless Terraform provisioner. The latter one connects to a node via ssh, syncs pillar/state trees, runs the salt-bootstrap.sh
script and then uses the salt-call --local
command to apply a state.
Details
- Contributed by: Duncan Mac-Vicar P. @dmacvicar @dmacvicar
- PR: #48873
- Documentation: README.md
Ansible playbooks and inventory
Ansible is definitely more popular, but people still switch to Salt. The reasons can be very different, such as infrastructure growth, unacceptable playbook running time, a need to react to infrastructure events automatically, and even the existential fear of IBM. As with Terraform, the right strategy is to simplify interoperability and increase the ease of switching.
Salt.modules.ansiblegate was first introduced in Salt 2018.3. In Salt Fluorine it gained the ability to run Ansible playbooks (both from states and orchestration jobs).
Also from now on Salt uses ansible-inventory
command internally to retrieve a roster.
Details
- Contributed by: Daniel Wallace @gtmanfred @gtmanfred
- PRs: #48254 and #48538
- Documentation: salt.modules.ansiblegate.playbooks
CLI exit codes
This feature is not very visible from a user perspective but is quite essential. It streamlines many edge cases in CLI exit codes and can simplify your scripts or CI workflows.
In addition to the table above:
- A non-zero exit code will be set when minions fail to return
- For a multi-module salt call, the highest return value will be used to determine if it failed
- Salt-call exit code is no longer ignored by salt-ssh
- As a bonus, it is possible to override a retcode from cmd.run and other cmd functions, by specifying the success_retcodes parameter
% salt-call --local cmd.run cmd='return 42' ; echo $?
[ERROR ] Command 'return 42' failed with return code: 42
[ERROR ] retcode: 42
[ERROR ] Command 'return 42' failed with return code: 42
[ERROR ] output:
local:
1
% salt-call --local cmd.run cmd='return 42' success_retcodes='[42]'; echo $?
local:
0
Details
- Contributed by: @terminalmage , @garethgreenaway , @KaiSforza and @marmarek
- PRs: #48361, #49217, #45851, #47544 and #50733
- Documentation: return codes, salt.states.cmd.run
Loadable matchers
When you read the Salt targeting documentation, it is not immediately obvious that minions are responsible for matching themselves against a target specification. Every minion looks at the targeting data broadcasted by the salt-master via ZeroMQ pub/sub messaging channel and decides if they match it (NOTE: this process is more nuanced if you have zmq_filtering
enabled).
In Salt Fluorine all matchers were moved to the separate module namespace and can be dynamically loaded. It is not possible to create a new matcher, because the required CLI plumbing does not exist yet. For now, you can only override any existing matcher by placing a file into the _matchers
directory in your file_roots
and propagating it with saltutil.sync_matchers
:
# list_matcher.py
from __future__ import absolute_import, print_function, unicode_literals
from salt.ext import six
def match(self, tgt):
'''
Determines if this host is on the list
'''
if isinstance(tgt, six.string_types):
# The stock matcher splits on `,`. Change to `/` below.
tgt = tgt.split('/')
return bool(self.opts['id'] in tgt)
Details
Loadable serializers
Add your own custom serializers (XML, anyone?) via Salt dynamic module distribution mechanism. You can use them to manage domain-specific file formats, such as configuration files.
Example serializer (put this into salt://_serializers/hcl.py
):
"""HCL deserializer."""
try:
import hcl # https://github.com/virtuald/pyhcl
available = True
except ImportError:
available = False
from salt.serializers import DeserializationError
from salt.ext import six
__all__ = ['deserialize', 'available']
def deserialize(stream_or_string, **options):
try:
if not isinstance(stream_or_string, (bytes, six.string_types)):
return hcl.load(stream_or_string)
if isinstance(stream_or_string, bytes):
stream_or_string = stream_or_string.decode('utf-8')
return hcl.loads(stream_or_string)
except Exception as e:
raise DeserializationError(e)
def serialize(obj, **options):
raise NotImplementedError("pyhcl can only serialize to json")
# salt/hcl.sls
{% load_text as hcl_example %}
variable "ami" {
description = "the AMI to use"
}
resource "aws_instance" "web" {
ami = "${var.ami}"
count = 2
source_dest_check = false
connection {
user = "root"
}
}
{% endload %}
{% do salt.log.warning(salt['slsutil.deserialize']('hcl', hcl_example)) %}
To sync serializers from salt://_serializers
run the salt '*' saltutil.sync_serializers
command:
% salt-call --local saltutil.sync_serializers
local:
- serializers.hcl
% salt-call --local state.apply hcl
[WARNING ] {"resource": {"aws_instance": {"web": {"ami": "${var.ami}", "connection": {"user": "root"},
"count": 2, "source_dest_check": false}}}, "variable": {"ami": {"description": "the AMI to use"}}}
Details
- Contributed by: Tyler Couto
- PR: #46435
- Documentation: source code
Docker proxy minion
This adds the new minion type called docker
, which uses docker.call
to run Salt modules in Docker containers without installing Salt in the container. Also, it can run state.sls
, state.apply
and state.highstate
in the Docker container.
Details
- Contributed by: Daniel Wallace @gtmanfred @gtmanfred
- PR: #47716
- Documentation: salt/proxy/docker.py
Other Docker improvements
docker.prune
support for containers, images, networks, volumes and builder cache. PR #46176 by Ronald van Zantvoort- Add filters to the
docker_events
engine. PR #46218 by Ronald van Zantvoort - Manage docker-compose service definitions (
service_create
,service_upsert
,service_remove
andservice_set_tag
). PR #45231 by Sjuul Janssen
Using proxy minion from the CLI
This is a huge time saver for the real men who write their own device drivers people who write and troubleshoot their own proxy minions. It allows you to use proxy minions from the minion box without a master:
% salt-call --local --proxyid PROXY_ID test.ping
This salt-call
console command does basically the same thing as the separate salt-proxy --proxyid PROXY_ID
process, but just for a single call. It also nicely complements the above-mentioned Docker proxy minion feature.
Details
- Contributed by: Daniel Wallace @gtmanfred @gtmanfred
- PR: #48344
- Documentation: Salt Proxy Caller
Grains in grains
When writing custom grains, sometimes it is useful to reuse the data from already existing grain. It is hard to do because the grain evaluation order is nondeterministic, but this restriction has been partially lifted. For custom grains, if the function accepts an argument named grains
, then the previously rendered core grains will be passed in as a dictionary.
import re
def if_count(grains):
"""Return number of interfaces excluding the loopback."""
return {
'if_count': len([i for i in grains['ip_interfaces'] if i != 'lo'])
}
def role(grains):
"""Extract a server role from FQDN like env-role-NN.domain.tld."""
match = re.match(
'^[a-z0-9]+-([a-z0-9]+)-[0-9]+\.[a-z0-9-]+\.[a-z]+$',
grains['fqdn']
)
return {'role': match.group(1)} if match else {}
Details
- Contributed by: Daniel Wallace @gtmanfred @gtmanfred
- PR: #47372
- Documentation: Grains precedence
SaltSSH key password
Previously, using ssh-agent
was the only way to use password-protected SSH keys with salt-ssh
. Now, the private key passphrase can be set in 3 different places:
--priv-passwd
argument forsalt-ssh
commandssh_priv_passwd
master config optionpriv_passwd
in asalt-ssh
roster entry
Details
- Contributed by: Peng Yao
- PR: #47238
- Documentation: SaltSSH major updates
Configurable module environment
On the surface, this feature allows you to specify arbitrary environment variables for aptpkg
, yumpkg
and zypper
execution modules. Under the hood, it is much more interesting, because it allows you to specify custom environment variables for shell commands executed by Salt modules (states, execution modules, returners, etc.). To do that, you need to add something like this to either grains or pillars:
system-environment:
<type>: # Type of the module (states, modules, etc.).
<module>: # Module name
_: # Namespace for all functions in the module
<VAR>: "value"
<function>: # Namespace only for particular function in the module
<VAR>: "value"
The configuration is quite granular: it allows you to define variables for any module type, module name and even for a specific function. The only caveat is that the environment won’t be applied to all existing modules automatically. It requires explicit module-level support. To do that, you need to call salt.utils.environment.get_module_environment(globals(), function=None)
in your module and pass the resulting environment to __salt__['cmd.run']
or __salt__['cmd.run_all']
.
Details
- Contributed by: Bo Maryniuk @isbm
- PR: #48021
- Documentation: Configurable module environment
Wtmp/btmp beacon improvements
action
key has been added to the events fired bywtmp
beacon, which will contain either the stringlogin
orlogout
- Added configurable
ut_type
to distinguish between login and logout events - Better support of posting failed logins to Slack via reactor
- Group support in the btmp and wtmp beacons
Details
- Contributed by: Erik Johnson and Gareth J. Greenaway
- PRs: #48532 and #47711
- Documentation:
salt.beacons.wtmp
Cross platform file monitoring
It is similar to the inotify beacon, with the main difference that it uses the cross-platform watchdog module and works on Linux 2.6+, Mac OS X, BSD Unix variants, Windows Vista and later and also has an OS-independent polling mechanism.
beacons:
watchdog:
- directories:
/path/to/dir:
mask:
- create
- modify
- delete
- move
Details
- Contributed by: David Wagner and Marco Molteni
- PR: #48615
- Documentation: source code
Redis SDB module
Initially, SDB modules in Salt were designed to store secrets, as an alternative to pillar files. Redis does not look like a good option to store sensitive data (as compared to Vault and some of the other SDB modules). However, if you want to store more dynamic data across different masters and minions and then use it in your states, then Redis looks like a good solution. Also, there is the Redis cache backend and also Redis returner, which you can query using the SDB module.
Details
- Contributed by: Mircea Ulinic @mirceaulinic @mirceaulinic
- PR: #48239
- Documentation: salt.sdb.redis_sdb
Google Chat module
{% if pillar.get('sadserver_scheduled_run', False) %}
sadserver_quote:
# NOTE: Put use_superseded: ['module.run'] into the minion config
module.run:
- google_chat.send_message:
# https://developers.google.com/hangouts/chat/how-tos/webhooks
- url: "https://chat.googleapis.com/v1/spaces/XXX/messages?key=YYY&token=ZZZ"
- message: {{ salt['cmd.run']('python3 -c \'import json, random, sys, urllib.request; sys.stdout.buffer.write(("```{}```".format(random.choice(json.loads(urllib.request.urlopen("https://brokenco.de/files/sadserver.json").read().decode("utf-8")))["full_text"].strip())).encode("utf-8"))\'') | yaml_encode }}
# Also try https://brokenco.de/files/sadoperator.json
{% else %}
sadserver_morning_schedule:
schedule.present:
- function: state.sls_id
- job_args:
- sadserver_quote
- {{ sls }}
- job_kwargs:
pillar:
sadserver_scheduled_run: True
- when:
- Monday 9:00am
- Tuesday 9:00am
- Wednesday 9:00am
- Thursday 9:00am
- Friday 9:00am
{% endif %}
Details
- Contributed by: Luke Orden
- PR: #48919
- Documentation: salt.modules.google_chat
SMTP attachments
With the addition of the new parameter named attachments
, you can send local files over email by using smtp
state/module. One obvious example is sending out generated client certificates:
{% set email='user@example.com' %}
{% set filename = email.replace('@', '-').replace('.', '-') %}
email-openvpn-config-for-{{ filename }}:
smtp.send_msg:
- name: |
Your personal OpenVPN configuration file is attached below:
- subject: 'Your OpenVPN profile'
- recipient: {{ email }}
- sender: admin@example.com
- profile: smtp-credentials
- attachments:
- /etc/pki/openvpn/{{ filename }}.ovpn
- onchanges:
- file: /etc/pki/openvpn/{{ filename }}.ovpn
/etc/pki/openvpn/{{ filename }}.ovpn:
file.managed:
- mode: 0600
- template: jinja
- defaults:
ca: __slot__:salt:file.read(/etc/pki/ca.crt)
tls_crypt: __slot__:salt:file.read(/etc/pki/static.key)
cert: __slot__:salt:file.read(/etc/pki/issued/{{ filename }}.crt)
key: __slot__:salt:file.read(/etc/pki/private/{{ filename }}.key)
- source: salt://openvpn/files/config.ovpn.j2
# salt/openvpn/files/config.ovpn.j2
client
dev tun
remote openvpn.example.com 1194 udp
connect-retry-max 3
resolv-retry 5
tls-timeout 10
nobind
persist-key
persist-tun
explicit-exit-notify
verb 3
remote-cert-tls server
<ca>
{{ ca }}
</ca>
<cert>
{{ cert }}
</cert>
<key>
{{ key }}
</key>
<tls-crypt>
{{ tls_crypt }}
</tls-crypt>
Details
- Contributed by: jeduardo
- PR: #47442
- Documentation: salt.states.smtp
Jira integration
Writing a terraform provider to create the JIRA tickets needed to provision a new machine in the datacenter.Am I devopsing right?
— DevSadOps (@sadoperator) July 1, 2016
This is an execution module to manipulate Jira tickets using the Jira python client library. It could be used to automatically raise Jira tickets when something happens and supports the following operations:
create_issue
assign_issue
add_comment
- check the
issue_closed
status
There is no corresponding state module, so if you want to use it in a state, you need to use the module.run
function.
Details
- Contributed by: Mircea Ulinic @mirceaulinic @mirceaulinic
- PR: #48687
- Documentation: salt.modules.jira_mod
KMS decryption renderer
The new renderer that utilizes AWS Key Management Service to decrypt pillar values using Fernet symmetric encryption. To use it you need to specify KMS credentials and then include your ciphertexts in a pillar file:
#!yaml|aws_kms
a-secret: gAAAAABaj5uzShPI3PEz6nL5Vhk2eEHxGXSZj8g71B84CZsVjAAt
Please note, that the aws_kms
renderer will attempt to decrypt each pillar value recursively (only string types). You probably want to use it sparingly and for small pillar files.
Details
- Contributed by: Michael A. Smith
- PR: #46155
- Documentation: salt.renderers.aws_kms
Enhancements in package modules
Various enhancements for the FreeBSD pkgng execution module
- New package locking functions:
pkg.lock
,pkg.unlock
,pkg.locked
,pkg.list_locked
- Add
pkg.list_upgrades
for compatibility withpkg.uptodate
state - Support
pkgs
keyword inpkg.upgrade
for compatibility withpkg.uptodate
state - Add
pkg.hold
andpkg.unhold
for compatibility withpkg.installed
state - Add
clean_all
anddryrun
options
Details
- PRs: #45217 by @amendlik , #45166 by Ben Woods
- Documentation: salt.modules.pkgng
Other enhancements
- Properly implement
openbsdpkg.purge
andopenbsdpkg.upgrade
. PRs #45106 and #45145 by Jasper Lievisse Adriaanse - Proxy support for
aptpkg.mod_repo
. PR #45224 by Alexandru Avadanii - Add
--setopt
support andpkg.installed
state toyumpkg
. PR #46263 by Erik Johnson - Support for multiple version conditions in
pkg.installed
, to allow version ranges and exclusions. PR #48511 by Guillermo Hernandez - Virtual package module for AIX. PR #48924 by David Murphy
--autoremove
and--force-removal-of-dependent-packages
option support foropkg.remove
. PR #48549 by Cristian Hotea
New Azure ARM modules
Huge improvements in Azure ARM execution and state modules:
Azure GovCloud support
- Cloud module can now hit endpoints for any Microsoft hosted endpoint or custom Azure Stack endpoint
General improvements
- Custom scripts can now be passed via VM extensions
- Fixed functions to work from the command line in order to list various resources accessible to the cloud provider configuration
- Start/stop actions
Compute module/state
- Manage availability sets
- Capture a VM to create a template
- Convert virtual machine disks from blob-based to managed disks
- Manage virtual machines (deallocate, generalize, power off, start, restart, redeploy)
Network module/state
- Check domain name availability
- Manage public IP addresses
- Manage security rules
- Manage network security groups
- Manage virtual networks and subnets
- Manage load balancers
- List subscription network usage
- Manage network interfaces
- Manage route filter rules, routes, and route tables
Resource module/state
- Manage resource groups
- Manage deployments and deployment operations
- List subscriptions and locations
- List tenants
- manage policy assignments and definitions
Details
- Contributed by: Nicholas Hughes @nicholasmhughes and @sumeetisp
- PRs: #45186, #45187 and #45119
- Documentation (partial, see the PRs above for details): Azure ARM intro, salt.cloud.clouds.azurearm
Cloud map improvements
The first feature allows you to override providers in map nodes (previously it was only possible to specify a provider in the cloud profile):
webapp:
- node1:
provider: ny:openstack
- node2:
provider: nj:openstack
- node3:
provider: toronto:openstack
The second feature enables use of cloud map data sourced from the pillar (salt-call cloud.map_run map_pillar=my-prd-map
):
cloud:
maps:
my-prd-map:
named-profile-01:
- named-instance-01
- named-instance-02
Details
- Contributed by: Matt Phillips and Nick Garber
- PRs: #47648 and #47742
- Documentation: #47648, Pillar configuration
Other cloud improvements
- Customizable SSH gateway command for salt-cloud. PRs #48062 and #48199 by Ky-Anh Huynh
- Emit stopping/starting events when
salt-cloud -a stop/start
is used. PR #44400 by Vitaliy - Allow
salt-cloud
to operate within a separate directory tree withoutlog_file
directive. PR #48182 by Deleted user - Ability to send Salt minion keys to the userdata script. PR #46491 by Nicholas Hughes
- Ability to specify a startup script id in a profile. PR #46091 by C. R. Oldham
- Block storage and ssh key support to
salt.cloud.clouds.oneandone
. PR #47254 by Amel Ajdinovic - SSH key support for Scaleway. PR #45089 by @jbadson
- EC2 spot instance and block device tagging. PRs #48305 and #48716 by Paul Bruno
- ProfitBricks Cloud API v4 support. PR #44987 by Ethan Devenport
- Volume password support for ProfitBricks. PR #46694 by Ethan Devenport
- CLI function to reserve ProfitBricks IP blocks. PR #46724 by Ethan Devenport
- RBAC subuser support to Joyent driver. PR #45180 by Andrew Hill
Windows runas improvements
- Runas can launch processes on behalf of users without a password
- Support for LOCAL SERVICE and NETWORK SERVICE system accounts
- Runas can now use system accounts from salt-call (SYSTEM, LOCAL SERVICE, and NETWORK SERVICE)
- Fix runas when running under winrm
Details
- Contributed by: Daniel Wozniak @dwoz
- PR: #47621
- Documentation: Windows runas changes
Windows Advanced Audit policies
This module allows you to view and modify the audit settings as they are applied on the machine (either set directly or via local or domain group policy). The audit settings are broken down into nine categories (and the default one named All
):
- Account Logon
- Account Management
- Detailed Tracking
- DS Access
- Logon/Logoff
- Object Access
- Policy Change
- Privilege Use
- System
You can use the auditpol.get_settings
, auditpol.get_setting
and auditpol.set_setting
functions in the following way:
# Get current state of all audit settings
salt * auditpol.get_settings
# Get the current state of all audit settings in the "Account Logon"
# category
salt * auditpol.get_settings category="Account Logon"
# Get current state of the "Credential Validation" setting
salt * auditpol.get_setting name="Credential Validation"
# Set the state of the "Credential Validation" setting to Success and
# Failure
salt * auditpol.set_setting name="Credential Validation" value="Success and Failure"
# Set the state of the "Credential Validation" setting to No Auditing
salt * auditpol.set_setting name="Credential Validation" value="No Auditing"
Details
- Contributed by: Shane Lee
- PR: #51223
- Documentation: salt.modules.win_auditpol
LXD module/state
This feature was extracted from the lxd-formula and requires the pylxd module to work.
lxd
state to initialize the LXD daemon, manage config settings, authenticate to a remote peerlxd_container
state to manage containers (present
,absent
,running
,stopped
,frozen
,migrated
)lxd_image
state to manage images (present
,absent
)lxd_profile
state to manage profiles (present
,absent
)
Details
- Contributed by: Rene Jochum and Daniel Wallace
- PRs: #46231 and #49032
- Documentation: source code
Libvirt improvements
- An engine that listens for libvirt events and resends them to the Salt event bus. Has optional filters to only relay the necessary events. PRs #46461 and #50897 by Cedric Bosdonnat
- Functions/states to manage libvirt networks and storage pools. PRs #46683 by David Homolka and #47907 by Cedric Bosdonnat
- New
virt.capabilities
andvirt.domain_capabilities
functions to compute XML definitions for virtual guests. PR #47892 by Cedric Bosdonnat - Make
virt.init
more flexible and allow to define/override default disks and network interfaces. PRs #48261 and #48262 by Cedric Bosdonnat - Improved
virt
states by using the newvirt.init
parameters and handle more pool types. PR #48421 by Cedric Bosdonnat - Allow
virt.running
to update existing VMs, add the correspondingvirt.update
module function. PR #48736 by Cedric Bosdonnat - Allow to define VM type and CPU architecture. PR #49540 by Cedric Bosdonnat
- Add
uuid
,on_reboot
,on_restart
andon_crash
settings to thevirt.vm_info
andvirt.full_info
outputs. PR #48214 by @pm17788 - Proper handling of cdrom/floppy devices. PR #50379 by Cedric Bosdonnat
NI Linux RT improvements
- Support for the restartcheck module. PR #45554 by Alejandro del Castillo
- New “reboot required” logic for opkg operations. PR #46774 by @10ne1
- Reboot detection for restartcheck/opkg when system plugins are installed by the package manager. PR #47722 by @10ne1
- EtherCAT support for
modules.nilrt_ip
. PR #48617 by Vasiu Alexandru - Make
modules.nilrt_ip
compatible with older NILRT distros. PR #48400 by Vasiu Alexandru - ARM kernel version detection. PR #47610 by @10ne1
SmartOS improvements
- Docker image support in
smartos.imgadm
module/state - Docker support for
smartos.vm_present
- Beacons for
imgadm
andvmadm
Details
- Contributed by: Jorge Schrauwen
- PRs: #48046, #48282 and #48397
GlusterFS improvements
- Methods to get and set the GlusterFS op-version. PR #45091 by Robert Penberthy
- Fix GlusterFS module for version 4.0 and above. PR #48222 by Martin Polreich
- Ability to create “replica 3 arbiter 1” volumes. PR #48774 by @jdito
Vault improvements
Runner function to unseal Vault server
salt-run vault.unseal
uses the keys
from the fault
configuration to unseal Vault server.
PR #46996 by Daniel Wallace
wrapped_token
authentication method
A new wrapped_token
authentication method that allows automatic unwrapping of vault wrapped tokens in the local vault configuration.
PR #47072 by Beorn Facchini
vault.write_raw
function
This function allows you to write raw data to a vault:
salt '*' vault.write_raw "secret/my/secret" '{"user":"foo","password": "bar"}'
Named roles
An option to define named role for creation of vault tokens. User can define specific token named role
for minion created tokens and explicitly define its behavior and access policies. Example: https://www.nomadproject.io/docs/vault-integration/index.html#vault-token-role-configuration.
Zabbix improvements
- Zabbix inventory support. PR #45458 by Christian McHugh
- State modules for Zabbix templates, actions and valuemaps. PR #47398 by @slivik
- New state
zabbix_user.admin_password_present
. PR #47970 by @slivik
Nifty tricks
JID in the logs
This feature is super useful for debugging purposes because it allows you to grep the logs for a specific job ID. It is off by default, but I think you should enable it right away! Add the following lines to your master/minion config file (the relevant part is %(jid)s
):
log_fmt_logfile: '%(asctime)s,%(msecs)03d [%(name)-17s][%(levelname)-8s] %(jid)s %(message)s'
log_level: info
Then you can use the JID to filter the log:
% sudo salt --show-jid minion1 state.apply teststate
jid: 20181128221721109828
minion1:
----------
ID: test_notification
Function: test.show_notification
Result: True
Comment: Hello there!
Started: 22:17:21.283097
Duration: 2.02 ms
Changes:
Summary for minion1
------------
Succeeded: 1
Failed: 0
------------
Total states run: 1
Total run time: 2.020 ms
% sudo salt minion1 cmd.run 'grep "\[JID: 20181128221721109828\]" /var/log/salt/minion'
minion1:
2018-11-28 22:17:21,133 [salt.minion ][INFO ] [JID: 20181128221721109828] Starting a new job 20181128221721109828 with PID 1955
2018-11-28 22:17:21,237 [salt.state ][INFO ] [JID: 20181128221721109828] Loading fresh modules for state activity
2018-11-28 22:17:21,283 [salt.state ][INFO ] [JID: 20181128221721109828] Running state [test_notification] at time 22:17:21.283098
2018-11-28 22:17:21,283 [salt.state ][INFO ] [JID: 20181128221721109828] Executing state test.show_notification for [test_notification]
2018-11-28 22:17:21,284 [salt.state ][INFO ] [JID: 20181128221721109828] Hello there!
2018-11-28 22:17:21,285 [salt.state ][INFO ] [JID: 20181128221721109828] Completed state [test_notification] at time 22:17:21.285117 (duration_in_ms=2.02)
2018-11-28 22:17:21,287 [salt.minion ][INFO ] [JID: 20181128221721109828] Returning information for job: 20181128221721109828
Docs: Logging changes. PR #48660 by Gareth J. Greenaway
Per-state failhard
If you want to abort the state execution process when any single state fails, you can use global or per-state failhard
option. Starting with Salt Fluorine, you can override the global failhard: True
option by adding failhard: False
to any state. This is also helpful if you want to use onfail
, onfail_in
or onfail_any
state requisites because otherwise they are ignored.
Wildcard pillar includes
Previously it was only possible to use wildcards to include states, and now you can do the same for pillar (both in top.sls and individual pillar files via include
):
base:
'*':
- users.*
Nodegroup support for compound matcher
Use salt -C 'N@nodegroup'
on the command line and compound nodegroup matchers in your top.sls
(apparently, this requires putting nodegroups into both master and minion configuration files). PR #47421 by Matt Phillips
List the states that will be applied on highstate
% salt '*' state.show_states
minion1:
- base
- timezone
- ntp
Unlike the state.show_top
, this function also shows included states.
PR #44475 by Petr Michalec
slsutil.merge_all function
The same as slsutil.merge
, but can merge more than two dictionaries at once:
# pillar file
{% set layer1 = {'a': 'a', 'b': 'b', 'c': 'c'} %}
{% set layer2 = {'a': 'z'} %}
{% set layer3 = {'c': 'x'} %}
value: {{ salt['slsutil.merge_all']([layer1, layer2, layer3]) }}
% salt-call --local pillar.get value
local:
----------
a:
z
b:
b
c:
x
PR #47679 by Tyler Couto
New functions in the defaults
module
- New
defaults.deepcopy
function - New
defaults.update
function defaults.merge
got themerge_lists
andin_place
arguments
PRs #44850, #44851 and #45051 by Ahmed M. AbouZaid
state.sls_exists function
The main use-case for this function is to conditionally include a state only if the corresponding file exists (for example, to apply per-role or per-host states automatically). Unlike the file.exists
, it should work with gitfs
too.
base:
'*':
- base
{% set minion_state = 'minion.' ~ (grains.id | replace('.', '_')) -%}
{% if salt['state.sls_exists'](minion_state) -%}
- {{ minion_state }}
{%- endif %}
PR #45730 by Christian McHugh
file.tidied state
This is a port of Puppet tidy resource. It allows you to recursively remove unwanted files based on specific criteria. For example:
prepared-for-distribution:
file.tidied:
- name: /tmp/source
- matches:
- .*\.pyc
- .*\.orig
- .*\.rej
- .DS_Store
PR #47718 by Dirk Heinrichs
Use unless
and onlyif
together
Allow the unless
and onlyif
requisites to both work when specified in a state file. Previously, if you tried to specify them simultaneously, onlyif
would take precedence and the unless
statement was ignored.
PR #45229 by Gareth J. Greenaway
Relative Jinja imports
Allow you to include Jinja templates using relative paths: {% from './foo' import bar %}
. Quite useful for writing formulas or if you have a Jinja macro that is used across different states.
PR #47490 by @plastikos
config.items helper
This helper returns a complete config from the currently running minion process, including the default values.
# salt minion1 config.items
minion1:
----------
__cli:
salt-minion
__role:
minion
acceptance_wait_time:
10
acceptance_wait_time_max:
0
always_verify_signature:
False
append_minionid_config_dirs:
auth_safemode:
False
auth_timeout:
5
auth_tries:
7
auto_accept:
True
autoload_dynamic_modules:
True
autosign_timeout:
120
...
You can use it to find the difference between two minions (with the help of yamldiff
):
# yamldiff --file1 <(salt minion1 config.items --out yaml) \
--file2 <(salt minion2 config.items --out yaml)
- minion1: {
+ minion2: {
- uuid: "c6c51464-65cc-b044-94dd-927488c90cfc",
+ uuid: "538dce5d-228c-3d42-83ca-98ab6b999f83",
- id: "minion1",
+ id: "minion2",
- ipv6: true,
+ ipv6: false,
Other notable features
- Experimental support for salt-api on Windows. Unfortunately, it won’t be installed by default until the next release of Salt. PRs #48001 and #49949 by @rares-pop .
- The ability to set permissions in the Windows registry. PR #48832 by Shane Lee
- Various
mac_service
improvements. PRs #46206, #47256 and #49121 by Wesley Whetstone and Megan Wilhite . - MacOS launchctl subcommand support to start and stop services. PR #47256 by Wesley Whetstone
test=None
by default - very useful for people who enabletest=True
in the minion config by default, and want to explicitly specifytest=False
on the command line for orchestration jobs. PR #47427 by John Hicks .show_changed
option for theevent.send
state - if you send any events from states, you already know that they always report changes and pollute the output. Now you can passshow_changed: False
to silence the output fromevent.send
. PR #47391 by Todd Wells- An option to configure HTTP connection timeout for tornado backend. PR #46102 by @mephi42
no_proxy
option to define a list of hosts to bypass HTTP proxy. PR #48108 by @mrproper- Only show the failed states in Slack. PR #46840 by Matthew Erickson
- Support for ext3/ext4 partition types in the parted module. PR #45048 by Piotr
- LDAP authentication with starttls. PR #48697 by @dgengtek
- Multiple GPG ciphertexts in a single pillar value. PR #45781 by Ignat Korchagin
- DNS utils improvements. PR #46184 by Ronald van Zantvoort
- New
group
option forcmdmod
functions. PR #43901 by @boltronics runas
option to run Django management commands. PR #45537 by Tobias Macey- The ability to set a global splay for all jobs in the scheduler. PR #46525 by Gareth J. Greenaway
- Ability to run scheduled jobs in the foreground. PR #46544 by Pedro Algarvio
- Allow Thorium to use gitfs with a mount point or saltenv. PR #47187 by @azelezni
- Allow excluding multiple directories in rsync. PR #46515 by Daniel Wallace
zmq_filtering
support forsalt-syndic
. PR #48905 by Peng Yao- Mask sensitive data in salt-ssh debug logs. PR #48291 by Bo Maryniuk
- State and module functions to manage SELinux port policies. PR #47230 by Lee Clemens
- The ability to explicitly specify the trust model used by
gpg.verify
. PR #50474 by Janik - An option to hard-reset only when there are remote changes in
git.latest
. PR #46854 by Erik Johnson - An execution module for OpenBSD Packet Filter. PR #45905 by Jasper Lievisse Adriaanse
- New Xen grains and function to get/set PV_ARGS. PRs #46459 and #47091 by Andreas Thienemann
- New
vmctl
module to interface with the OpenBSD VMM hypervisor. PR #45164 by Jasper Lievisse Adriaanse exclude_patterns
option for Sentry log handler. PR #45689 by @rrroo- A module for Pure Storage FlashBlade array. PR #45993 by Simon Dodsley
- Kapacitor module/state enhancements. PRs #46294 and #46825 by Ahmed AbouZaid
- Kubernetes configuration via
kubeconfig
. PR #46244 by Michael Calmer - MongoDB connection string support in
mongo_future_return
. PR #48371 by Joanna Yurdal - Additional parameters for the
acme
module. PR #45414 by Herbert - A function to return TLS certificate expiration date. PR #46922 by Erik Johnson
Want to read about the upcoming Argon release?
I’m always hesitant to commit to writing another post like this one (it takes a lot of time!). However, I get bits of motivation to do so when people subscribe to the mailing list:
Powered by Mailgit
Also, you can follow me on Twitter where I periodically post things like this: