Each of the five roles touched in this branch now ships: * meta/argument_specs.yml: typed schema for every variable in defaults/main.yml plus the optional inputs surfaced via this branch (traefik_extra_hosts, authentik_host_rewrite_domains, authentik_proxy_apps.mode / .allowed_groups, drawio_extra_domains, drawio_authentik_forward_auth*, garage_webui_authentik_forward_auth*). All five specs load cleanly through ansible-core's ArgumentSpecValidator. * README.md: replaces the ansible-galaxy boilerplate (where it was still in place) with a focused write-up — service vars, required secrets, ForwardAuth/idempotency notes, dependencies, and a working example playbook. authentik and garage READMEs are rewritten to cover the new knobs while preserving their existing content.
116 lines
3.7 KiB
Markdown
116 lines
3.7 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. First entry is the
|
|
canonical hostname and is used as `root_domain` in `garage.toml`.
|
|
- `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
|