docs(roles): add argument_specs and README for traefik, authentik, drawio, garage, nextcloud
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.
This commit is contained in:
parent
a9c33baed9
commit
1dcff92240
10 changed files with 1348 additions and 143 deletions
|
|
@ -1,113 +1,116 @@
|
|||
Garage
|
||||
======
|
||||
# Garage
|
||||
|
||||
Ansible role to deploy Garage S3-compatible object storage using Docker Compose.
|
||||
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
|
||||
------------
|
||||
## Requirements
|
||||
|
||||
- Docker and Docker Compose installed on the target host
|
||||
- Ansible collection: `community.docker`
|
||||
- Traefik reverse proxy (for external access)
|
||||
- `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
|
||||
--------------
|
||||
## Role variables
|
||||
|
||||
Key variables defined in `defaults/main.yml`:
|
||||
Full spec with types and defaults: `meta/argument_specs.yml`. The most
|
||||
common overrides:
|
||||
|
||||
**Base Configuration:**
|
||||
- `docker_compose_base_dir`: Base directory for Docker Compose files (default: `/etc/docker/compose`)
|
||||
- `docker_volume_base_dir`: Base directory for Docker volumes (default: `/srv/data`)
|
||||
### Service
|
||||
|
||||
**Garage Configuration:**
|
||||
- `garage_service_name`: Service name (default: `garage`)
|
||||
- `garage_image`: Garage Docker image (default: `dxflrs/garage:v2.1.0`)
|
||||
- `garage_s3_domain`: Domain for S3 API endpoint (default: `storage.local.test`)
|
||||
- `garage_web_domain`: Domain for S3 web endpoint (default: `web.storage.local.test`)
|
||||
- `garage_webui_domain`: Domain for web console (default: `console.storage.local.test`)
|
||||
- `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`.
|
||||
|
||||
**Garage Storage Configuration:**
|
||||
- `garage_replication_factor`: Replication factor (default: `1`)
|
||||
- `garage_compression_level`: Compression level (default: `1`)
|
||||
- `garage_db_engine`: Database engine (default: `lmdb`)
|
||||
- `garage_s3_region`: S3 region (default: `us-east-1`)
|
||||
### Required secrets
|
||||
|
||||
**Garage Ports:**
|
||||
- `garage_s3_api_port`: S3 API port (default: `3900`)
|
||||
- `garage_s3_web_port`: S3 web port (default: `3902`)
|
||||
- `garage_admin_port`: Admin API port (default: `3903`)
|
||||
- `garage_rpc_port`: RPC port (default: `3901`)
|
||||
Generate with `openssl rand -hex 32` (32 bytes / 64 hex chars):
|
||||
|
||||
**Garage Security:**
|
||||
- `garage_rpc_secret`: RPC secret for node communication
|
||||
- `garage_admin_token`: Admin API token
|
||||
- `garage_metrics_token`: Metrics API token
|
||||
- `garage_rpc_secret`: node-to-node RPC secret
|
||||
- `garage_admin_token`: admin API token
|
||||
- `garage_metrics_token`: metrics endpoint token
|
||||
|
||||
**Garage WebUI Configuration:**
|
||||
- `garage_webui_enabled`: Enable web UI (default: `true`)
|
||||
- `garage_webui_image`: WebUI Docker image (default: `khairul169/garage-webui:latest`)
|
||||
- `garage_webui_port`: WebUI port (default: `3909`)
|
||||
- `garage_webui_username`: WebUI username (default: `admin`)
|
||||
- `garage_webui_password`: WebUI password in plaintext (default: `admin`)
|
||||
### WebUI authentication
|
||||
|
||||
**Traefik Configuration:**
|
||||
- `garage_traefik_network`: Traefik network name (default: `proxy`)
|
||||
- `garage_internal_network`: Internal network name (default: `internal`)
|
||||
- `garage_use_ssl`: Enable SSL (default: `true`)
|
||||
Three modes:
|
||||
|
||||
Dependencies
|
||||
------------
|
||||
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`.
|
||||
|
||||
This role requires:
|
||||
- Traefik reverse proxy to be configured and the `proxy` network to be created
|
||||
- `htpasswd` utility (from `apache2-utils` package) for generating bcrypt password hashes
|
||||
### Layout bootstrap
|
||||
|
||||
Example Playbook
|
||||
----------------
|
||||
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: garage
|
||||
- role: digitalboard.core.garage
|
||||
vars:
|
||||
garage_s3_domain: "storage.example.com"
|
||||
garage_rpc_secret: "your-secure-rpc-secret"
|
||||
garage_admin_token: "your-admin-token"
|
||||
garage_webui_enabled: true
|
||||
garage_webui_username: "admin"
|
||||
garage_webui_password: "secure-password"
|
||||
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]
|
||||
```
|
||||
|
||||
**Note:** The WebUI password is specified in plaintext and will be automatically hashed using bcrypt during deployment. The role uses `htpasswd` to generate a secure bcrypt hash that is then properly escaped for use in Docker Compose.
|
||||
## License
|
||||
|
||||
Post-Installation
|
||||
-----------------
|
||||
|
||||
After deployment, you need to configure the Garage cluster:
|
||||
|
||||
1. Connect to the node and get the node ID:
|
||||
```bash
|
||||
docker exec -ti garage /garage node id
|
||||
```
|
||||
|
||||
2. Configure the node layout:
|
||||
```bash
|
||||
docker exec -ti garage /garage layout assign -z dc1 -c 1G <node-id>
|
||||
docker exec -ti garage /garage layout apply --version 1
|
||||
```
|
||||
|
||||
3. Create a key for S3 access:
|
||||
```bash
|
||||
docker exec -ti garage /garage key create my-key
|
||||
```
|
||||
|
||||
4. Create a bucket:
|
||||
```bash
|
||||
docker exec -ti garage /garage bucket create my-bucket
|
||||
docker exec -ti garage /garage bucket allow my-bucket --read --write --key my-key
|
||||
```
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
MIT-0
|
||||
MIT-0
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue