Kustomize manifests for Thunderbird Pro Customer Auth — the Keycloak instance
serving realm tbpro (auth.tb.pro) — deployed to the Thunderbird Pro EKS
clusters via ArgoCD. Migration plan & target architecture:
platform-infrastructure/docs/keycloak-customer-auth-migration.md.
Epic: platform-infrastructure#132.
Database is shared Neon, not RDS. Source ECS and the EKS target use the same shared Neon Postgres DB, reached over PrivateLink. There is no data migration — the prod cutover is a traffic flip. Validation runs against isolated Neon branches (
mzla-tb-{dev,prod}). The vestigial ACK-RDS machinery was removed (platform-infrastructure#579).
bases/
keycloak/ namespace, StatefulSet, services (incl. metrics), PDB,
db/admin ExternalSecrets, VMServiceScrape
overlays/
tb-dev/ tailnet-only (Tailscale Ingress); Neon branch mzla-tb-dev; 2 replicas
tb-prod/ tailnet-only validation; Neon branch mzla-tb-prod; 2 replicas
(public Cloudflare tunnel + tailnet admin + 3 replicas are kept in the
overlay dir but unreferenced until the cutover, #142)
The ArgoCD app-of-apps for each cluster lives in platform-infrastructure
(argocd/tb-{dev,prod}/apps/keycloak-customer.yaml) and points at
overlays/<cluster>. The cluster's Pulumi stack (mzla-tb-{dev,prod}, Phase 4e)
provides the Keycloak Neon PrivateLink endpoint SG + pod SG + IRSA; the pod SG
is assigned to the pods via the overlay's SecurityGroupPolicy.
./util/kustomize-build-all.sh # builds every overlay (CI gate)
kustomize build overlays/tb-dev # or a single overlay- Admin is never public. It is reached over Tailscale, like the Staff SSO
Keycloak. Both dev and prod are tailnet-only today (whole service). At the prod
cutover (#142) tb-prod adds a public Cloudflare tunnel for the auth host, with the
admin console/REST kept on the tailnet (
KC_HOSTNAME_ADMIN) and public/admindenied at the edge (Cloudflare Access). - Realm
tbprolives in the shared Neon DB (validated via isolated Neon branches) — there is no--import-realmand no data migration.
The overlay's keycloak/statefulset.yaml sets KC_DB_URL_HOST to the env's Neon
endpoint (the mzla-tb-{dev,prod} branch today) + KC_DB_URL_PROPERTIES=?sslmode=require.
The pods reach Neon over the manually-created Neon interface endpoints, gated by the
dedicated mzla-tb-{dev,prod}-keycloak-neondb-privatelink endpoint SG; the pods carry
the dedicated pod SG via keycloak/securitygrouppolicy.yaml.
| Token / value | Source |
|---|---|
REPLACE_MZLA_ECR/keycloak-customer (kustomization.yaml images:) |
the per-account mzla ECR mirror (done, platform-infrastructure#558); each overlay sets newName + newTag |
keycloak/securitygrouppolicy.yaml groupIds |
the cluster's eks-cluster-sg + pulumi stack output keycloak_customer_pod_sg_id (mzla-tb-{dev,prod}) |
KC_DB_URL_HOST (overlay keycloak/statefulset.yaml) |
the env's Neon endpoint (branch today; live shared endpoint at cutover) |
Secrets (AWS Secrets Manager, per account, eu-central-1) referenced by the
ExternalSecrets: mzla/<env>/keycloak-customer-db and
mzla/<env>/keycloak-customer-admin ({username, password}).
tb-dev also uses mzla/tb-dev/keycloak-customer-admin-client ({client-secret}) for
keycloak-config-cli auth (the tb-accounts-admin service account) — see
docs/dev-realm-redirect-uris.md for the codified
thunderbird-accounts client reconcile that keeps tb-dev config across Neon resets.
mzla/shared-services/cloudflare-operator already exists (read cross-account; used by the cutover Cloudflare resources).
- Public Cloudflare tunnel (
auth.tb.pro) + tailnet admin ingress + 3 replicas (files present, unreferenced). - Public
/admindeny for tb-prod (Cloudflare Access). - Repoint
KC_DB_URL_HOSTfrom the validation branch to the live shared Neon endpoint.