digitalboard.core/roles/garage/README.md
Simon Bärlocher 03bf0efe44
docs(collection): document all roles and fix metadata drift
Replace ansible-galaxy init placeholders across the collection and
correct documentation that drifted from the code, after a multi-agent
review of every role README against its defaults, tasks and templates.

Collection level:
- README: role table for all 16 roles, requirements and role-ordering
- galaxy.yml: declare community.docker and community.general deps,
  real description/tags/urls; normalize license to MIT-0
- meta/runtime.yml: requires_ansible '>=2.15.0'
- plugins/README: document the homarr_layout filter and
  garage_credentials lookup instead of scaffold boilerplate

Per-role meta/main.yml and README for the placeholder roles
(389ds, authentik, authentik_outpost_ldap, base, collabora, drawio,
garage, homarr, httpbin, keycloak, nextcloud, opencloud, traefik).

Correctness fixes found during review:
- keycloak: wrong domain default, drop invented keycloak_cert_resolver,
  document the provisioning feature
- garage: root_domain is .s3.<first-entry>, not the bare domain
- opnform: jwt/front_api secrets use `openssl rand -hex 32`; align the
  validation fail_msg in tasks/main.yml accordingly
- send: S3 example references garage_s3_domains[0] (was singular)
- opencloud: document required opencloud_wopi_domain

License normalized to MIT-0 across galaxy.yml, role meta and READMEs to
match the SPDX headers.
2026-05-27 22:33:42 +02:00

118 lines
3.8 KiB
Markdown

# Garage
Ansible role to deploy [Garage](https://garagehq.deuxfleurs.fr/) S3-compatible
object storage via Docker Compose, with declarative key/bucket
provisioning and an optional WebUI behind htpasswd or authentik
ForwardAuth.
## Requirements
- Docker and Docker Compose installed on the target host
- Ansible collection: `community.docker`
- `htpasswd` (from `apache2-utils` / `httpd-tools`) when the WebUI is
enabled and authentik ForwardAuth is *not* used
- Traefik with a shared `garage_traefik_network` (default `proxy`)
## Role variables
Full spec with types and defaults: `meta/argument_specs.yml`. The most
common overrides:
### Service
- `garage_s3_domains`: FQDNs the S3 router accepts. The first entry is the
canonical hostname; `garage.toml` derives the virtual-hosted-style S3
`root_domain` from it as `.s3.<first-entry>` (so buckets resolve under
`<bucket>.s3.<first-entry>`).
- `garage_web_domain`, `garage_webui_domain`: separate hostnames for
the S3-website endpoint and the console.
- `garage_image`, `garage_replication_factor`, `garage_db_engine`,
`garage_s3_region`.
### Required secrets
Generate with `openssl rand -hex 32` (32 bytes / 64 hex chars):
- `garage_rpc_secret`: node-to-node RPC secret
- `garage_admin_token`: admin API token
- `garage_metrics_token`: metrics endpoint token
### WebUI authentication
Three modes:
1. **htpasswd** (default): `garage_webui_username` / `garage_webui_password`
in plaintext. The role hashes the password with
`htpasswd -nbBC 10`, persists the hash on disk, and re-verifies with
`htpasswd -vbB` so unchanged passwords don't churn the play.
2. **authentik ForwardAuth**: set
`garage_webui_authentik_forward_auth: true` and
`garage_webui_authentik_forward_auth_url:
"https://auth.example.com/outpost.goauthentik.io/auth/traefik"`.
`AUTH_USER_PASS` is dropped from the container env so authentik is
the only gate.
3. **Disabled**: `garage_webui_enabled: false`.
### Layout bootstrap
Setting `garage_bootstrap_enabled: true` runs the bootstrap task, which
joins the local node to the layout (`zone: garage_bootstrap_zone`,
capacity: `garage_bootstrap_capacity`) on the first run. The check
tolerates the 16-char truncation that `garage layout show` performs.
### Declarative S3 keys and buckets
```yaml
garage_s3_keys:
- name: nextcloud
buckets:
- name: nextcloud-data
permissions: [read, write]
- name: backup
buckets:
- name: restic-prod
permissions: [read, write, owner]
```
The role:
- Lists existing keys (`garage key list`), creates missing ones
- Lists existing buckets (`garage bucket list`), creates missing ones
- Reads current permissions via `garage bucket info` and runs
`garage bucket allow` only when the current RWO flags for the key
don't already match the desired permissions
`stdout` parsing is hardened against ANSI escapes and interleaved INFO
log lines, so probe noise no longer produces spurious changes.
## Dependencies
- Traefik network (`garage_traefik_network`, default `proxy`)
- Internal network (`garage_internal_network`, default `internal`)
## Example playbook
```yaml
- hosts: storage_servers
roles:
- role: digitalboard.core.garage
vars:
garage_s3_domains:
- "storage.example.com"
- "storage.int.example.com"
garage_rpc_secret: "{{ vault_garage_rpc_secret }}"
garage_admin_token: "{{ vault_garage_admin_token }}"
garage_metrics_token: "{{ vault_garage_metrics_token }}"
garage_bootstrap_enabled: true
garage_webui_authentik_forward_auth: true
garage_webui_authentik_forward_auth_url: "https://auth.example.com/outpost.goauthentik.io/auth/traefik"
garage_s3_keys:
- name: nextcloud
buckets:
- name: nextcloud-data
permissions: [read, write]
```
## License
MIT-0