--- title: "Examples" html_title: "Enroll Examples" description: "Copy/paste recipes for Enroll: Ansible, Puppet, Salt, fleets, drift detection, and safe storage." ---
Examples

Copy/paste recipes

Practical flows you can adapt to Ansible, Puppet, Salt, or all three.

Harvest once, try each renderer locally
$ enroll harvest --out /tmp/enroll-harvest

# Ansible noop
$ enroll manifest --harvest /tmp/enroll-harvest --target ansible --out /tmp/enroll-ansible
$ ansible-playbook -i "localhost," -c local /tmp/enroll-ansible/playbook.yml --diff --check

# Puppet noop
$ enroll manifest --harvest /tmp/enroll-harvest --target puppet --out /tmp/enroll-puppet
$ puppet apply --modulepath /tmp/enroll-puppet/modules /tmp/enroll-puppet/manifests/site.pp --noop

# Salt noop
$ enroll manifest --harvest /tmp/enroll-harvest --target salt --out /tmp/enroll-salt
$ salt-call --local --file-root /tmp/enroll-salt/states state.apply test=True

Great for “make this box reproducible”, testing renderer output, or building a golden baseline you will refine.

Enroll a remote host over SSH
$ enroll harvest \
  --remote-host myhost.example.com \
  --remote-user myuser \
  --out /tmp/enroll-harvest

$ enroll manifest \
  --harvest /tmp/enroll-harvest \
  --target puppet \
  --out /tmp/enroll-puppet

The bundle lands locally. Change --target puppet to ansible or salt without re-harvesting. For remote sudo prompts use --ask-become-pass/-K; use --no-sudo for a less complete non-root harvest.

Fleets: --fqdn output
$ fqdn="$(hostname -f)"
$ enroll harvest --out /tmp/enroll-harvest

# Ansible: inventory/host_vars and a per-host playbook
$ enroll manifest --harvest /tmp/enroll-harvest --target ansible --out /tmp/enroll-ansible --fqdn "$fqdn"
$ ansible-playbook /tmp/enroll-ansible/playbooks/${fqdn}.yml -i /tmp/enroll-ansible/inventory/hosts.ini -c local --check --diff

# Puppet: Hiera data keyed by certname
$ enroll manifest --harvest /tmp/enroll-harvest --target puppet --out /tmp/enroll-puppet --fqdn "$fqdn"
$ puppet apply --modulepath /tmp/enroll-puppet/modules --hiera_config /tmp/enroll-puppet/hiera.yaml --certname "$fqdn" /tmp/enroll-puppet/manifests/site.pp --noop

# Salt: pillar data keyed by minion id
$ enroll manifest --harvest /tmp/enroll-harvest --target salt --out /tmp/enroll-salt --fqdn "$fqdn"
$ salt-call --local --id "$fqdn" --file-root /tmp/enroll-salt/states --pillar-root /tmp/enroll-salt/pillar state.apply test=True

--fqdn disables common grouping and moves host-specific state into the target’s native host-data layer: inventory, Hiera, or pillar.

Control role/module/state grouping
# Default single-site mode: combine packages/services by package Section where possible
$ enroll manifest --harvest /tmp/enroll-harvest --target ansible --out /tmp/enroll-ansible

# Keep output split more literally by discovered package/service role
$ enroll manifest --harvest /tmp/enroll-harvest --target ansible --out /tmp/enroll-ansible-raw --no-common-roles

# --fqdn also disables common grouping because host data must remain isolated
$ enroll manifest --harvest /tmp/enroll-harvest --target salt --out /tmp/enroll-salt --fqdn "$(hostname -f)"

Grouping keeps first-pass output manageable. Use --no-common-roles when you prefer more direct one-role-per-package/service output.

Drift detection with enroll diff
$ enroll diff --old /path/to/harvestA --new /path/to/harvestB \
  --format markdown \
  --exclude-path /var/anacron \
  --ignore-package-versions

$ enroll diff --old /path/to/golden --new /path/to/current \
  --webhook https://example.net/webhook \
  --webhook-format json \
  --webhook-header 'X-Enroll-Secret: ...' \
  --ignore-package-versions \
  --exit-code

Use it in cron, systemd timers, or CI to alert on change.

Explain a harvest with enroll explain
$ enroll explain /tmp/enroll-harvest

# machine-readable reasons, examples, and inventory breakdown
$ enroll explain /tmp/enroll-harvest --format json | jq .

# encrypted bundle
$ enroll explain /var/lib/enroll/harvest.tar.gz.sops --sops

Great for answering “why did it include/exclude that file?” before you generate a manifest.

Enforce the previous state with enroll diff --enforce
$ enroll diff \
  --old /path/to/harvestA \
  --new /path/to/harvestB \
  --enforce \
  --format json

Enforcement currently uses generated Ansible and ansible-playbook on PATH, even if you also use Puppet or Salt for normal manifest output.

Encrypt bundles at rest with SOPS
$ enroll harvest --dangerous --out /tmp/harvest \
  --sops <FINGERPRINT>

$ enroll manifest --harvest /tmp/harvest/harvest.tar.gz.sops \
  --target salt \
  --out /tmp/enroll-salt \
  --sops <FINGERPRINT>

Use this if you intend to store harvests/manifests long term or if you harvested with --dangerous.