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.
Bundle of cross-role changes for the gymb services deployment:
- Traefik routers: OR-combine opnform/homarr/bookstack Host rules with new
*_extra_domains (internal *.int.* FQDNs for a DMZ reverseproxy), and emit
tls.certresolver only when traefik_cert_mode == acme (drawio, homarr,
opnform, send).
- Split-horizon: bookstack_extra_hosts / opnform_extra_hosts add container
/etc/hosts overrides so containers reach the IdP public FQDN over the LAN.
- bookstack: assert the OIDC issuer resolves concretely (reject "//v2.0"),
allowing non-Entra IdPs that override bookstack_oidc_issuer.
- homarr: derive the bcrypt salt from the password digest so the admin hash
is idempotent — no spurious template changes / container restarts.
- opnform: PATCH an existing OIDC connection instead of skipping (applies
corrected inventory on re-run); add OIDC_FORCE_LOGIN (enabled only after
bootstrap) and an optional direct-SSO ingress entrypoint.
Docs: READMEs and meta/argument_specs.yml updated for all new variables.
47 typed options covering the full defaults file plus the OIDC and
backup-timer subsystems. The three secrets the role asserts on
(db_root_password, db_password, admin_password) are marked
required: true so ansible refuses the play with a clear error before
the validate task even runs.
Loads cleanly through ansible-core's ArgumentSpecValidator with 100%
defaults/spec coverage. Matches the spec convention used by traefik,
authentik, drawio, garage, nextcloud, opnform, coturn, talk and send.
Deploy BookStack with linuxserver.io images behind Traefik, including
Entra ID OIDC SSO support and a daily backup timer.
Stack:
- lscr.io/linuxserver/bookstack:version-v26.03.3
- lscr.io/linuxserver/mariadb:11.4.9
- Traefik labels for websecure entrypoint on internal network
- Healthcheck via mariadb-admin ping (LSIO image lacks healthcheck.sh)
Features:
- Persistent APP_KEY generated on first run, stored in volume dir
- Optional OIDC SSO via Microsoft Entra ID (configurable per-instance)
- Idempotent admin user creation with DB-based existence check
- Daily systemd timer backup (DB dump + uploads tar + APP_KEY)
with configurable retention
Implementation notes:
- DB queries use --protocol=tcp with the app user because root@localhost
uses unix_socket auth in the LSIO MariaDB image (no password) and
root@% does not exist
- docker_container_exec uses argv: (list) instead of command: (string)
to avoid argument-splitting issues
- Migration-wait task ensures users table exists before admin check,
since /login returns 200 before Laravel migrations complete
- no_log: true on all tasks that reference DB or admin passwords
- artisan absolute path (/app/www/artisan) because LSIO image WORKDIR
is not the app directory
Adds bookstack route to DMZ Traefik service registry.