diff --git a/src/content/_index.html b/src/content/_index.html
index c31bc8a..2e62fb4 100644
--- a/src/content/_index.html
+++ b/src/content/_index.html
@@ -1,26 +1,26 @@
---
title: "Enroll"
-html_title: "Enroll - Reverse-engineering Linux hosts into Ansible"
-description: "Enroll inspects Debian-like and RedHat-like Linux hosts and generates Ansible configuration-management code from what it finds. Harvest → Manifest → Manage."
-og_title: "Enroll - Reverse-engineering Linux hosts into Ansible"
-og_description: "Harvest a host's real configuration and turn it into Ansible roles and playbooks. Safe-by-default, with optional SOPS encryption."
+html_title: "Enroll - Reverse-engineering servers into configuration management"
+description: "Enroll inspects Debian-like and RedHat-like Linux hosts and generates Ansible, Puppet, or Salt manifests from what it finds. Harvest → Manifest → Manage."
+og_title: "Enroll - Reverse-engineering servers into configuration management"
+og_description: "Harvest a host's real configuration and turn it into Ansible, Puppet, or Salt code. Safe-by-default, with optional SOPS encryption."
og_type: "website"
---
-
Reverse-engineering Linux hosts into Ansible
-
Get an existing server into configuration management without starting from a blank file.
-
Enroll inspects a Debian-like or RedHat-like Linux machine, harvests the state that matters, and generates Ansible roles and playbooks from the captured bundle.
+
Reverse-engineering servers into Ansible, Puppet, or Salt
+
Get an existing Linux host into configuration management in seconds.
+
Enroll inspects a Debian-like or RedHat-like system, harvests the state that matters, and generates Ansible roles, Puppet modules, or Salt states so you can bring snowflakes under management fast.
Current Enroll output is Ansible-only. Older examples that mention --target puppet or --target salt are from an experimental branch and no longer match the CLI.
+
Tip: for multiple hosts, use --fqdn to generate target-native host data: Ansible inventory, Puppet Hiera, or Salt pillar.
@@ -50,24 +52,96 @@ og_type: "website"
-
The mental model
-
Enroll is built around a small pipeline: capture first, render later, validate before you trust the output.
+
A simple mental model
+
Enroll is built around two phases, plus optional drift and reporting tools:
-
Harvest
Collect host facts and selected files into a bundle.
-
Manifest
Turn that bundle into an Ansible repository-style output tree.
-
Diff
Compare two harvests and optionally notify by webhook or email.
-
Explain
Summarise what was included or excluded and why.
-
Validate
Check schema and artifact consistency before using a bundle.
+
+
+
+
Harvest
+
Collect host facts + relevant files into a bundle.
+
+
+
+
+
+
Manifest
+
Render Ansible roles/playbooks, Puppet modules/Hiera data, or Salt states/pillar from the harvest.
+
+
+
+
+
+
Diff
+
Compare two harvests and notify via webhook/email.
+
+
+
+
+
+
Explain
+
Analyze what's included/excluded in the harvest and why.
+
+
+
+
+
+
Validate
+
Confirm that a harvest isn't corrupt or lacking artifacts.
+
+
-
Default secret avoidance
Likely private keys, credential assignments, tokens, secret paths, oversized files, and binary-looking files are avoided unless you opt into --dangerous.
-
Ansible output
Generated output includes roles, playbooks, requirements, defaults, templates, and host variables in --fqdn mode.
-
Grouped roles by default
Package/service snapshots are grouped by Debian Section or RPM Group where possible. Use --no-common-roles to keep one generated role per package or unit.
-
Multi-site mode
--fqdn moves host-specific state into Ansible inventory and implies --no-common-roles.
-
Remote over SSH
Run the harvest on another host through Paramiko/OpenSSH config support, then render the manifest locally.
-
SOPS bundles
--sops stores harvests and generated manifests as encrypted tarballs for safer at-rest storage.
+
+
+
+
Safe-by-default harvesting
+
Enroll avoids likely secrets with a path denylist, content sniffing, and size caps - then lets you opt in to more aggressive collection when you're ready.
+
+
+
+
+
+
+
Ansible, Puppet, or Salt
+
The harvest bundle is renderer-neutral. Choose --target ansible, --target puppet, or --target salt at manifest time.
+
+
+
+
+
+
+
Fewer roles/modules where possible
+
By default, package/service snapshots are grouped by package Section or equivalent metadata to reduce role/module sprawl. Use --no-common-roles, or --fqdn, to keep output more host-specific.
+
+
+
+
+
+
+
Multi-site without "shared role broke host2"
+
In --fqdn mode, host-specific data moves into the target's native host-data layer: Ansible inventory, Puppet Hiera, or Salt pillar.
+
+
+
+
+
+
+
Remote over SSH
+
Harvest a remote host from your workstation, then render Ansible, Puppet, or Salt output locally.
+
+
+
+
+
+
+
Encrypt bundles at rest
+
Use --sops to store harvests/manifests as a single encrypted .tar.gz.sops file (GPG) for safer long-term storage as a DR strategy.
+
+
+
@@ -77,78 +151,272 @@ og_type: "website"
-
Quickstart
Start with a local safe-mode harvest, inspect the generated output, then run Ansible when you are ready.
# Harvest once
+enroll harvest --out ./harvest
+
+# Render and noop-test Ansible
+enroll manifest --harvest ./harvest --target ansible --out ./ansible
+ansible-playbook -i "localhost," -c local ./ansible/playbook.yml --check --diff
+
+# Render and noop-test Puppet
+enroll manifest --harvest ./harvest --target puppet --out ./puppet
+puppet apply --modulepath ./puppet/modules ./puppet/manifests/site.pp --noop
+
+# Render and noop-test Salt
+enroll manifest --harvest ./harvest --target salt --out ./salt
+salt-call --local --file-root ./salt/states state.apply test=True
+
+
+
+
+
Good for
+
Disaster recovery snapshots, "make this one host reproducible", and comparing how the same harvest looks in Ansible, Puppet, or Salt before you commit to a workflow.
+
+
Using Ansible and want templates for structured configs? Install JinjaTurtle and use --jinjaturtle (or let it auto-detect).
If you don't want/need sudo on the remote host, add --no-sudo (expect a less complete harvest). For remote sudo prompts use --ask-become-pass/-K. If your SSH private key is encrypted, use --ask-key-passphrase (interactive) or --ssh-key-passphrase-env ENV_VAR (non-interactive/CI).
Rule of thumb: single-site for "one server, easy-to-read roles/modules/states"; --fqdn for "many servers, host-specific data, fast adoption".
+
+
+
+
+
# Compare two harvests and get a human-friendly report (ignoring noise)
+enroll diff --old /path/to/harvestA --new /path/to/harvestB --format markdown \
+ --exclude-path /var/anacron \
+ --ignore-package-versions
+
+# Send a webhook when differences are detected
+enroll diff \
+ --old /path/to/harvestA \
+ --new /path/to/harvestB \
+ --webhook https://example.net/webhook \
+ --webhook-format json \
+ --webhook-header 'X-Enroll-Secret: ...' \
+ --ignore-package-versions \
+ --exit-code
+
+# Ignore a path and changes to package versions, and optionally
+# enforce the old state locally
+enroll diff --old /path/to/harvestA --new /path/to/harvestB \
+ --exclude-path /var/anacron \
+ --ignore-package-versions \
+ --enforce
+
+
E-mail notifications are also supported. Run it on a systemd timer to alert to drift!
+
+
+
+
+
# Explain what's in a harvest
+enroll explain /path/to/harvest
+
+# JSON format, and using a SOPS-encrypted harvest
+enroll explain /path/to/harvest.sops \
+ --sops \
+ --format json
+
+
+
'explain' tells you why something was included, but also why something was excluded.
+
+
+
+
+
# Validate a harvest is correct.
+enroll validate /path/to/harvest
+
+# Check against the latest published version of the state schema specification
+enroll validate /path/to/harvest --schema https://enroll.sh/schema/state.schema.json
+
+
+
'validate' makes sure the harvest's state conforms to Enroll's state schema, doesn't contain orphaned artifacts and isn't missing any artifacts needed by the state. By default, it checks against the schema packaged with Enroll, but you can also check against the latest version on this site.
+
-
+
-
What Enroll tries to capture
+
+
+
Demonstrations
+
+
+
-
Packages and services
Manual packages, service-linked packages, systemd enable/running state, and service-relevant changed or custom config.
-
Configuration files
Changed package conffiles, unowned service files, miscellaneous /etc, APT/DNF/YUM config, selected symlinks, and explicit include paths.
-
Runtime and user state
Non-system users, SSH public keys, Flatpak/Snap state, Docker/Podman images, writable sysctls, and fallback iptables/ipset state when persistent files are absent.
-
-
-
-
-
-
-
Commands
-
-
harvest
Collect host state into state.json and artifacts/.
Enroll avoids obvious secrets by default, validates harvest structure, freezes directory bundles into private temp trees before manifesting, rejects unknown SSH host keys, and warns when a root PATH looks unsafe.
-
It cannot prove that a structurally valid harvest is semantically safe. Only apply manifests generated from harvests whose provenance you trust.
+
+
+
+
Harvest
+
Collect state into a bundle.
+
+
+
-
-
-
Dangerous mode means dangerous
-
Use --dangerous only when you intentionally want to bypass likely-secret checks. Pair it with --sops or another appropriate at-rest encryption workflow whenever there is any doubt.
+
+
+
+
Manifest
+
Render Ansible roles/playbooks, Puppet modules, or Salt states.
+
+
+
+
+
+
+
+
+
+
Single-shot
+
Harvest → Manifest in one command.
+
+
+
+
+
+
+
+
Diff
+
Drift report + webhook/email notifications, or optionally enforce the previous state!
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
News
+
Enroll 0.7.0 adds Puppet and Salt rendering
+
The same harvest bundle can now render Ansible, Puppet, or Salt output, with target-native multi-host layouts and package-section grouping where possible.
diff --git a/src/content/docs.html b/src/content/docs.html
index c8ad555..9477d27 100644
--- a/src/content/docs.html
+++ b/src/content/docs.html
@@ -1,182 +1,308 @@
---
title: "Docs"
-html_title: "Enroll documentation - Ansible host harvesting and manifesting"
-description: "Documentation for the current Enroll CLI: harvest Linux host state and generate Ansible configuration-management code."
-og_title: "Enroll documentation"
-og_description: "Current Enroll docs for harvest, manifest, single-shot, diff, explain, validate, security, SOPS, and Ansible output."
-og_type: "article"
+html_title: "Enroll Docs"
+description: "How Enroll works: harvest, manifest, modes, and configuration."
---
-
-
-
-
-
Documentation
-
How Enroll works today
-
Enroll harvests selected Linux host state, validates it, and renders Ansible configuration-management output. This documentation reflects the current Ansible-only CLI.