Enroll inspects a Debian-like or RedHat-like system, harvests the state that matters, and generates Ansible roles/playbooks so you can bring snowflakes under management fast.
enroll single-shot --out ./ansiblecd ./ansible && tree -L 2. ├── ansible.cfg ├── playbook.yml ├── roles/ │ ├── cron/ │ ├── firewall/ │ ├── nginx/ │ ├── openssh-server/ │ ├── users/ │ ├── etc_custom/ └── README.md
--fqdn to generate inventory-driven, data-driven roles.Enroll is built around two phases, plus an optional drift report:
--fqdn mode, roles are data-driven and host inventory decides what gets managed per host.--sops to store harvests/manifests as a single encrypted .tar.gz.sops file (GPG) for safer long-term storage as a DR strategy.diff mode detects and alerts about drift over timeCopy, paste, iterate.
# Harvest → Manifest in one go
enroll single-shot --out ./ansible
# Then run Ansible locally
ansible-playbook -i "localhost," -c local ./ansible/playbook.yml
--jinjaturtle (or let it auto-detect).# Remote harvest over SSH, then manifest locally
enroll single-shot \
--remote-host myhost.example.com \
--remote-user myuser \
--harvest /tmp/enroll-harvest \
--out ./ansible \
--fqdn myhost.example.com
--no-sudo (expect a less complete harvest).# Multi-site mode: shared roles, host-specific state in inventory
enroll harvest --out /tmp/enroll-harvest
enroll manifest --harvest /tmp/enroll-harvest --out ./ansible --fqdn "$(hostname -f)"
# Run the per-host playbook
ansible-playbook ./ansible/playbooks/"$(hostname -f)".yml
--fqdn for "many servers, high abstraction, fast adoption".# Compare two harvests and get a human-friendly report
enroll diff --old /path/to/harvestA --new /path/to/harvestB --format markdown
# 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: ...' \
--exit-code
Use your preferred packaging. An AppImage is also available.
sudo mkdir -p /usr/share/keyrings
curl -fsSL https://mig5.net/static/mig5.asc | sudo gpg --dearmor -o /usr/share/keyrings/mig5.gpg
echo "deb [arch=amd64 signed-by=/usr/share/keyrings/mig5.gpg] https://apt.mig5.net $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/mig5.list
sudo apt update
sudo apt install enroll
sudo rpm --import https://mig5.net/static/mig5.asc
sudo tee /etc/yum.repos.d/mig5.repo > /dev/null << 'EOF'
[mig5]
name=mig5 Repository
baseurl=https://rpm.mig5.net/rpm/$basearch
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://mig5.net/static/mig5.asc
EOF
sudo dnf upgrade --refresh
sudo dnf install enroll
pip install enroll
# or: pipx install enroll
--dangerous, strongly consider pairing it with --sops for encrypted-at-rest bundles.