feat(opnform)!: add admin and OIDC bootstrap, rename role to lowercase
Rename roles/OpnForm → roles/opnform so the role resolves as
digitalboard.core.opnform (Ansible collection convention is
lowercase). Update tests/test.yml reference accordingly.
Add automated admin user creation via POST /api/register, gated on
opnform_admin_email + opnform_admin_password. Idempotent through a
prior login probe. Without these vars the manual setup page flow is
preserved.
Add automated OIDC IdentityConnection setup via the per-workspace
/api/open/workspaces/{id}/oidc-connections endpoint, gated on
opnform_oidc_enabled. Hard-coupled to the admin bootstrap (the API
requires an authenticated admin token); validation block fails fast
if OIDC is enabled without admin credentials. Supports both an
explicit opnform_oidc_group_role_mappings list and a fallback
opnform_oidc_admin_group convenience var.
Convert opnform_oidc_scopes from space-separated string to YAML list
to match OpnForm's API expectation. Rewrite README "First login" and
"OIDC setup" sections to reflect that self-hosted OpnForm does not
ship a pre-seeded admin and to document the new bootstrap paths.
BREAKING CHANGE: opnform_oidc_scopes changed from space-separated
string to YAML list. Inventories that override it must update from
"openid profile email" to [openid, profile, email].
This commit is contained in:
parent
eb51b6a054
commit
256a82df1f
11 changed files with 366 additions and 145 deletions
|
|
@ -1,117 +0,0 @@
|
|||
#SPDX-License-Identifier: MIT-0
|
||||
---
|
||||
# tasks file for opnform
|
||||
|
||||
# =====================================================================
|
||||
# 0. VALIDATION
|
||||
# =====================================================================
|
||||
|
||||
- name: Validate required secrets
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- opnform_app_key | length > 0
|
||||
- opnform_app_key is match('^base64:[A-Za-z0-9+/=]+$')
|
||||
- opnform_jwt_secret | length > 0
|
||||
- opnform_front_api_secret | length > 0
|
||||
- opnform_db_password | length > 0
|
||||
fail_msg: >-
|
||||
OpnForm requires opnform_app_key (prefix 'base64:'), opnform_jwt_secret,
|
||||
opnform_front_api_secret and opnform_db_password.
|
||||
Generate with: openssl rand -base64 32
|
||||
The app_key MUST be prefixed with "base64:"
|
||||
Provide via OpenBao, Ansible Vault or extra-vars.
|
||||
success_msg: Secrets validation passed
|
||||
|
||||
- name: Validate OIDC configuration when enabled
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- opnform_oidc_client_secret | length > 0
|
||||
fail_msg: >-
|
||||
opnform_oidc_client_secret must be set when opnform_oidc_enabled is true.
|
||||
when: opnform_oidc_enabled | bool
|
||||
|
||||
# =====================================================================
|
||||
# 1. PREPARATION
|
||||
# =====================================================================
|
||||
|
||||
- name: Ensure required packages are installed
|
||||
ansible.builtin.package:
|
||||
name:
|
||||
- python3-docker
|
||||
state: present
|
||||
|
||||
- name: Create docker compose directory
|
||||
ansible.builtin.file:
|
||||
path: "{{ opnform_docker_compose_dir }}"
|
||||
state: directory
|
||||
mode: '0755'
|
||||
|
||||
- name: Create OpnForm data directories
|
||||
ansible.builtin.file:
|
||||
path: "{{ item }}"
|
||||
state: directory
|
||||
mode: "0755"
|
||||
loop:
|
||||
- "{{ opnform_docker_volume_dir }}"
|
||||
- "{{ opnform_storage_dir }}"
|
||||
- "{{ opnform_db_data_dir }}"
|
||||
- "{{ opnform_redis_data_dir }}"
|
||||
|
||||
# =====================================================================
|
||||
# 2. CONFIGURATION FILES
|
||||
# =====================================================================
|
||||
|
||||
- name: Deploy nginx ingress configuration
|
||||
ansible.builtin.template:
|
||||
src: nginx.conf.j2
|
||||
dest: "{{ opnform_docker_compose_dir }}/nginx.conf"
|
||||
mode: '0644'
|
||||
notify: restart opnform
|
||||
|
||||
- name: Deploy docker-compose file
|
||||
ansible.builtin.template:
|
||||
src: docker-compose.yml.j2
|
||||
dest: "{{ opnform_docker_compose_dir }}/docker-compose.yml"
|
||||
mode: '0644'
|
||||
notify: restart opnform
|
||||
|
||||
# =====================================================================
|
||||
# 3. CONTAINER STARTUP
|
||||
# =====================================================================
|
||||
|
||||
- name: Start opnform containers
|
||||
community.docker.docker_compose_v2:
|
||||
project_src: "{{ opnform_docker_compose_dir }}"
|
||||
state: present
|
||||
wait: true
|
||||
wait_timeout: 180
|
||||
|
||||
# =====================================================================
|
||||
# 4. WAIT FOR API READINESS
|
||||
# =====================================================================
|
||||
|
||||
- name: Wait for API container to be healthy
|
||||
ansible.builtin.command:
|
||||
cmd: docker inspect --format='{% raw %}{{.State.Health.Status}}{% endraw %}' opnform-api
|
||||
register: api_health
|
||||
until: api_health.stdout == "healthy"
|
||||
retries: 30
|
||||
delay: 10
|
||||
changed_when: false
|
||||
|
||||
- name: Display deployment info
|
||||
ansible.builtin.debug:
|
||||
msg: |-
|
||||
OpnForm deployed at {{ opnform_base_url }}
|
||||
|
||||
Default credentials (from API container logs on first start):
|
||||
Email: admin@opnform.com
|
||||
Password: password
|
||||
|
||||
On first login you will be prompted to change email and password.
|
||||
|
||||
If login does not respond, the DB seed may have failed. Run:
|
||||
docker compose -f {{ opnform_docker_compose_dir }}/docker-compose.yml exec api php artisan migrate:refresh --seed
|
||||
docker compose -f {{ opnform_docker_compose_dir }}/docker-compose.yml exec api php artisan app:init-project
|
||||
|
||||
OIDC: {% if opnform_oidc_enabled %}enabled (configure via Admin UI){% else %}disabled{% endif %}
|
||||
|
|
@ -13,7 +13,6 @@ Docker Compose stack behind Traefik.
|
|||
|
||||
## What this role does NOT do (stage 1)
|
||||
|
||||
- Does not pre-create an admin user (use the default credentials below)
|
||||
- Does not pre-configure OIDC / identity_connections — set up via Admin UI
|
||||
|
||||
## Architecture note: why two reverse proxies?
|
||||
|
|
@ -61,39 +60,83 @@ missing or malformed.
|
|||
|
||||
## First login
|
||||
|
||||
After the role completes, OpnForm seeds a default admin user. Visit
|
||||
the URL in `opnform_base_url` and log in with:
|
||||
OpnForm in self-hosted mode does **not** ship a pre-seeded admin user.
|
||||
The first user to register becomes the owner of the default workspace,
|
||||
and further public registration is disabled afterwards (additional
|
||||
users must be invited via the Admin UI).
|
||||
|
||||
- Email: `admin@opnform.com`
|
||||
- Password: `password`
|
||||
This role supports two ways to create that first user:
|
||||
|
||||
On first login OpnForm will prompt you to change email and password.
|
||||
Self-hosted instances disable public registration after this — invite
|
||||
further users via the Admin UI.
|
||||
### Option A — automated bootstrap (recommended)
|
||||
|
||||
### If the login does not respond
|
||||
Set `opnform_admin_email` and `opnform_admin_password` (ideally from
|
||||
Vault / OpenBao). The role then POSTs to `/api/register` after the
|
||||
API container is healthy, skipping the setup page entirely. The task
|
||||
is idempotent: it does a login check first and only registers if the
|
||||
user does not already exist.
|
||||
|
||||
The DB seed may have failed. Re-run it manually:
|
||||
|
||||
```bash
|
||||
cd /etc/docker/compose/opnform
|
||||
docker compose exec api php artisan migrate:refresh --seed
|
||||
docker compose exec api php artisan app:init-project
|
||||
```yaml
|
||||
opnform_admin_name: "Administrator" # default
|
||||
opnform_admin_email: "admin@example.com"
|
||||
opnform_admin_password: "{{ vault_opnform_admin_password }}"
|
||||
```
|
||||
|
||||
## OIDC setup (stage 2, not yet automated)
|
||||
Password rules enforced by OpnForm: minimum 8 characters, at least one
|
||||
letter, one digit, and one of `@$!%*#?&-_+=.,:;<>^()[]{}|~`.
|
||||
|
||||
Manual setup via the Admin UI is currently the supported path:
|
||||
### Option B — manual setup page
|
||||
|
||||
1. Settings → Identity Connections → Add Connection
|
||||
2. Provider: OIDC
|
||||
3. Issuer: `https://auth.digitalboard.ch/realms/Digitalboard`
|
||||
4. Client ID / Secret: from your Keycloak client
|
||||
5. Add Group Role Mapping: Entra/Keycloak group Object ID → OpnForm role
|
||||
Leave `opnform_admin_email` / `opnform_admin_password` empty. Visit
|
||||
`opnform_base_url` and complete the setup page in the browser.
|
||||
|
||||
Direct DB manipulation of `identity_connections` / `group_role_mappings`
|
||||
is possible but fragile across OpnForm versions. A future iteration of
|
||||
this role may automate it.
|
||||
## OIDC setup
|
||||
|
||||
Set `opnform_oidc_enabled: true` and the role creates an
|
||||
IdentityConnection on the admin's default workspace via
|
||||
`POST /api/open/workspaces/{id}/oidc-connections`. OpnForm enforces a
|
||||
single OIDC connection per workspace, so the task is idempotent (GETs
|
||||
existing connections first and skips if any exist).
|
||||
|
||||
**Prerequisite**: the admin bootstrap must be configured
|
||||
(`opnform_admin_email` + `opnform_admin_password`). The OIDC API
|
||||
requires an authenticated admin token; the role logs in with those
|
||||
credentials to make the call. The validation block fails fast if OIDC
|
||||
is enabled without admin credentials.
|
||||
|
||||
### Required when `opnform_oidc_enabled: true`
|
||||
|
||||
| Variable | Notes |
|
||||
|---|---|
|
||||
| `opnform_oidc_client_secret` | from your IdP, never commit |
|
||||
| `opnform_oidc_domain` | email domain that triggers OIDC (e.g. `example.com`) |
|
||||
|
||||
### Tunables (defaults shown)
|
||||
|
||||
```yaml
|
||||
opnform_oidc_issuer: "https://auth.digitalboard.ch/realms/Digitalboard"
|
||||
opnform_oidc_client_id: "opnform-digitalboard"
|
||||
opnform_oidc_client_name: "Digitalboard" # display name in UI
|
||||
opnform_oidc_slug: "oidc" # used in /auth/{slug}/callback
|
||||
opnform_oidc_scopes: [openid, profile, email, groups]
|
||||
```
|
||||
|
||||
### Group → role mapping
|
||||
|
||||
Two ways, the list takes precedence:
|
||||
|
||||
```yaml
|
||||
# Option 1: full list (any number of mappings)
|
||||
opnform_oidc_group_role_mappings:
|
||||
- idp_group: "opnform-admins"
|
||||
role: admin
|
||||
- idp_group: "opnform-editors"
|
||||
role: editor
|
||||
|
||||
# Option 2: convenience — single admin group
|
||||
opnform_oidc_admin_group: "opnform-admins" # mapped to role=admin
|
||||
```
|
||||
|
||||
Valid roles: `owner`, `admin`, `editor`, `member`.
|
||||
|
||||
## Example playbook
|
||||
|
||||
|
|
@ -38,6 +38,17 @@ opnform_db_name: "opnform"
|
|||
opnform_db_user: "opnform"
|
||||
opnform_db_password: "xtNLUVc2ajcWictqWXWkLR"
|
||||
|
||||
# Admin bootstrap — when email+password are set, the role creates the
|
||||
# first user via OpnForm's /api/register endpoint, skipping the
|
||||
# self-hosted setup page. Leave both empty to keep the manual setup flow.
|
||||
# Password must satisfy OpnForm's rules: min 8 chars, contain a letter,
|
||||
# a digit and one of @$!%*#?&-_+=.,:;<>^()[]{}|~
|
||||
# Provide via OpenBao, Ansible Vault or extra-vars.
|
||||
opnform_admin_name: "Administrator"
|
||||
opnform_admin_email: ""
|
||||
opnform_admin_password: ""
|
||||
opnform_admin_hear_about_us: "ansible"
|
||||
|
||||
# PHP configuration
|
||||
opnform_php_memory_limit: "1G"
|
||||
opnform_php_max_execution_time: "600"
|
||||
|
|
@ -57,14 +68,33 @@ opnform_mail_encryption: ""
|
|||
opnform_mail_from_address: "noreply@digitalboard.ch"
|
||||
opnform_mail_from_name: "OpnForm"
|
||||
|
||||
# OIDC configuration (Stage 1: not auto-configured, set up via UI after deploy)
|
||||
# OIDC configuration — when enabled, the role auto-creates an
|
||||
# IdentityConnection in the first workspace via OpnForm's API after the
|
||||
# admin bootstrap. Requires opnform_admin_email/_password to be set
|
||||
# (the API call needs an authenticated admin token).
|
||||
opnform_oidc_enabled: false
|
||||
opnform_oidc_issuer: "https://auth.digitalboard.ch/realms/Digitalboard"
|
||||
opnform_oidc_client_id: "opnform-digitalboard"
|
||||
opnform_oidc_client_secret: ""
|
||||
opnform_oidc_client_name: "Digitalboard"
|
||||
opnform_oidc_scopes: "openid profile email groups"
|
||||
# OpnForm-side identifier used in /auth/{slug}/callback. Lowercase
|
||||
# alphanumeric + hyphens, unique across all identity_connections.
|
||||
opnform_oidc_slug: "oidc"
|
||||
# Email domain that triggers OIDC login for matching users (e.g. users
|
||||
# with @example.com emails are redirected to the IdP). Required when
|
||||
# opnform_oidc_enabled is true.
|
||||
opnform_oidc_domain: ""
|
||||
opnform_oidc_scopes:
|
||||
- openid
|
||||
- profile
|
||||
- email
|
||||
- groups
|
||||
# Convenience: maps a single IdP group to the OpnForm "admin" role.
|
||||
# Ignored when opnform_oidc_group_role_mappings is non-empty.
|
||||
opnform_oidc_admin_group: "opnform-admins"
|
||||
# Full group-to-role mapping list. Takes precedence over the convenience
|
||||
# var. Each item: {idp_group: "<group name>", role: "owner|admin|editor|member"}
|
||||
opnform_oidc_group_role_mappings: []
|
||||
|
||||
# Traefik configuration
|
||||
opnform_traefik_network: "proxy"
|
||||
265
roles/opnform/tasks/main.yml
Normal file
265
roles/opnform/tasks/main.yml
Normal file
|
|
@ -0,0 +1,265 @@
|
|||
#SPDX-License-Identifier: MIT-0
|
||||
---
|
||||
# tasks file for opnform
|
||||
|
||||
# =====================================================================
|
||||
# 0. VALIDATION
|
||||
# =====================================================================
|
||||
|
||||
- name: Validate required secrets
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- opnform_app_key | length > 0
|
||||
- opnform_app_key is match('^base64:[A-Za-z0-9+/=]+$')
|
||||
- opnform_jwt_secret | length > 0
|
||||
- opnform_front_api_secret | length > 0
|
||||
- opnform_db_password | length > 0
|
||||
fail_msg: >-
|
||||
OpnForm requires opnform_app_key (prefix 'base64:'), opnform_jwt_secret,
|
||||
opnform_front_api_secret and opnform_db_password.
|
||||
Generate with: openssl rand -base64 32
|
||||
The app_key MUST be prefixed with "base64:"
|
||||
Provide via OpenBao, Ansible Vault or extra-vars.
|
||||
success_msg: Secrets validation passed
|
||||
|
||||
- name: Validate OIDC configuration when enabled
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- opnform_oidc_client_secret | length > 0
|
||||
- opnform_oidc_domain | length > 0
|
||||
- opnform_admin_email | length > 0
|
||||
- opnform_admin_password | length > 0
|
||||
fail_msg: >-
|
||||
When opnform_oidc_enabled is true, you must set:
|
||||
- opnform_oidc_client_secret
|
||||
- opnform_oidc_domain (email domain that triggers OIDC)
|
||||
- opnform_admin_email / opnform_admin_password
|
||||
(the OIDC API requires an authenticated admin; the role logs in
|
||||
with these credentials to POST the connection)
|
||||
when: opnform_oidc_enabled | bool
|
||||
|
||||
# =====================================================================
|
||||
# 1. PREPARATION
|
||||
# =====================================================================
|
||||
|
||||
- name: Ensure required packages are installed
|
||||
ansible.builtin.package:
|
||||
name:
|
||||
- python3-docker
|
||||
state: present
|
||||
|
||||
- name: Create docker compose directory
|
||||
ansible.builtin.file:
|
||||
path: "{{ opnform_docker_compose_dir }}"
|
||||
state: directory
|
||||
mode: '0755'
|
||||
|
||||
- name: Create OpnForm data directories
|
||||
ansible.builtin.file:
|
||||
path: "{{ item }}"
|
||||
state: directory
|
||||
mode: "0755"
|
||||
loop:
|
||||
- "{{ opnform_docker_volume_dir }}"
|
||||
- "{{ opnform_storage_dir }}"
|
||||
- "{{ opnform_db_data_dir }}"
|
||||
- "{{ opnform_redis_data_dir }}"
|
||||
|
||||
# =====================================================================
|
||||
# 2. CONFIGURATION FILES
|
||||
# =====================================================================
|
||||
|
||||
- name: Deploy nginx ingress configuration
|
||||
ansible.builtin.template:
|
||||
src: nginx.conf.j2
|
||||
dest: "{{ opnform_docker_compose_dir }}/nginx.conf"
|
||||
mode: '0644'
|
||||
notify: restart opnform
|
||||
|
||||
- name: Deploy docker-compose file
|
||||
ansible.builtin.template:
|
||||
src: docker-compose.yml.j2
|
||||
dest: "{{ opnform_docker_compose_dir }}/docker-compose.yml"
|
||||
mode: '0644'
|
||||
notify: restart opnform
|
||||
|
||||
# =====================================================================
|
||||
# 3. CONTAINER STARTUP
|
||||
# =====================================================================
|
||||
|
||||
- name: Start opnform containers
|
||||
community.docker.docker_compose_v2:
|
||||
project_src: "{{ opnform_docker_compose_dir }}"
|
||||
state: present
|
||||
wait: true
|
||||
wait_timeout: 180
|
||||
|
||||
# =====================================================================
|
||||
# 4. WAIT FOR API READINESS
|
||||
# =====================================================================
|
||||
|
||||
- name: Wait for API container to be healthy
|
||||
ansible.builtin.command:
|
||||
cmd: docker inspect --format='{% raw %}{{.State.Health.Status}}{% endraw %}' opnform-api
|
||||
register: api_health
|
||||
until: api_health.stdout == "healthy"
|
||||
retries: 30
|
||||
delay: 10
|
||||
changed_when: false
|
||||
|
||||
# =====================================================================
|
||||
# 5. ADMIN BOOTSTRAP (optional)
|
||||
# =====================================================================
|
||||
# Skips the self-hosted setup page by registering the first user via
|
||||
# OpnForm's /api/register endpoint. Idempotent: a successful login
|
||||
# attempt with the same credentials means the user already exists.
|
||||
|
||||
- name: Check if OpnForm admin user already exists
|
||||
ansible.builtin.uri:
|
||||
url: "https://127.0.0.1/api/login"
|
||||
method: POST
|
||||
headers:
|
||||
Host: "{{ opnform_domain }}"
|
||||
body_format: json
|
||||
body:
|
||||
email: "{{ opnform_admin_email }}"
|
||||
password: "{{ opnform_admin_password }}"
|
||||
status_code: [200, 401, 422]
|
||||
validate_certs: false
|
||||
register: opnform_admin_login
|
||||
when:
|
||||
- opnform_admin_email | length > 0
|
||||
- opnform_admin_password | length > 0
|
||||
|
||||
- name: Create OpnForm admin user via /api/register
|
||||
ansible.builtin.uri:
|
||||
url: "https://127.0.0.1/api/register"
|
||||
method: POST
|
||||
headers:
|
||||
Host: "{{ opnform_domain }}"
|
||||
body_format: json
|
||||
body:
|
||||
name: "{{ opnform_admin_name }}"
|
||||
email: "{{ opnform_admin_email }}"
|
||||
password: "{{ opnform_admin_password }}"
|
||||
password_confirmation: "{{ opnform_admin_password }}"
|
||||
hear_about_us: "{{ opnform_admin_hear_about_us }}"
|
||||
status_code: [200, 201]
|
||||
validate_certs: false
|
||||
no_log: true
|
||||
when:
|
||||
- opnform_admin_email | length > 0
|
||||
- opnform_admin_password | length > 0
|
||||
- opnform_admin_login.status != 200
|
||||
|
||||
# =====================================================================
|
||||
# 6. OIDC IDENTITY CONNECTION (optional)
|
||||
# =====================================================================
|
||||
# Creates a single OIDC connection on the admin's default workspace.
|
||||
# OpnForm enforces one OIDC connection per workspace, so this block is
|
||||
# idempotent: we GET existing connections first and skip if any exists.
|
||||
|
||||
- name: Log in as admin to obtain OIDC API token
|
||||
ansible.builtin.uri:
|
||||
url: "https://127.0.0.1/api/login"
|
||||
method: POST
|
||||
headers:
|
||||
Host: "{{ opnform_domain }}"
|
||||
body_format: json
|
||||
body:
|
||||
email: "{{ opnform_admin_email }}"
|
||||
password: "{{ opnform_admin_password }}"
|
||||
status_code: 200
|
||||
validate_certs: false
|
||||
register: opnform_oidc_token
|
||||
no_log: true
|
||||
when: opnform_oidc_enabled | bool
|
||||
|
||||
- name: Fetch admin's workspaces
|
||||
ansible.builtin.uri:
|
||||
url: "https://127.0.0.1/api/open/workspaces"
|
||||
method: GET
|
||||
headers:
|
||||
Host: "{{ opnform_domain }}"
|
||||
Authorization: "Bearer {{ opnform_oidc_token.json.token }}"
|
||||
status_code: 200
|
||||
validate_certs: false
|
||||
register: opnform_workspaces
|
||||
no_log: true
|
||||
when: opnform_oidc_enabled | bool
|
||||
|
||||
- name: Fetch existing OIDC connections for the default workspace
|
||||
ansible.builtin.uri:
|
||||
url: "https://127.0.0.1/api/open/workspaces/{{ opnform_workspaces.json[0].id }}/oidc-connections"
|
||||
method: GET
|
||||
headers:
|
||||
Host: "{{ opnform_domain }}"
|
||||
Authorization: "Bearer {{ opnform_oidc_token.json.token }}"
|
||||
status_code: 200
|
||||
validate_certs: false
|
||||
register: opnform_existing_oidc
|
||||
no_log: true
|
||||
when: opnform_oidc_enabled | bool
|
||||
|
||||
- name: Resolve OIDC group-role mappings
|
||||
ansible.builtin.set_fact:
|
||||
_opnform_oidc_group_role_mappings: >-
|
||||
{{
|
||||
opnform_oidc_group_role_mappings
|
||||
if (opnform_oidc_group_role_mappings | length > 0)
|
||||
else
|
||||
([{'idp_group': opnform_oidc_admin_group, 'role': 'admin'}]
|
||||
if (opnform_oidc_admin_group | length > 0) else [])
|
||||
}}
|
||||
when: opnform_oidc_enabled | bool
|
||||
|
||||
- name: Create OIDC identity connection
|
||||
ansible.builtin.uri:
|
||||
url: "https://127.0.0.1/api/open/workspaces/{{ opnform_workspaces.json[0].id }}/oidc-connections"
|
||||
method: POST
|
||||
headers:
|
||||
Host: "{{ opnform_domain }}"
|
||||
Authorization: "Bearer {{ opnform_oidc_token.json.token }}"
|
||||
body_format: json
|
||||
body:
|
||||
name: "{{ opnform_oidc_client_name }}"
|
||||
slug: "{{ opnform_oidc_slug }}"
|
||||
domain: "{{ opnform_oidc_domain }}"
|
||||
issuer: "{{ opnform_oidc_issuer }}"
|
||||
client_id: "{{ opnform_oidc_client_id }}"
|
||||
client_secret: "{{ opnform_oidc_client_secret }}"
|
||||
scopes: "{{ opnform_oidc_scopes }}"
|
||||
enabled: true
|
||||
options:
|
||||
require_state: true
|
||||
group_role_mappings: "{{ _opnform_oidc_group_role_mappings }}"
|
||||
status_code: [201]
|
||||
validate_certs: false
|
||||
no_log: true
|
||||
when:
|
||||
- opnform_oidc_enabled | bool
|
||||
- opnform_existing_oidc.json | length == 0
|
||||
|
||||
- name: Display deployment info
|
||||
ansible.builtin.debug:
|
||||
msg: |-
|
||||
OpnForm deployed at {{ opnform_base_url }}
|
||||
|
||||
{% if opnform_admin_email | length > 0 %}
|
||||
Admin user bootstrapped:
|
||||
Email: {{ opnform_admin_email }}
|
||||
Password: (from opnform_admin_password)
|
||||
{% else %}
|
||||
No admin bootstrap configured — visit {{ opnform_base_url }} and
|
||||
complete the self-hosted setup page to create the first user.
|
||||
Set opnform_admin_email + opnform_admin_password to automate this.
|
||||
{% endif %}
|
||||
|
||||
{% if opnform_oidc_enabled %}
|
||||
OIDC: connection "{{ opnform_oidc_client_name }}" bootstrapped
|
||||
(slug: {{ opnform_oidc_slug }}, domain: {{ opnform_oidc_domain }})
|
||||
Users with @{{ opnform_oidc_domain }} addresses will be
|
||||
redirected to {{ opnform_oidc_issuer }} on login.
|
||||
{% else %}
|
||||
OIDC: disabled (set opnform_oidc_enabled=true to auto-configure)
|
||||
{% endif %}
|
||||
|
|
@ -3,4 +3,4 @@
|
|||
- hosts: localhost
|
||||
remote_user: root
|
||||
roles:
|
||||
- OpnForm
|
||||
- opnform
|
||||
Loading…
Add table
Add a link
Reference in a new issue