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.
3.8 KiB
Garage
Ansible role to deploy Garage 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(fromapache2-utils/httpd-tools) when the WebUI is enabled and authentik ForwardAuth is not used- Traefik with a shared
garage_traefik_network(defaultproxy)
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.tomlderives the virtual-hosted-style S3root_domainfrom 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 secretgarage_admin_token: admin API tokengarage_metrics_token: metrics endpoint token
WebUI authentication
Three modes:
- htpasswd (default):
garage_webui_username/garage_webui_passwordin plaintext. The role hashes the password withhtpasswd -nbBC 10, persists the hash on disk, and re-verifies withhtpasswd -vbBso unchanged passwords don't churn the play. - authentik ForwardAuth: set
garage_webui_authentik_forward_auth: trueandgarage_webui_authentik_forward_auth_url: "https://auth.example.com/outpost.goauthentik.io/auth/traefik".AUTH_USER_PASSis dropped from the container env so authentik is the only gate. - 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
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 infoand runsgarage bucket allowonly 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, defaultproxy) - Internal network (
garage_internal_network, defaultinternal)
Example playbook
- 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