Add enroll single-shot

Miguel Jacq 2025-12-17 22:45:11 -06:00
parent d94af7d649
commit 0b919ed090

214
enroll single-shot.-.md Normal file

@ -0,0 +1,214 @@
# enroll single-shot
Run **harvest -> manifest** in one command.
This is the convenience "do the whole thing" mode: it collects a harvest bundle (locally or remotely) and immediately generates an Ansible manifest from it.
---
## Synopsis
```bash
enroll single-shot --harvest <DIR> --out <DIR|FILE> [--fqdn <HOST>] [--dangerous] [--sops <GPG_FPR...>] [--jinjaturtle | --no-jinjaturtle] [--remote-host <HOST> [--remote-user <USER>] [--remote-port <PORT>] [--no-sudo]]
```
---
## What it does
1) **Harvest phase**
- Runs the same logic as `enroll harvest`
- Produces a harvest bundle (plaintext directory unless `--sops` is enabled)
2) **Manifest phase**
- Runs the same logic as `enroll manifest`
- Produces an Ansible output tree (plaintext directory unless `--sops` is enabled)
- `--fqdn` controls whether the output is **single-site** (default) or **site mode**
---
## Required arguments
### `--harvest <dir>`
Where to write the (intermediate) harvest bundle.
- In single-shot, `--harvest` is treated as a **directory path**.
- It may be:
- a newly created directory, or
- an existing directory (contents may be overwritten/updated)
> Note: Unlike `enroll harvest`, single-shot assumes you want a concrete directory for the intermediate harvest output.
### `--out <path>`
Where to write the final manifest output.
- **Plain mode (no `--sops`)**
- must be a directory path
- **SOPS mode (`--sops ...`)**
- may be a directory (writes `manifest.tar.gz.sops` inside), or
- may be a file path (writes that exact file)
---
## Options
### `--fqdn <host>`
Enable "site mode" output (inventory + per-host vars) in the manifest phase.
If omitted, output is generated in "single-site mode" with a top-level `playbook.yml`.
### `--dangerous`
Applies to the harvest phase.
Disables "likely secret" safety checks, potentially collecting:
- private keys
- TLS key material
- database passwords
- API tokens
- other credentials
Strongly consider using `--sops` when you enable `--dangerous`.
### `--sops <GPG_FINGERPRINT...>`
Enable SOPS "encrypt at rest" mode for single-shot.
In single-shot, `--sops` affects **both** phases:
- Harvest output is written as a SOPS file (typically `harvest.tar.gz.sops`) in the harvest directory
- Manifest output is written as a SOPS file (typically `manifest.tar.gz.sops`) in the output location
Requires `sops` available on `PATH`.
> If you want plaintext harvest but encrypted manifest (or the other way around), use `enroll harvest` and `enroll manifest` separately instead of single-shot.
### JinjaTurtle integration
#### `--jinjaturtle`
Force templating **on** for the manifest phase (errors if not installed).
#### `--no-jinjaturtle`
Force templating **off** for the manifest phase.
#### Default (no flag)
Auto mode: use JinjaTurtle if found on `PATH`.
### Remote harvesting
#### `--remote-host <host>`
Run the harvest phase on a remote host over SSH, then generate the manifest locally.
#### `--remote-user <user>`
SSH username (default: local `$USER`).
#### `--remote-port <port>`
SSH port (default: `22`).
#### `--no-sudo`
Dont use sudo on the remote host (may result in partial harvest).
---
## Permutations (valid combinations)
### Local, plain, single-site
```bash
enroll single-shot --harvest /tmp/enroll-harvest --out /tmp/enroll-ansible
```
### Local, plain, site mode (`--fqdn`)
```bash
enroll single-shot --harvest /tmp/enroll-harvest --out /tmp/enroll-ansible --fqdn "$(hostname -f)"
```
### Local, plain, `--dangerous`
```bash
enroll single-shot --harvest /tmp/enroll-harvest --out /tmp/enroll-ansible --dangerous
```
### Local, plain, control JinjaTurtle
Force off:
```bash
enroll single-shot --harvest /tmp/enroll-harvest --out /tmp/enroll-ansible --no-jinjaturtle
```
Force on:
```bash
enroll single-shot --harvest /tmp/enroll-harvest --out /tmp/enroll-ansible --jinjaturtle
```
---
### Local, SOPS-encrypted (`--sops`) output
Output to directory:
```bash
enroll single-shot --harvest /tmp/enroll-harvest --out /tmp/enroll-ansible --sops <FPR1>
# writes /tmp/enroll-harvest/harvest.tar.gz.sops and /tmp/enroll-ansible/manifest.tar.gz.sops
```
Output to a specific manifest file:
```bash
enroll single-shot --harvest /tmp/enroll-harvest --out /tmp/enroll-ansible/manifest.tar.gz.sops --sops <FPR1>
```
### Local, SOPS-encrypted + `--dangerous`
```bash
enroll single-shot --harvest /tmp/enroll-harvest --out /tmp/enroll-ansible --dangerous --sops <FPR1>
```
### Local, SOPS-encrypted + site mode
```bash
enroll single-shot --harvest /tmp/enroll-harvest --out /tmp/enroll-ansible --fqdn "$(hostname -f)" --sops <FPR1>
```
---
### Remote, plain, single-site
```bash
enroll single-shot --remote-host host.example.com --harvest /tmp/enroll-harvest --out /tmp/enroll-ansible
```
### Remote, plain, site mode
```bash
enroll single-shot --remote-host host.example.com --harvest /tmp/enroll-harvest --out /tmp/enroll-ansible --fqdn "host.example.com"
```
### Remote, plain, `--dangerous`
```bash
enroll single-shot --remote-host host.example.com --harvest /tmp/enroll-harvest --out /tmp/enroll-ansible --dangerous
```
### Remote, plain, without sudo
```bash
enroll single-shot --remote-host host.example.com --no-sudo --harvest /tmp/enroll-harvest --out /tmp/enroll-ansible
```
### Remote, SOPS-encrypted output
```bash
enroll single-shot --remote-host host.example.com --harvest /tmp/enroll-harvest --out /tmp/enroll-ansible --sops <FPR1>
```
### Remote, SOPS-encrypted + `--dangerous` + site mode
```bash
enroll single-shot --remote-host host.example.com --harvest /tmp/enroll-harvest --out /tmp/enroll-ansible --fqdn "host.example.com" --dangerous --sops <FPR1>
```
---
## Working with the encrypted manifest output
If you used `--sops`, the final output is a single file (typically `manifest.tar.gz.sops`). To use it with Ansible:
```bash
mkdir -p /tmp/enroll-manifest && cd /tmp/enroll-manifest
sops -d /path/to/manifest.tar.gz.sops | tar -xzvf -
```
Then run Ansible from inside the extracted tree.
---
## Common gotchas
- `--dangerous` affects **harvest only** (but in single-shot it still impacts what ends up in the manifest).
- In SOPS mode, you must decrypt/extract before running Ansible.
- If you want to mix plaintext and SOPS between phases, use `harvest` and `manifest` separately instead of single-shot.