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.
118 lines
3.8 KiB
Markdown
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
|