Skip to content

Update to Keycloak 26 and split Terraform modules#491

Open
lucas-koehler wants to merge 37 commits into
mainfrom
lk/keycloak-update
Open

Update to Keycloak 26 and split Terraform modules#491
lucas-koehler wants to merge 37 commits into
mainfrom
lk/keycloak-update

Conversation

@lucas-koehler
Copy link
Copy Markdown
Contributor

@lucas-koehler lucas-koehler commented May 29, 2026

Merge note: This should probably be squashed on merge because there are various tryout and rebase-fix commits.

Fixes #472

E2E test run: https://github.com/eclipse-theia/theia-cloud/actions/runs/26575253687

Update Keycloak setup and split Terraform modules

This PR updates the Keycloak deployment to Keycloak 26 (via the official Keycloak Operator instead of the Bitnami chart) and restructures the Terraform modules so that cluster prerequisites and Theia Cloud installation are clearly separated.

Terraform: new cluster-prerequisites module

A new module replaces the prerequisite parts of the old helm module. It uses the official Keycloak Operator (instead of the deprecated Bitnami Helm chart) and is configurable enough to skip parts that are already installed in the target cluster.

  • Installs the Keycloak Operator from keycloak-k8s-resources (default version 26.4.5) and creates the Keycloak instance via the Keycloak CR
  • Deploys an integrated PostgreSQL 17 backend (configurable, can be disabled to use an external database)
  • Optionally installs cert-manager (v1.17.4) and a self-signed ClusterIssuer for local development
  • Optionally installs the nginx or haproxy ingress controller with a configurable load balancer IP
  • Creates the Keycloak Ingress with TLS, configurable cluster issuer, common name, annotations, and HTTP relative path (default /keycloak/)
  • Exposes keycloak_url, namespace, tls_secret_name, and service-name outputs; keycloak_url is trimmed of any trailing slash so downstream consumers (e.g. the Keycloak provider) can use it directly
  • Includes a README documenting variables, examples (Minikube, GKE, external Postgres, existing cert-manager) and a migration guide from the Bitnami chart

Two notable implementation details:

  • The Keycloak Operator manifests are applied with terraform_data + local-exec instead of kubectl_manifest. The previous approach parsed YAML from an HTTP response to build dynamic for_each keys, which Terraform cannot evaluate at plan time.
  • The Postgres PVC doesn't wait for a binding pod, because the pod that binds it is only created in a later step.

Terraform: new theia-cloud module

A new module that only installs the Theia Cloud Helm charts (theia-cloud-base, theia-cloud-crds, theia-cloud). Each chart can be toggled individually via install_theia_cloud_base, install_theia_cloud_crds, and install_theia_cloud so that downstream configurations can stage installs as needed.

  • New theia_cloud_version variable (default 1.2.0) pins the chart version for all three releases
  • New keycloak_url variable lets consumers pass the URL from the cluster-prerequisites module; falls back to https://<hostname>/keycloak if empty
  • A single trailing slash is enforced on the URL before passing it to the Helm chart, since the chart requires it

Terraform: removed helm module

The old helm module has been deleted; its functionality is now split between cluster-prerequisites and theia-cloud.

Terraform: updated configurations

All consumers have been migrated to the new modules:

  • gke_getting_started: drops the unused postgres_postgres_password variable, installs cert-manager and the theia-cloud-base module first (to re-use its letsencrypt-prod ClusterIssuer for the Keycloak ingress), then cluster-prerequisites, then the remainder of theia-cloud. The Keycloak provider URL is taken from module.cluster_prerequisites.keycloak_url.
  • minikube_getting_started/1_theiacloud-and-dependencies: replaces the helm module with cluster_prerequisites + theia-cloud. The standalone .terraform.lock.hcl at the configuration root has been removed (the configuration is split into sub-directories with their own lockfiles).
  • ci-configurations/e2e_tests: switches to cluster_prerequisites for Keycloak and prerequisites; Theia Cloud charts continue to be installed from the local checkout via direct helm_releases.
  • test-configurations/1_dependencies: switches to cluster_prerequisites. The keycloak output now exposes the module URL directly.

Terraform: keycloak module

  • Removes the now-redundant hostname variable (the Keycloak URL is supplied via the provider configuration)
  • Sets first_name/last_name on the foo and bar test users so that first login does not prompt for them with Keycloak 26.

Landing page and testing page (keycloak-js update)

Both pages have been updated for Keycloak 26 compatibility:

  • node/landing-page: keycloak-js bumped from 20.0.5 to 26.2.4
  • node/testing-page: keycloak-js bumped from ^17.0.1 to 26.2.4
  • App.tsx: uses new Keycloak(...) (the v26 API no longer supports calling Keycloak() without new) and logs the underlying error in the auth failure handlers

Documentation

  • Top-level README.md release checklist now points to terraform/modules/theia-cloud/variables.tf for the Helm chart version (the old terraform/modules/helm path no longer exists)
  • terraform/terraform.md points at the two new modules instead of the removed helm module

- Installs the keycloak operator via offical keycloak K8S resources
- Sets up postgreSQL database and ingress
- Setup keycloak instance via CR
- Add helm_release for nginx ingress controller with configurable
  installation, version, namespace, and load balancer IP
- Update deprecated kubernetes resources to v1 versions:
  kubernetes_namespace, kubernetes_secret, kubernetes_persistent_volume_claim,
  kubernetes_deployment, kubernetes_service
The helm module now only installs theia-cloud components (base, crds,
theia-cloud). Cert-manager, nginx-ingress-controller, and keycloak are
now handled by the cluster-prerequisites module which should be
installed first.

Removed resources:
- helm_release.cert-manager
- helm_release.nginx-ingress-controller
- helm_release.keycloak
- kubectl_manifest.selfsigned_issuer

Deleted files:
- keycloak.yaml
- clusterissuer-selfsigned.yaml
Replace helm module usage with cluster-prerequisites for keycloak,
cert-manager, and nginx-ingress setup in all configurations:
- gke_getting_started
- minikube_getting_started
- 0_minikube-setup/minikube_test_cluster
- 0_minikube-keycloak-setup (removed redundant http provider)
- ci-configurations/e2e_tests

The helm module now only handles theia-cloud components (base, crds,
theia-cloud), while cluster-prerequisites handles the infrastructure.
Move trimsuffix() into the cluster-prerequisites module output so
consumers don't need to handle URL normalization. This follows URL
conventions and meets the Keycloak provider's requirement directly.
Replace kubectl_manifest with terraform_data and local-exec to avoid
the "for_each value depends on resource attributes that cannot be
determined until apply" error. The previous approach parsed YAML from
an HTTP response to construct dynamic map keys, which Terraform cannot
evaluate at plan time.
Do not make it wait until a pod is bound because the pod is only created in the next step
- Remove usage of helm module
- Install cert-manager and theia-cloud-base before cluster-prerequisites
  because we re-use theia cloud's let's encrypt cluster issuer
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Authentification failed on landing page with keycloak 26

1 participant