Adds k3s and ess_pro roles to replace the planned Nextcloud Talk stack. Integrates with existing Keycloak (OIDC), Garage (S3 media) and OpenBao (secrets). Hostnames under digitalboard.ch.
8.8 KiB
Ansible Role: ess_pro
Deploys Element Server Suite Pro on a single-node K3s cluster, using the
official oci://registry.element.io/matrix-stack Helm chart.
Follows the conventions of the other digitalboard.core roles
(bookstack, opnform, homarr): the role itself is secrets-agnostic;
sensitive values are supplied via group_vars/ess_servers.yml as
community.hashi_vault lookups against OpenBao.
Replaces the previously-planned coturn + nextcloud-talk-hpb
(spreed-signaling + Janus) stack with a fully-fledged Matrix backend
(Synapse Pro, MAS, Element Web, Element Admin, Element Call / LiveKit).
Hostnames
| Component | Default hostname |
|---|---|
Matrix serverName |
digitalboard.ch |
| Synapse | matrix.digitalboard.ch |
| MAS | mas.digitalboard.ch |
| Element Web | chat.digitalboard.ch |
| Element Admin Panel | admin.digitalboard.ch |
| Matrix RTC / LiveKit | rtc.digitalboard.ch |
.well-known apex |
digitalboard.ch |
Note: MAS uses mas.* because auth.digitalboard.ch is already owned
by Keycloak in the reference infrastructure. Override the whole map via
ess_pro_hostnames if needed (e.g. for wksbern.ch).
Architecture
┌────────────────────────────────────────────┐
Internet ──HTTPS──▶│ DMZ Traefik (reference-ansible) │
│ chat.* mas.* matrix.* admin.* rtc.* │
└───────────────────┬─────────────────────────┘
│ HTTP (TLS terminated)
▼
┌────────────────────────────────────────────┐
│ ess host (Debian bookworm + K3s) │
│ ┌──────────────────────────────────────┐ │
│ │ ess namespace │ │
│ │ • synapse-pro │ │
│ │ • matrix-authentication-service │ │
│ │ • element-web │ │
│ │ • element-admin │ │
│ │ • matrix-rtc (lk-jwt + LiveKit SFU) │ │
│ │ • haproxy / well-known │ │
│ └──────────────────────────────────────┘ │
└────────────────────────────────────────────┘
│ UDP 50000–60000
▼
LiveKit ICE candidates
Integration with the existing reference-ansible stack:
- DMZ Traefik terminates TLS, forwards HTTP to the K3s node.
- Keycloak on
auth.digitalboard.ch(RealmDigitalboard) is MAS' upstream OIDC provider — same SSO story as bookstack/opnform/homarr. - Garage (S3-compatible) hosts the Synapse media store via the
ess-mediabucket. - OpenBao on the same path layout (
kv/digitalboard/<service>). - Cluster lives on the same VM that was previously planned for coturn/HPB, because it has the right DMZ NAT topology for SFU UDP.
Prerequisites
-
Ansible collections on the control node:
ansible-galaxy collection install \ kubernetes.core community.general community.hashi_vault pip install kubernetes pyyaml hvac -
ESS Pro subscription credentials in OpenBao at
kv/digitalboard/ess-pro(KV v2, flat keys):bao kv put kv/digitalboard/ess-pro \ username='ess-customer-xxx' \ token='paste-from-customer.element.io' \ client_secret='from-keycloak' \ s3_access_key='...' \ s3_secret_key='...'See
examples/openbao-bootstrap.shfor an interactive helper. -
Keycloak OIDC client
ess-masin theDigitalboardrealm with redirect URIhttps://mas.digitalboard.ch/upstream/callback/01J0KCK0DNNNDIGITALBOARDKC01. -
Garage bucket
ess-mediawith a dedicated access key. -
DNS A/AAAA records for
matrix.,mas.,chat.,admin.,rtc.and the apexdigitalboard.ch, pointing at the DMZ Traefik. -
DMZ firewall NAT-forwards UDP
50000-60000(configurable) and TCP7881to the K3s node — LiveKit's media ports.
Required variables
| Variable | Notes |
|---|---|
ess_pro_registry_username |
OpenBao lookup — see example |
ess_pro_registry_token |
OpenBao lookup |
ess_pro_oidc_client_secret |
OpenBao lookup (when OIDC enabled) |
ess_pro_s3_access_key |
OpenBao lookup (when S3 enabled) |
ess_pro_s3_secret_key |
OpenBao lookup (when S3 enabled) |
ess_pro_rtc_external_ip |
DMZ public IP for LiveKit ICE |
See defaults/main.yml for everything else. The examples/ directory
contains a ready-to-use group_vars/ess_servers.yml with all the
OpenBao lookups pre-wired.
Example playbook
- name: Deploy Element Server Suite Pro
hosts: ess_servers
become: true
roles:
- digitalboard.core.k3s
- digitalboard.core.ess_pro
With inventory variables (group_vars/ess_servers.yml):
ess_pro_server_name: "digitalboard.ch"
ess_pro_oidc_enabled: true
ess_pro_s3_media_enabled: true
ess_pro_rtc_external_ip: "203.0.113.42"
ess_pro_registry_username: "{{ lookup('community.hashi_vault.vault_kv2_get',
'digitalboard/ess-pro',
mount_point='kv').data.data.username }}"
ess_pro_registry_token: "{{ lookup('community.hashi_vault.vault_kv2_get',
'digitalboard/ess-pro',
mount_point='kv').data.data.token }}"
ess_pro_oidc_client_secret: "{{ lookup('community.hashi_vault.vault_kv2_get',
'digitalboard/ess-pro',
mount_point='kv').data.data.client_secret }}"
ess_pro_s3_access_key: "{{ lookup('community.hashi_vault.vault_kv2_get',
'digitalboard/ess-pro',
mount_point='kv').data.data.s3_access_key }}"
ess_pro_s3_secret_key: "{{ lookup('community.hashi_vault.vault_kv2_get',
'digitalboard/ess-pro',
mount_point='kv').data.data.s3_secret_key }}"
Post-deploy
-
Get the bootstrap admin password:
kubectl -n ess get secrets/ess-generated \ -o jsonpath='{.data.ADMIN_USER_PASSWORD}' | base64 -d -
Log in to
https://admin.digitalboard.chas@localadmin:digitalboard.ch. -
Create users via the Admin Panel or via MAS:
kubectl -n ess exec -it deploy/ess-matrix-authentication-service -- \ mas-cli manage register-user -
If OIDC is enabled, users can also log in directly via Keycloak from the Element Web client.
Operations
-
Re-deploy / config change: re-run the playbook.
kubernetes.core.helmperformshelm upgrade --install— idempotent. -
Upgrade chart version: bump
ess_pro_chart_version, re-run. -
Rotate the Element token: update it in OpenBao, re-run the playbook. The role re-creates the image pull secret and re-authenticates the Helm CLI.
-
Rendered values.yaml on the host:
/etc/ess/values.yaml. -
Tear down:
helm uninstall -n ess ess && kubectl delete ns ess
Known caveats
- The bundled in-cluster Postgres is not for production — point at an external Postgres VM before going live.
- TLS termination on the DMZ Traefik means well-known delegation and
Element Call ICE rely on the upstream proxy sending correct
X-Forwarded-Proto. Synapse is configured withx_forwarded: true; verify withcurl https://digitalboard.ch/.well-known/matrix/server. - ESS Pro Helm chart field names track upstream — if a future chart
version renames a field (e.g.
matrixRTC.sfu.additional), updatetemplates/values.yaml.j2accordingly. Runhelm show values oci://registry.element.io/matrix-stackafter major upgrades. - The
serverNameis immutable after first deploy.