Add enroll manifest

Miguel Jacq 2025-12-17 22:43:08 -06:00
parent d8492fb67d
commit 0ad918fb25

186
enroll-manifest.md Normal file

@ -0,0 +1,186 @@
# enroll manifest
Generate an Ansible "manifest" (roles/playbooks, and optionally inventory) from an existing harvest bundle.
---
## Synopsis
```bash
enroll manifest --harvest <DIR|SOPS_FILE> --out <DIR|FILE> [--fqdn <HOST>] [--jinjaturtle | --no-jinjaturtle] [--sops <GPG_FPR...>]
```
---
## Inputs
### `--harvest <path>` (required)
Path to the harvest input.
- **Plain mode (no `--sops`)**
- must be a **directory** created by `enroll harvest` (containing `state.json`, `artifacts/`)
- **SOPS mode (`--sops ...`)**
- may be either:
- a **directory** (already decrypted), or
- a **SOPS-encrypted harvest tarball** produced by `enroll harvest --sops` (e.g. `harvest.tar.gz.sops`)
---
## Outputs
### Plain mode output (directory)
In plain mode, `--out` is a directory that is written in-place.
#### Default (single-site mode, no `--fqdn`)
Typical top-level layout:
- `roles/`
- `playbook.yml`
#### Site mode (`--fqdn <host>`)
Adds inventory scaffolding and per-host files:
- `roles/`
- `inventory/hosts.ini`
- `inventory/host_vars/<fqdn>/...`
- `playbooks/<fqdn>.yml`
- `ansible.cfg`
In site mode, some raw harvested files are stored under:
`inventory/host_vars/<fqdn>/<role>/.files/...`
to avoid cross-host clobber while still sharing role code.
### SOPS mode output (single encrypted file)
When `--sops <FPR...>` is set, the manifest output is bundled and encrypted into one file:
- `manifest.tar.gz.sops`
`--out` may be:
- a directory - `manifest.tar.gz.sops` is created inside it
- a file path - that exact filename is written
---
## Options
### `--out <path>` (required)
Where to write the manifest output.
- **Plain mode**: must be a directory path (created if needed).
- **SOPS mode**: may be a directory or a file path (see above).
### `--fqdn <host>`
Enable "site mode" output.
- Generates `inventory/`, `inventory/host_vars/<fqdn>/...`, and `playbooks/<fqdn>.yml`. This includes the `inventory/hosts.ini` with the fqdn inside it.
- Generates an `ansible.cfg` with some nice defaults for running against multiple remote hosts.
- Useful when you are enrolling multiple hosts into a shared repo layout
If `--fqdn` is omitted (or empty), the manifest is generated in "single-site mode" with `playbook.yml`, and no inventory files (all role parameters are stored in `defaults/main.yml` in the roles) or `ansible.cfg`. In that scenario, you are responsible for creating the `inventory` file or using `-i`.
If you *do* include `--fqdn`, and run the command repeatedly against different harvests but with the same `--out` param, Enroll will 'merge' the new host's inventory, roles, and playbooks into your manifest directory, as opposed to **overwrite** it.
Therefore, if you keep running `harvest` against all your hosts, you can gradually assemble a 'complete' manifest of all roles/playbooks/inventory of all hosts!
### JinjaTurtle integration
#### `--jinjaturtle`
Force JinjaTurtle templating integration **on**.
- Errors if `jinjaturtle` is not available on `PATH`.
#### `--no-jinjaturtle`
Force JinjaTurtle integration **off**, even if its installed.
#### Default (no flag)
Auto mode: use JinjaTurtle if found on `PATH`, otherwise do not.
### `--sops <GPG_FINGERPRINT...>`
Enable SOPS mode for manifest generation.
In this mode:
1) If `--harvest` is an encrypted file, `enroll` decrypts and extracts it (using `sops -d`) to a secure temp directory.
2) It generates the manifest into a secure temp directory.
3) It bundles (tar.gz) and encrypts the entire manifest output into `manifest.tar.gz.sops`.
Requires `sops` available on `PATH`.
---
## Permutations (valid combinations)
### Plain + single-site (default; JinjaTurtle auto)
```bash
enroll manifest --harvest /path/to/harvest-dir --out /path/to/ansible-dir
```
### Plain + site mode (`--fqdn`)
```bash
enroll manifest --harvest /path/to/harvest-dir --out /path/to/ansible-dir --fqdn host.example.com
```
### Plain + disable JinjaTurtle
```bash
enroll manifest --harvest /path/to/harvest-dir --out /path/to/ansible-dir --no-jinjaturtle
```
### Plain + force JinjaTurtle on
```bash
enroll manifest --harvest /path/to/harvest-dir --out /path/to/ansible-dir --jinjaturtle
```
---
### SOPS output (manifest encrypted), harvest input is a directory
Output to a directory (default filename inside):
```bash
enroll manifest --harvest /path/to/harvest-dir --out /path/to/out-dir --sops <FPR1>
# writes /path/to/out-dir/manifest.tar.gz.sops
```
Output to a specific file:
```bash
enroll manifest --harvest /path/to/harvest-dir --out /path/to/manifest.tar.gz.sops --sops <FPR1>
```
### SOPS output, harvest input is an encrypted file
```bash
enroll manifest --harvest /path/to/harvest.tar.gz.sops --out /path/to/out-dir --sops <FPR1>
```
### SOPS output + site mode (`--fqdn`)
```bash
enroll manifest --harvest /path/to/harvest.tar.gz.sops --out /path/to/out-dir --fqdn host.example.com --sops <FPR1>
```
### SOPS output + JinjaTurtle control
Force on:
```bash
enroll manifest --harvest /path/to/harvest.tar.gz.sops --out /path/to/out-dir --sops <FPR1> --jinjaturtle
```
Force off:
```bash
enroll manifest --harvest /path/to/harvest.tar.gz.sops --out /path/to/out-dir --sops <FPR1> --no-jinjaturtle
```
---
## Working with the encrypted manifest (`manifest.tar.gz.sops`)
The encrypted manifest is one file; to use it with Ansible you typically:
```bash
mkdir -p /tmp/enroll-manifest && cd /tmp/enroll-manifest
sops -d /path/to/manifest.tar.gz.sops | tar -xzvf -
```
After extraction, run Ansible from inside the extracted tree.
---
## Common gotchas
- In **plain mode**, `--out` is written in-place. If you re-run against the same output directory, expect files to be updated/overwritten.
- In **site mode**, host-specific state lives under `inventory/host_vars/<fqdn>/...`; this is intentionally per-host.
- In **SOPS mode**, the manifest is not directly runnable until you decrypt and extract it.