- authentik: address the rewrite service by compose service name instead of a network alias on the public FQDN, which shadowed extra_hosts pins and broke OIDC discovery for c-ares-based (Node) resolvers - homarr: add homarr_extra_hosts to pin the IdP FQDN to a LAN IP so OIDC discovery stays in-network while the issuer matches the browser-facing URL - opnform: add opnform_oidc_sso_redirect_root to 302 the root URL to the SSO path (deep-links untouched, /login?bypass=1 break-glass); restart ingress via container restart so envsubst re-renders nginx.conf - nextcloud: make the UserConfig sed workaround fail loud on upstream drift instead of silently skipping (nextcloud/server#59629) - gitignore: exclude the local .ansible/ collection cache
275 lines
9.4 KiB
YAML
275 lines
9.4 KiB
YAML
---
|
|
argument_specs:
|
|
main:
|
|
short_description: Deploy OpnForm (api + ui + db + redis + ingress) via Docker Compose.
|
|
description:
|
|
- Renders a Compose stack for the full OpnForm setup (PHP-FPM api,
|
|
Nuxt ui, Postgres, Redis, nginx ingress) and exposes it through
|
|
Traefik.
|
|
- Optionally bootstraps the first admin user via the OpnForm
|
|
C(/api/register) endpoint (skipping the self-hosted setup page)
|
|
and provisions a single OIDC identity connection in the default
|
|
workspace via the workspace API. Both bootstraps are idempotent.
|
|
options:
|
|
docker_compose_base_dir:
|
|
type: path
|
|
default: /etc/docker/compose
|
|
docker_volume_base_dir:
|
|
type: path
|
|
default: /srv/data
|
|
opnform_service_name:
|
|
type: str
|
|
default: opnform
|
|
opnform_docker_compose_dir:
|
|
type: path
|
|
description: Defaults to C({{ docker_compose_base_dir }}/{{ opnform_service_name }}).
|
|
opnform_docker_volume_dir:
|
|
type: path
|
|
description: Defaults to C({{ docker_volume_base_dir }}/{{ opnform_service_name }}).
|
|
opnform_storage_dir:
|
|
type: path
|
|
description: OpnForm storage volume mounted into the api container.
|
|
opnform_db_data_dir:
|
|
type: path
|
|
opnform_redis_data_dir:
|
|
type: path
|
|
|
|
opnform_domain:
|
|
type: str
|
|
default: forms.local.test
|
|
description: Hostname used in the traefik Host rule.
|
|
opnform_extra_domains:
|
|
type: list
|
|
elements: str
|
|
default: []
|
|
description:
|
|
- Additional hostnames the Traefik router answers on, OR-combined
|
|
with C(opnform_domain). Useful for an internal C(*.int.*) FQDN so
|
|
a DMZ reverseproxy can reach a backend hostname covered by the
|
|
cert.
|
|
opnform_extra_hosts:
|
|
type: list
|
|
elements: str
|
|
default: []
|
|
description:
|
|
- Container-level C(/etc/hosts) overrides for the API containers
|
|
(Compose C(extra_hosts) entries, C("host:ip")). Needed in
|
|
split-horizon setups where the OpnForm API must reach the IdP's
|
|
public FQDN (used in the OIDC discovery / C(iss) claim) over the
|
|
LAN rather than hairpinning through a DMZ with no NAT loopback.
|
|
opnform_base_url:
|
|
type: str
|
|
default: https://forms.local.test
|
|
description: Public URL OpnForm uses for APP_URL and NUXT_PUBLIC_APP_URL.
|
|
|
|
opnform_api_image:
|
|
type: str
|
|
default: jhumanj/opnform-api:latest
|
|
opnform_client_image:
|
|
type: str
|
|
default: jhumanj/opnform-client:latest
|
|
opnform_redis_image:
|
|
type: str
|
|
default: "redis:7"
|
|
opnform_db_image:
|
|
type: str
|
|
default: "postgres:16"
|
|
opnform_ingress_image:
|
|
type: str
|
|
default: "nginx:1"
|
|
|
|
opnform_app_key:
|
|
type: str
|
|
required: true
|
|
description:
|
|
- Laravel application key. Must be prefixed with C(base64:).
|
|
Generate with C(echo "base64:$(openssl rand -base64 32)").
|
|
Provide via OpenBao, Ansible Vault or extra-vars.
|
|
opnform_jwt_secret:
|
|
type: str
|
|
required: true
|
|
description: JWT signing secret. Generate with C(openssl rand -hex 32).
|
|
opnform_front_api_secret:
|
|
type: str
|
|
required: true
|
|
description: Shared secret between ui and api. Generate with C(openssl rand -hex 32).
|
|
|
|
opnform_db_name:
|
|
type: str
|
|
default: opnform
|
|
opnform_db_user:
|
|
type: str
|
|
default: opnform
|
|
opnform_db_password:
|
|
type: str
|
|
required: true
|
|
|
|
opnform_admin_name:
|
|
type: str
|
|
default: Administrator
|
|
opnform_admin_email:
|
|
type: str
|
|
default: ''
|
|
description:
|
|
- When non-empty (together with C(opnform_admin_password)) the role
|
|
bootstraps the first user via C(/api/register), skipping the
|
|
self-hosted setup page. Required when C(opnform_oidc_enabled=true).
|
|
opnform_admin_password:
|
|
type: str
|
|
default: ''
|
|
description:
|
|
- "Must satisfy OpnForm's policy: min 8 chars, letter + digit +
|
|
symbol from C(@$!%*#?&-_+=.,:;<>^()[]{}|~)."
|
|
opnform_admin_hear_about_us:
|
|
type: str
|
|
default: ansible
|
|
|
|
opnform_php_memory_limit:
|
|
type: str
|
|
default: 1G
|
|
opnform_php_max_execution_time:
|
|
type: str
|
|
default: "600"
|
|
opnform_php_upload_max_filesize:
|
|
type: str
|
|
default: 64M
|
|
opnform_php_post_max_size:
|
|
type: str
|
|
default: 64M
|
|
opnform_nginx_max_body_size:
|
|
type: str
|
|
default: 64m
|
|
|
|
opnform_mail_mailer:
|
|
type: str
|
|
default: log
|
|
choices: [log, smtp, ses, mailgun, postmark, sendmail]
|
|
opnform_mail_host:
|
|
type: str
|
|
default: ''
|
|
opnform_mail_port:
|
|
type: str
|
|
default: ''
|
|
opnform_mail_username:
|
|
type: str
|
|
default: ''
|
|
opnform_mail_password:
|
|
type: str
|
|
default: ''
|
|
opnform_mail_encryption:
|
|
type: str
|
|
default: ''
|
|
choices: ['', tls, ssl]
|
|
opnform_mail_from_address:
|
|
type: str
|
|
default: noreply@digitalboard.ch
|
|
opnform_mail_from_name:
|
|
type: str
|
|
default: OpnForm
|
|
|
|
opnform_oidc_enabled:
|
|
type: bool
|
|
default: false
|
|
description:
|
|
- "When true the role calls the workspace API to create a single
|
|
OIDC C(identity_connection) on the default workspace after the
|
|
admin bootstrap. Requires C(opnform_admin_email) +
|
|
C(opnform_admin_password) so the role can authenticate.
|
|
Idempotent: skipped when any connection already exists."
|
|
opnform_oidc_issuer:
|
|
type: str
|
|
default: https://auth.digitalboard.ch/realms/Digitalboard
|
|
description: OIDC issuer URL.
|
|
opnform_oidc_client_id:
|
|
type: str
|
|
default: opnform-digitalboard
|
|
opnform_oidc_client_secret:
|
|
type: str
|
|
default: ''
|
|
description: Required when C(opnform_oidc_enabled=true).
|
|
opnform_oidc_client_name:
|
|
type: str
|
|
default: Digitalboard
|
|
description: Display name shown in the OpnForm UI.
|
|
opnform_oidc_slug:
|
|
type: str
|
|
default: oidc
|
|
description:
|
|
- OpnForm-side identifier used in C(/auth/{slug}/callback). Lowercase
|
|
alphanumeric + hyphens, unique across all C(identity_connections).
|
|
opnform_oidc_domain:
|
|
type: str
|
|
default: ''
|
|
description:
|
|
- Email domain that triggers OIDC for matching users. Required
|
|
when C(opnform_oidc_enabled=true).
|
|
opnform_oidc_force_login:
|
|
type: bool
|
|
default: false
|
|
description:
|
|
- "When true, sets C(OIDC_FORCE_LOGIN=true) on the api container:
|
|
password-based login is disabled and every user must authenticate
|
|
via OIDC. Only takes effect when C(opnform_oidc_enabled=true).
|
|
Ensure all real users have addresses under C(opnform_oidc_domain)
|
|
before enabling — there is no password fallback."
|
|
opnform_oidc_scopes:
|
|
type: list
|
|
elements: str
|
|
default: [openid, profile, email, groups]
|
|
opnform_oidc_admin_group:
|
|
type: str
|
|
default: opnform-admins
|
|
description:
|
|
- Convenience setting that maps a single IdP group to the OpnForm
|
|
C(admin) role. Ignored when C(opnform_oidc_group_role_mappings)
|
|
is non-empty.
|
|
opnform_oidc_group_role_mappings:
|
|
type: list
|
|
elements: dict
|
|
default: []
|
|
description:
|
|
- Full IdP-group -> OpnForm-role mapping. Takes precedence over
|
|
C(opnform_oidc_admin_group).
|
|
options:
|
|
idp_group:
|
|
type: str
|
|
required: true
|
|
description: Group name as it appears in the IdP groups claim.
|
|
role:
|
|
type: str
|
|
required: true
|
|
choices: [owner, admin, editor, member]
|
|
opnform_oidc_sso_entrypoint:
|
|
type: bool
|
|
default: false
|
|
description:
|
|
- When true (and C(opnform_oidc_enabled=true)) the nginx ingress
|
|
serves a small redirect page at C(opnform_oidc_sso_path) that
|
|
calls OpnForm's C(/api/auth/{slug}/redirect) endpoint and
|
|
forwards the browser to the returned IdP authorize URL. Lets
|
|
you link users straight to the IdP, skipping OpnForm's
|
|
email-based login form. OpnForm has no native option for this.
|
|
opnform_oidc_sso_path:
|
|
type: str
|
|
default: /sso
|
|
description:
|
|
- Path (on C(opnform_domain)) where the direct-SSO redirect page
|
|
is served when C(opnform_oidc_sso_entrypoint=true). Must start
|
|
with C(/) and not collide with OpnForm's own routes.
|
|
opnform_oidc_sso_redirect_root:
|
|
type: bool
|
|
default: false
|
|
description:
|
|
- When true, the nginx ingress 302-redirects the root URL
|
|
(exact-match on C(/)) to C(opnform_oidc_sso_path), so visiting
|
|
C(https://<domain>/) jumps straight to the IdP without
|
|
OpnForm's email login form. Public form deep-links
|
|
(C(/forms/<slug>), C(/login), C(/admin/...)) are untouched.
|
|
Requires C(opnform_oidc_sso_entrypoint=true).
|
|
|
|
opnform_traefik_network:
|
|
type: str
|
|
default: proxy
|
|
opnform_use_ssl:
|
|
type: bool
|
|
default: true
|