What's new in Salt 3007 Chlorine STS
20 minute read Updated:
This post is a bit unusual because it contains not only the new features that went into the Salt 3007 short term support release (master cluster, mTLS, WebSocket transport, salt-ssh changes, etc), but also the VMware acquisition news and its consequences. Plus, I allowed myself to delve into the problem-solution fitness theories and JTBD in particular. For a shorter summary, check out the official announcement.
What's new in Salt 3007 Chlorine: VMware acquisition, migration to Salt Extensions, Master cluster, TCP mTLS and WebSocket transports, Vault, Salt SSH
- VMware acquisition by Broadcom
- New maintenance policies
- Expedited migration to Salt Extensions
- Master cluster
- TCP mTLS and WebSocket transports
- Vault
- Salt SSH
- Removals
- GPG
- Saltcheck
- Cloud
- Package managers
- Windows
- Small feature highlights
- Other notable features
The most prolific community contributor to this release is jeanluc . He resolved many long-standing issues, implemented some features that were expected to work but didn’t, and even improved the tools for extension maintainers!
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
VMware acquisition by Broadcom
Well, it definitely made a splash… Here are a couple of headlines (including Reddit and Slack):
- Broadcom Hands VMware Partners ‘Termination Notice’
- Scared, Angry And Terminated, VMware Partners Unload On Broadcom
- Broadcom ditches VMware Cloud Service Providers
- VMware OEM partners and resellers, received a notice from Broadcom
- Most VMware SaaS Products Discontinued
- Any other Salt users part of VMware VCPP and just got royally boned by Broadcom?
- VMware End of Availability of perpetual licensing and associated products
- VCPP partners getting terminated, what plan B are you considering?
- VMware alternatives for global enterprise?
- My quote was 625% higher than last year
- 300% increase in renewal
- Broadcom cuts at least 2,800 VMware jobs
- Salt community Slack is temporarily down
It is difficult to comment on this, other than with an old Russian saying:
Новая метла по-новому метёт (А new broom sweeps clean)
Unfortunately, the acquisition also had an effect on the Salt Project. The following folks from the core team were laid off:
- Gareth Greenaway
- Megan Wilhite
- Anil Sharma
- Caleb Beard
- Chad McMarrow
This is a huge loss. Gareth, Megan, and Wayne Werner (who left VMware at the beginning of 2023 for reasons unknown to me) were some of the most responsive core developers on Salt Community Slack and have deep knowledge of Salt internals:
- Gareth is deeply familiar with the internals of Salt scheduler, beacons, engines, Deltaproxy code, state requisites, etc
- Megan was the primary maintainer of Salt SSH and Heist, and was also responsible for pushing out new Salt releases
- Wayne was famous for running the Test Clinic
I hope they all found good new opportunities and impactful projects to work on.
These events led to several important policy changes (you can watch the Salt Project Community Open Hour 12-21-23 where Tom Hatch makes the announcements). More on that below.
New maintenance policies
I’m not going to cite the changes; just go and read them on your own time (the policies are quite radical, TBH):
Expedited migration to Salt Extensions
Salt Extensions have a long history:
- They were introduced in February 2016 and released in Salt 2016.9 (I can’t even find the corresponding release notes)
- A major improvement was added in November 2020 and released in Salt 3003
- In July 2022, Tom Hatch submitted a SEP to migrate lots of built-in modules to extensions
- In October 2023, Gareth Greenaway created a project board to track the migration process
- After the Broadcom event, the push really came to shove, and it looks like there won’t be any deprecation period
- In January 2024, the list of modules to be extracted was opened for comments
- The extensions are migrated into the salt-extensions community org
- The great module purge PR was created
Migration-related changes:
- Add
__deprecated__
dunder to mark modules that are moved to Salt Extensions. PR #64569 by Gareth J. Greenaway - Show documentation warnings on modules that are getting deprecated into extensions. PR #65572 by Pedro Algarvio
- Deprecate the proxmox cloud. PR #64453 by Bernhard Gally
- Deprecate the apache modules. PR #64910 by Gareth J. Greenaway
- Deprecate the zabbix modules. PR #64892 by Gareth J. Greenaway
- Deprecate the docker modules. PR #64890 by Gareth J. Greenaway
- Deprecate the vault modules. PR #64889 by Gareth J. Greenaway
- Deprecate the Kubernetes modules. PR #65566 by Nicholas Hughes
- Deprecate the
pushover
modules in favor of saltext. PRs #65569 and #65725 by jeanluc - Remove Azure modules. PR #64323 by @natalieswork
Outstanding problems:
- The SEP is open for more than a year. UPD: the whole SEP process is deprecated
- The extension index has not been updated since November 2021! I strongly believe Salt needs something like Django Packages. Right now, the only way to discover new extensions is by searching for
saltext
on PyPI - The extension template dependencies need to be regularly kept up to date (although some improvements have been made, plus there is a new unofficial tool for extension maintainers)
- There is a major blocker that prevents installing more than one Salt Extension
- No easy way to bootstrap a minion with extensions
- The same for Heist minions
I believe that from a Salt user point of view, this transition from a single tool to multiple building blocks can be a disaster, unless Broadcom executes it well enough. Do not get me wrong - I totally understand how hard and costly it is to maintain a cross-platform codebase like Salt. But the “user point of view” part is critical there. Users can be very fickle, even if they do not state that explicitly:
Customers are always beautifully, wonderfully dissatisfied, even when they report being happy and business is great. Even when they don’t yet know it, customers want something better, and your desire to delight customers will drive you to invent on their behalf. © Jeff Bezos
They will:
- Switch to Ansible because it is more popular, easier to learn or get certified for, easier to hire skilled people, less risky to choose (“everyone uses it!”), etc.
- Use (managed) Kubernetes to avoid doing OS-level configuration management
- Use serverless offerings
All of that erodes the Salt user base, reduces the number of community contributors, and, in some ways, may even affect the revenue from commercial products that utilize Salt under the hood.
So, to execute the transition well enough, Salt maintainers and the extension developer community need to care about user needs first, while being strategically smart about the efforts required to maintain the distributed codebase.
A long diversion into JTBD
I’m a huge fan of JTBD (Jobs to be Done) and ODI (Outcome Driven Innovation) theories, and I believe that they can be used to develop mitigations for many usability problems with Salt. Below are the main concepts:
- The primary objective is to understand the “underlying process” (JTBD) the user is trying to execute when they are using a product or service
- Every process has some steps that can be described in an almost generic way (Define, Locate, Prepare, Confirm, Execute, Monitor, Modify, Conclude). This is a job map for the core functional job - the stable, long-term focal point around which all other needs (related, emotional and consumption chain jobs, and financial outcomes) are defined
- The consumption chain job is a journey a user goes through to receive, set-up, use, upgrade, clean and maintain a product. By exaggerating a bit, one can say that the whole SaaS model became so widespread because it eliminated many tedious parts of the software consumption chain job (download, install, upgrade, etc.)
- Each step in a job map has many (usually tens) user needs or outcome statements, and the whole job map can have around 100-150 needs. It is possible to uncover an exhaustive list of needs.
- Different user segments tend to care about different clusters of outcomes. By segmenting by outcomes, you can develop well-targeted solutions more efficiently (without bloat)
- The job steps and user needs need to be written in a solution-free form to be stable over time (this allows different solutions to be invented as technologies evolve)
- Besides the primary job executor (user), there are other roles that can exist - the purchase decision maker, the product life cycle support team, the product vendor, etc. They have their own jobs and needs
Because Salt is an extensible framework, it does many core functional jobs:
- Execute commands remotely
- Manage software components on a host
- Manage laptops that are not always online (a quite common goal that is not well-supported by the existing Salt documentation and features)
- Provision cloud environments
- Orchestrate jobs across many hosts
- React to events
…etc. It will take many months and a user research team to map them all.
Instead, I did a relatively limited exercise and partially mapped the Salt consumption chain job (i.e. the important outcomes for setting up, upgrading and maintaining a Salt minion). The goal is to uncover the most critical user needs, which can be used by the Salt developer community to brainstorm and implement some solutions that make the Salt user experience better while keeping the maintainer’s efforts within reasonable bounds.
Roles
- Salt User
- Salt Extension Developer
- Salt Core Developer
These are the most basic ones, but obviously more roles exist - 3rd Party Salt Package Maintainer (for Debian, FreeBSD, etc), Commercial Software Vendor who relies on Salt (VMware/Broadcom, SUSE, etc), and probably others.
User needs
To come up with a list of user needs, I used the following (free) template by Michael Boysen (who worked with the ODI creator Tony Ulwick at Strategyn): JTBD Framework: 20 Contexts Related to Installing or Setting up a New Product.
The user needs are not exhaustive (I only spent 2-3 hours to construct them), aren’t grouped by job steps, and use a less formal structure. Still, these are a great starting points, and as an engineer, you can likely imagine different solutions that can satisfy them. One possible solution mapping process is the Opportunity Solution Tree by Teresa Torres.
- There should be an easy way to find an extension that can manage any particular “thing”, as well as the extension docs
- It should be clear how well an extension is maintained (stability, test coverage, maintainer responsiveness, code reviews, etc)
- If there are multiple extensions that can manage a “thing”, it should be easy to determine which is best (features, popularity, number of downloads, etc)
- It should be clear whether an extension supports a specific “thing to manage” version, OS/arch version, Salt version, and also works with the latest Salt development version
- The same for extension dependencies (a user does not want to spend time guessing the right dependency version combinations)
- An extension license should be clearly stated and compatible with the Salt one
- An extension should not destabilize/break the whole Salt process (prevent Salt from starting, produce memory leaks)
- It should be easy to install/upgrade/uninstall Salt minion with any extensions needed, including their dependencies
- The installation/upgrade process should be repeatable (extensions, including their transitive dependencies, must be pinned), otherwise there will be problems
- The installation/upgrade process should be unattended
- The time required to upgrade and the frequency of upgrades should be minimized
- The installation should not only be repeatable, but also cryptographically signed (dependency hashes)
- The installation process should support various network environments (proxy settings, offline mode)
- The migration path from a monolithic salt minion installation to the one with extensions should be straightforward and error-free (for any supported OS)
- Extension-specific configuration settings should follow some common convention or have established namespaces
- It should be easy to define extension settings before they are installed, so they start with the right settings
- Users would like to never deal with a scenario where two extensions do not work together (a transitive dependency conflict, config/module namespace/virtualname clash, etc)
- It should be easy to see what extensions and dependencies (including their versions) are installed, including a programmatic way to do that
- It should be easy to determine if there are security updates available for Salt or any extensions/dependencies
- Extensions should conform to upstream documentation guidelines, logging conventions, testing frameworks, deprecation helpers, OS/Salt support lifecycle
- Extensions should quickly adapt to changes, deprecations and improvements in the “things” managed by them or used by them (underlying platforms)
- Extensions should conform to the major/minor versioning scheme, to allow safe upgrades
- Users need to be able to test their states in an automated way (unit/integration tests) against new Salt versions and new extension versions
- It should be easy to understand where to file a specific issue a user has (whether it is a Salt failure or an extension failure)
- The extension error messages and logs should be clear
This list is not exhaustive - I didn’t mention Salt learning needs (there are lots of issues that contribute to Salt’s steep learning curve), state development needs (text editor support has not been improved for years, state linter needs some work, state troubleshooting is hard), etc. By the way, Salt issue tracker is an excellent source to uncover many hidden user needs (this is why it is not a good idea to aggressively close feature requests and stale bug reports).
I spent much less time synthesizing an Extension maintainer and a Salt core developer needs, but below are some of them to start with:
Extension maintainer needs
- The extension should be easy to maintain and update according to the best upstream Salt practices, helpers and automations
- Not everyone uses Github, some pre-made pipelines should exist for Gitlab as well
- When releasing an extension, a maintainer wants to notify its potential users
- It should be easy to keep up with Salt updates and make sure the extension stays compatible and stable
- An upstream framework/convention to define configuration settings for new extensions
- An extension should be easy to keep secure and update if necessary
- The documentation should be easy to maintain and publish
- CI runner expenses should be minimized, but the test coverage should be well maintained
- A community of extension maintainers (to agree on common stuff, ask for help, etc)
- Be able to influence upstream Salt development and have access to Salt core developers
Salt core developer needs
- Minimize the number of non-relevant issues to deal with
- Easily keep track of relevant issues for the official extensions and Salt itself (having a monorepo might be easier)
- Reduce the test feedback cycle length
- Easily coordinate Salt/Extensions release cycles if there are cross-cutting features that need to be released
- Fast and safe release procedures
- Try not to break existing extensions with new Salt releases
- Keep the common code (CI pipelines, dependencies) up to-date across repos
- Keep the projects free of security issues
References
- “What Customers Want” and “JTBD: Theory to Practice” by Anthony Ulwick
- “Jobs to be Done Playbook” by Jim Kalbach
- “Competing Against Luck” by Clayton Christensen
- “The Jobs to be Done Handbook” by Chris Spiek and Bob Moesta
- “Intercom on Jobs to be Done”
- “JTBD Overview” by GitLab
- “20 Contexts Related to Installing or Setting up a New Product” by Mike Boysen
- “Opportunity solution trees” by Teresa Torres
If you want to discuss any of the above, ping me (@marnold) on Salt Community Slack.
Some notes on working with polyrepos
Tools to do polyrepo changes:
- https://github.com/gruntwork-io/git-xargs
- https://github.com/lindell/multi-gitter
- https://fabioz.github.io/mu-repo/
How big orgs approach polyrepos:
Master cluster
Over the years, there were a couple of requests to allow running multiple Salt Masters behind a load balancer (see #43368, #54297). Now it is possible!
The architecture is described in the master cluster SEP:
There are new master settings to configure the cluster:
cluster_id
cluster_peers
cluster_pki_dir
A shared filesystem like Gluster is required. All of the masters in a cluster are assumed to be running on a reliable local area network (there is no partition tolerance). For more information, visit the Master Cluster page.
The feature was implemented by Daniel Wozniak in PRs #64705, #64936, #65840, #65138, #65228, and #65754
TCP mTLS and WebSocket transports
- Fix tcp transport TLS options
- Add the ability to define multiple
verify_locations
and setverify_flags
via thessl
config setting - Support both server and client certificates (mTLS)
- Add a WebSocket transport leveraging
aiohttp
, to configure it settransport: ws
in both master and minion settings - The WebSocket transport supports full encryption and verification using both server and client certificates
Quoting the feature author:
One benefit of WebSocket over TCP is the ability of smarter routing of requests with load balancers that support TLS termination and routing based on headers. For instance, you could have both request server and publish server behind a load balancer that is listening on 443.
PR #64937 by Daniel Wozniak
Vault
- Fundamentally rewrite the Vault integration core and provide higher-level abstractions to interact with Vault
- Issue AppRoles to minions and manage their metadata, allowing much simpler ACL policies
- Make use of response wrapping to distribute secrets
- Allow to configure the token lifecycle, including renewals and revocations
- Use Salt cache classes instead of raw file operations
- Change the configuration format; the old format is translated automatically
- Fix some bugs with the current implementation
- Add some low-effort miscellaneous new behaviors like being able to configure audit log metadata
- Properly split policy management into execution and state module parts
- Correct some docs, add configuration examples and required policies
- Remove
__utils__
use - Migrate tests to pytest
- Add (a lot of) new (unit/integration) tests (accounts for ~75% of additions!)
- Try to achieve all this while staying backwards-compatible: Keep the previous runner endpoint as well as public utils module functions. Translate the old vault configuration. Compatible with legacy
peer_run
config, but it should be updated to avoid unnecessary roundtrips/reduce network overhead
If you use Vault, please go read the pull request for many additional details (like this discussion).
Salt SSH
There are several great improvements in salt-ssh
:
- Add
sync_wrapper
to thesaltutil
runner/execution/state modules. PR #64518 by jeanluc - Improve salt-ssh error handling. PR #64542 by jeanluc . Also see #64576.
- Allow accessing the regular mine/event bus from salt-ssh (
mine
andpublish
wrappers). PR #65646 by jeanluc - Make Salt-SSH sync custom utils (this is about making direct imports work). PR #65735 by jeanluc
- Update existing wrapper modules to be mostly in sync with the respective execution modules. Wrap most
cp.*
functions, addslsutil
wrapper, adddefaults
wrapper, addlog[mod]
wrapper, addcmdmod
wrapper forcmd.script
, makecp.cache_file
add the respective files to the filerefs archive that is sent to the minion during state runs. PR #65517 by jeanluc
Also, a long-standing issue with git pillar branches was fixed in Salt 3006.5 by the same author: #61861.
Removals
- Drop Python 3.7 support. PRs #64417 and #64424 by Pedro Algarvio
- Remove Linode API v3 usage. PR #64623 by Zhiwei Liang
- Remove
salt.modules.napalm_mod.netmiko_conn
andpyeapi_conn
. PR #64466 by Charles McMarrow - Remove support for RHEL 5. PR #64491 by David Murphy
- Remove
salt/log/
, some of the logging handlers found insalt/_logging/handlers
,salt/modules/cassandra_mod.py
,salt/returners/cassandra_return.py
,salt/returners/django_return.py
. PRs #65986 and #66017 by Pedro Algarvio
GPG
- Add
signed_by_[any|all]
parameters togpg.verify
. PR #63168 by jeanluc - Change the
gpg_decrypt_must_succeed
default fromFalse
toTrue
(for pillar decryption). PR #64471 by Charles McMarrow - Unbreak the
gpg
state module. PR #63162 by jeanluc - Add keyring param to gpg modules. PR #63179 by jeanluc
Saltcheck
Add an optional junit
keyword to Saltcheck, to generate reports in JUnit format. GitLab should understand it out of the box; GitHub has a number of third-party actions for that.
PR #63464 by Meghann Cunningham
Cloud
- DigitalOcean: implement the
vpc_uuid
parameter when creating a droplet. This parameter selects the correct virtual private cloud. PR #63745 by @waynegemmell - DigitalOcean: Don’t throw an error when deleting an instance. PR #60119 by Konrad Mosoń
- Add Linode
backups_enabled
option, improve Linode Cloud docs. PR #65698 by Zhiwei Liang - Add Backup Schedule Setter Function for Linode VMs. PR #65714 by Zhiwei Liang
Package managers
- Add support for dnf5 on Fedora. PR #64675 by David Murphy
- Add the ability to remove packages by wildcard via apt execution module. PR #65221 by Nicholas Hughes
- Improve pip target override condition with
VENV_PIP_TARGET
environment variable. PR #65562 by Victor Zhestkov - Enhance zypper pkg module to remove PTF (Product Temporary Fix) packages. PR #63460 by Michael Calmer
- Add support for
gpgautoimport
torefresh_db
in thezypperpkg
module. PR #62209 by Michael Calmer
Windows
- Add state for managing scheduled tasks in Windows (
task.present
,task.absent
). PR #66108 by Shane Lee - Add
win_appx
module and state for managing Microsoft Store apps. PR #64353 by Shane Lee - Add back ssm.exe to the Salt onedir tarball. PR #63804 by Shane Lee
Small feature highlights
- Add
match
runner that provides thecompound_matches
function to check whether a minion is matched by a given compound match expression (in a more secure way, without asking the minion to match itself). PR #63297 by jeanluc - Make x509_v2 compound matching more secure by using the
match
runner. PR #64302 by jeanluc - Allow all primitive grain types for
autosign_grains
. PR #65232 by Alexander Graul - Add signature verification to
file.managed
andarchive.extracted
. PR #63611 by jeanluc - Add
acme
support for manual plugin hooks (manual_auth_hook
andmanual_cleanup_hook
scripts). PR #65745 by Lee Clemens - Support master tops on masterless minions. Add
sync_tops
to thesaltutil
execution and state modules. Make salt-ssh master tops behave like regular ones (merging returns for the same saltenv). PR #65481 by jeanluc - Implement jq-esque
to_entries
andfrom_entries
Jinja filters. PR #64602 by Nicholas Hughes - Add Salt package type (
pip
,onedir
) to the versions report and grain (package
). PR #64446 by Megan Wilhite
Other notable features
- Deprecate
setup.py
customizations in favor ofpyproject.toml
in 3009. PR #65525 by Pedro Algarvio - Make
pkg.installed
show the installable version in test mode. PR #63986 by Nicholas Hughes - Fix
cmd.run
to show changes in test mode. PR #64151 by Nicholas Hughes - Add the ability to return
False
result in test mode ofconfigurable_test_state
. PR #64419 by Nicholas Hughes - Add the option to use a fresh connection for the MySQL cache. PR #63993 by Brian Saville
- Add MySQL privilege
SERVICE_CONNECTION_ADMIN
. PR #64934 by Benjamin Cremer - Add a
local
flag for user/group creation (inuseradd
andgroupadd
exec modules, anduser
andgroup
state modules) to force users and groups to be created locally instead of in a remotely managed account management system (e.g. LDAP). PR #64257 by Brian Saville - Replace deprecated
ifconfig
withip
inlxc
,network
,nspawn
, andvagrant
modules, addnetwork.ip_neighs
andnetwork.ip_neighs6
functions. PR #64351 by David Murphy - Remove
isfile
check to increase speed of listing large numbers of minion keys (useful for NFS mounts). PR #64262 by Brian Saville - Add the
create_if_missing
parameter to handle basic file creation forfile.keyvalue
. PR #64028 by Nicholas Hughes - Add the
opsnscap.xccdf_eval
function that callsoscap xccdf eval
on minions. #63416 by Pablo Suárez Hernández - Stop using
load_module
in the loader, useexec_module
instead. PR #65032 by Daniel Wozniak - Add the
follow_symlinks
(True
by default) tofile.symlink
exec module. Now you can optionally set it toFalse
to speed up symlink creation on NFS directories. PR #64666 by Nicholas Hughes - Add support for
show_jid
tosalt-run
. PR #65008 by Barney Sowood - Update
__pillar__
duringpillar_refresh
(to ensure thatprocess_beacons
has the updated beacons loaded from the pillar). PR #65092 by Gareth J. Greenaway - Account for included states that only include other states used as requisites. PR #65326 by Gareth J. Greenaway
- Fix extfs parameter and retcode handling. PR #65687 by Nicholas Hughes
- Fix the efi grain on FreeBSD. PR #63052 by Alan Somers
- Add dedicated
check_cmd
implementation tofile.serialize
. PR #65291 by Nicholas Hughes - Enable port modification in state selinux.port_policy_present PR #56164 by Jason Woods
- Dereference symlinks to set proper
__cli
opt. PR #65435 by Victor Zhestkov - Add password support to the Redis returner. PR #58044 by @marnovdm and Roald Nefs
You can find other changes and bugfixes in the official CHANGELOG.md and Release Notes
P.S. It is unlikely that I’ll be able to track and cover these countless new extensions and their features from now on. It requires too many efforts to be sustainable. Something like Django Packages needs to be invented by the community to fill the gap. For my unofficial release notes series, I will see whether there are enough changes in Salt itself to continue publishing them, or if the official changelog will suffice.
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