--- 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:///) jumps straight to the IdP without OpnForm's email login form. Public form deep-links (C(/forms/), 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