124 lines
12 KiB
HTML
124 lines
12 KiB
HTML
---
|
|
title: "Enroll 0.7.0: Puppet and Salt renderer support, Flatpak/Snap, and more"
|
|
html_title: "Enroll 0.7.0 News"
|
|
description: "Enroll 0.7.0 adds first-class Puppet and Salt manifest rendering alongside Ansible, along with other improvements."
|
|
date: 2026-06-17
|
|
summary: "Enroll can now render Puppet and Salt manifests alongside Ansible, detect Flatpak and Snap packages, other obscure runtime state, and produce better organised roles/modules."
|
|
---
|
|
<header class="py-5 hero">
|
|
<div class="container py-3">
|
|
<div class="kicker mb-3"><i class="bi bi-stars"></i> Release notes</div>
|
|
<h1 class="display-6 fw-bold mb-2">Enroll 0.7.0: Puppet and Salt join Ansible</h1>
|
|
<p class="lead mb-0">A single harvest can now be rendered into Ansible, Puppet, or Salt output.</p>
|
|
</div>
|
|
</header>
|
|
|
|
<main class="py-5">
|
|
<div class="container">
|
|
<div class="row g-4">
|
|
<div class="col-lg-8">
|
|
<article class="feature-card p-4">
|
|
<p class="text-secondary">Welcome to the first of Enroll's new, erm, news section! To celebrate, Enroll 0.7.0 has been released, and makes manifest rendering target-selectable based on your preferred config management tool! Ansible remains the default, but Puppet and Salt are now possible too (with a few small exceptions, read on).</p>
|
|
|
|
<h2 class="h4 fw-bold mt-4">Highlights</h2>
|
|
<ul>
|
|
<li><code>--target puppet</code> renders Puppet module/control-repo style output., and in <code>--fqdn</code> mode, renders per-host Hiera data.</li>
|
|
<li><code>--target salt</code> renders Salt state trees and, in <code>--fqdn</code> mode, Salt pillar data. Since it's Python, it also will make use of JinjaTurtle (if it finds it on your <code>$PATH</code>) to render templates, just like Ansible!</li>
|
|
<li>Ansible works basically as it always did, and is the default, but you can specify <code>--target ansible</code> too. As usual, in <code>--fqdn</code> mode, specific artifacts end up in <code>host_vars</code> inventory folders rather than polluting the 'golden' roles.</li>
|
|
<li>All three config management manifest renderers derive from the same harvest state. You can rendered repeatedly into different config management tools without re-harvesting the host!</li>
|
|
<li>Single-site output tries to combine package/service data by their package manager's <code>Section</code> (or equivalent metadata), to reduce role/module/state sprawl.</li>
|
|
<li>Flatpak and Snap detection!</li>
|
|
<li>Docker image detection!</li>
|
|
</ul>
|
|
|
|
<h2 class="h4 fw-bold mt-4">Dry-run examples</h2>
|
|
<div class="codeblock terminal">
|
|
<button class="btn btn-sm btn-outline-secondary copy-btn" data-copy-target="#news-070-noop"><i class="bi bi-clipboard"></i> Copy</button>
|
|
<pre class="mb-0"><code id="news-070-noop"><span class="prompt">$</span> enroll harvest --out ./harvest
|
|
|
|
<span class="prompt">$</span> enroll manifest --harvest ./harvest --target ansible --out ./ansible
|
|
<span class="prompt">$</span> ansible-playbook -i "localhost," -c local ./ansible/playbook.yml --check --diff
|
|
|
|
<span class="prompt">$</span> enroll manifest --harvest ./harvest --target puppet --out ./puppet
|
|
<span class="prompt">$</span> puppet apply --modulepath ./puppet/modules ./puppet/manifests/site.pp --noop
|
|
|
|
<span class="prompt">$</span> enroll manifest --harvest ./harvest --target salt --out ./salt
|
|
<span class="prompt">$</span> salt-call --local --file-root ./salt/states state.apply test=True</code></pre>
|
|
</div>
|
|
|
|
<p>I recommend using Salt 3008.1 - on Debian 13 I encountered annoying noisy Python errors with version 3007, which are unrelated to Enroll.</p>
|
|
|
|
<h2 class="h4 fw-bold mt-4">New grouping behaviour in roles/modules</h2>
|
|
<p class="text-secondary">Did you find the number of manifested roles overwhelming?</p>
|
|
<p>Previously, Enroll created an Ansible role (or, now, a Puppet module or Salt role) for pretty much every 'package' it found. In some cases (especially on desktops) this could result in hundreds of roles. Technically fine, but overwhelming to look at!</p>
|
|
|
|
<p>As of 0.7.0, where Enroll can read that package metadata, it groups related package and service snapshots by the package manager's <code>Section</code> category (or comparable backend metadata), to make it less noisy. For example, network-related packages and config files might end up in a role called <code>net</code>. Meanwhile, vim, nano might both appear in <code>editors</code>, and mutt and Thunderbird may be in <code>mail</code>.</p>
|
|
|
|
<p>If you're not a fan of this new layout, you can pass <code>--no-common-roles</code> to enforce the previous behaviour. Also, if you use <code>--fqdn</code> for host-specific data-driven output, the 'common' roles are disabled automatically, because it's then safer to avoid 'bleed in' of unnecessary package installation on other hosts from a role that otherwise 'assumes too much' for all hosts.</p>
|
|
|
|
<h2 class="h4 fw-bold mt-4">Flatpak and Snap detection</h2>
|
|
<p class="text-secondary">Beyond deb and rpm</p>
|
|
<p>When using Ansible, Enroll now attempts to detect Flatpak and Snaps present on the system. For Flatpaks, this includes user-specific Flatpaks as well as system-wide ones. Manifesting to Ansible will attempt to use the <code>community.general</code> collection to create <a href="https://galaxy.ansible.com/ui/repo/published/community/general/content/module/flatpak/" target="_blank" rel="noopener noreferrer">Flatpak</a> and <a href="https://galaxy.ansible.com/ui/repo/published/community/general/content/module/snap/" target="_blank" rel="noopener noreferrer">Snap</a> tasks to enforce the presence of those packages.</p>
|
|
<p>For now, unfortunately Flatpak/Snap manifesting will not occur for Puppet or Snap, just Ansible. Either way, the 'detection' still occurs at the <code>harvest</code> level, so you can still take advantage of that with other subcommands like <code>enroll diff</code>.</p>
|
|
|
|
<div class="codeblock terminal">
|
|
<pre class="mb-0"><code id="news-070-snap"><span class="prompt">$</span> sudo ansible-playbook playbook.yml -i localhost, -c local --tags role_snap --diff
|
|
|
|
PLAY [Apply all roles on all hosts] *******************************************************************************************************************************************************************************
|
|
|
|
TASK [Gathering Facts] ********************************************************************************************************************************************************************************************
|
|
ok: [localhost]
|
|
|
|
TASK [snap : Install system-wide snaps with full detected attributes] *********************************************************************************************************************************************
|
|
ok: [localhost] => (item={'channel': 'latest/stable', 'classic': False, 'dangerous': False, 'devmode': False, 'install_revision': False, 'name': 'bare', 'notes': ['base'], 'revision': 5, 'source': 'snap-list'})
|
|
ok: [localhost] => (item={'channel': 'latest/stable', 'classic': False, 'dangerous': False, 'devmode': False, 'install_revision': False, 'name': 'core24', 'notes': ['base'], 'revision': 1643, 'source': 'snap-list'})
|
|
ok: [localhost] => (item={'channel': 'latest/stable', 'classic': False, 'dangerous': False, 'devmode': False, 'install_revision': False, 'name': 'gnome-46-2404', 'notes': [], 'revision': 153, 'source': 'snap-list'})
|
|
ok: [localhost] => (item={'channel': 'latest/stable', 'classic': False, 'dangerous': False, 'devmode': False, 'install_revision': False, 'name': 'gtk-common-themes', 'notes': [], 'revision': 1535, 'source': 'snap-list'})
|
|
ok: [localhost] => (item={'channel': 'latest/stable', 'classic': False, 'dangerous': False, 'devmode': False, 'install_revision': False, 'name': 'mesa-2404', 'notes': [], 'revision': 1165, 'source': 'snap-list'})
|
|
ok: [localhost] => (item={'channel': 'latest/stable', 'classic': False, 'dangerous': False, 'devmode': False, 'install_revision': False, 'name': 'onionshare', 'notes': [], 'revision': 212, 'source': 'snap-list'})
|
|
ok: [localhost] => (item={'channel': 'latest/stable', 'classic': False, 'dangerous': False, 'devmode': False, 'install_revision': False, 'name': 'snapd', 'notes': ['snapd'], 'revision': 26865, 'source': 'snap-list'})
|
|
</code></pre>
|
|
</div>
|
|
|
|
<h2 class="h4 fw-bold mt-4">Docker image detection</h2>
|
|
<p class="text-secondary">Continuing to sniff out bits from your system...</p>
|
|
<p>The <code>harvest</code> now detects the presence of Docker images, if it has permission. In particular, it detects the SHA256 of the Docker image. All three renderers (Ansible, Salt and Puppet) will attempt to enforce the presence of those Docker images. For Puppet, you may need the <code>puppetlabs-docker</code> module installed. There are details in the manifested README.md of the Puppet code. For Ansible, you may need the <code>community.docker</code> collection, but on Debian 13 I found that it was already present by default in the official ansible Debian packages.</p>
|
|
|
|
<p>Please be aware that the Puppet and Salt renderers do not support the Flatpak/Snap package enforcement - only Ansible for now. You'll also need version 13+ of the <code>community.general</code> collection for this to work properly. A <code>requirements.yml</code> gets created with your manifest to help you install it if necessary.</p>
|
|
|
|
<h2 class="h4 fw-bold mt-4">Other smaller changes</h2>
|
|
<ul>
|
|
<li><code>sysctl</code> runtime parameters are now detected and would be written to <code>/etc/sysctl.d/99-enroll.conf</code>. Not all runtime parameters are supported.</li>
|
|
<li><code>.bashrc</code> and similar files are now only harvested from user directories when <code>--dangerous</code> is used, since this is a common place for sensitive environment variables to be set. As always, remember that <code>--dangerous</code> gives better harvest coverage, but you should use <code>--sops</code> or some other means of your own to encrypt the harvested data at rest safely!</li>
|
|
<li>Some output during an Ansible play is hidden with <code>no_log</code> to avoid potentially sensitive output, particularly of systemd unit state.</li>
|
|
<li>In case you missed it in version 0.6.0: Enroll now harvests runtime <code>iptables</code> and <code>ipset</code> rules!</li>
|
|
</ul>
|
|
|
|
<h2 class="h4 fw-bold mt-4">See you soon..</h2>
|
|
<p>I'm off to try and write more tests - we're at 83% coverage in pytest, and we also run a stack of 'noop' executions for Ansible, Puppet and Salt too now, <a href="https://git.mig5.net/mig5/enroll/actions/runs/592" target="_blank" rel="noopener noreferrer">in CI</a>.</p>
|
|
<p>Thanks to everyone who has reached out with suggestions, constructive criticism, and bug reports! You're helping make Enroll better for everyone.</p>
|
|
</ul>
|
|
|
|
</article>
|
|
</div>
|
|
|
|
<div class="col-lg-4">
|
|
<div class="callout p-4">
|
|
<div class="fw-semibold mb-2">Targets</div>
|
|
<ul class="small mb-0">
|
|
<li><code>--target ansible</code> (default)</li>
|
|
<li><code>--target puppet</code></li>
|
|
<li><code>--target salt</code></li>
|
|
</ul>
|
|
</div>
|
|
<div class="callout p-4 mt-3">
|
|
<div class="fw-semibold mb-2">Useful links</div>
|
|
<div class="d-grid gap-2">
|
|
<a class="btn btn-sm btn-outline-dark" href="../docs.html#targets"><i class="bi bi-book"></i> Target docs</a>
|
|
<a class="btn btn-sm btn-outline-dark" href="../examples.html"><i class="bi bi-terminal"></i> Examples</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</main>
|