SaltStack FreeBSD Jails β€” Part 1

2023-03-10 β€’ 3 min read β€’ Tags: Comp Sysadm Freebsd

Hear ye, hear ye, Salt’s most important functions (aka “states”) are jails/chroot-aware! πŸŽŠπŸŽ‰

Meaning when you define a service, install a package or copy a file, it is possible to specify the jail in which that should happen!

What’s crazy is that I’ve been a salt user since at least 2014 (says my git log) and, despite actively searching for this specific solution on the web for a long time now, I’ve never heard of it! 😳 This feature is not even obvious from the docs, as when you look at the documentation of a given state, it’s not clear that you should actually look into the OS-specific counterpart module, which in turn does contain OS-specific options, like jail 😑

Why is this important for me as a FreeBSD user? Because it brings me closer to being able to run a salt master and abandoning salt-ssh for good. As mentioned previously, my main motivation to start with salt-ssh instead of a master/minion setup was: 1.Β start simple, 2.Β avoid running minions in jails. But salt-ssh started showing serious issues since the move to python 3 (2017 maybe) and is basically abandoned now1.

What’s more, I discovered BastilleBSD, accidentally looking at how iocage was doing. Bastille has an interesting docker-like templating system and is inspired by Salt. I might well give it a try and just store template files in salt2. Maybe just use it for jails management and even write a salt module. Exciting!

It stroke me when I installed paperless onto a Linux raspberry-pi lately: it was as simple as configuring the docker-compose.yml file and adding it to salt. That’s instead of packaging everything in salt. Bastille goes very much into that direction.

I felt a bit dizzy and confused when discovering all this, like when configuring i3, urxvt, tmux and emacs: boundaries get blurry, it’s not easy to decide which we’re going to use for what. Tabs in i3 or in tmux? Split windows in tmux or multiple windows? Shell in emacs or in tmux? Is emacs a window manager?…

I started adapting a couple of my salt-based service definitions to become jail-aware and assigned these definitions to the host node instead of the jail. To keep service definitions generic (within a jail or not), my first attempt involves pillar data (similar to ansible vars) which makes it not immediately visible at top file level if the service runs inside a jail. Also it’s slightly less convenient to apply definitions at the granurity of jails. Fortunately jails usually have few definitions so that the state.apply command mostly does it.

OK but the switch from salt-ssh to master/minions may also come with the challenge of reaching distant nodes. We could make an ssh config to chain proxies (for example with ProxyCommand). But the salt master maintains a permanent connection to minions. I hope to overcome that with an internal VPN.

Now I can’t remember how I actually discovered jails-aware salt states… πŸ€” I think I was once again trying to figure how to manage jails from the host with salt and stumbled upon some obscure github issue, which finally led me the documentation of the pkgng module then its source code. And this is when it clicked!

UPDATE: See the follow-up post on failing to exploit this feature.


  1. See for example https://github.com/saltstack/salt/issues/21370, https://github.com/saltstack/salt/issues/31531, https://github.com/saltstack/salt/issues/58762↩︎

  2. Note for later: looks like templates and sysrc bastille_list="jail1 jail2" really is all I need. ↩︎