https://github.com/thunderbird/keycloak-customer-deploy
Kustomize manifests for Thunderbird Pro Customer Auth (Keycloak realm tbpro) on EKS
https://github.com/thunderbird/keycloak-customer-deploy
Last synced: about 1 month ago
JSON representation
Kustomize manifests for Thunderbird Pro Customer Auth (Keycloak realm tbpro) on EKS
- Host: GitHub
- URL: https://github.com/thunderbird/keycloak-customer-deploy
- Owner: thunderbird
- License: mpl-2.0
- Created: 2026-06-12T17:46:06.000Z (about 2 months ago)
- Default Branch: main
- Last Pushed: 2026-06-16T23:27:58.000Z (about 2 months ago)
- Last Synced: 2026-06-17T01:15:42.713Z (about 2 months ago)
- Language: Shell
- Size: 23.4 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# keycloak-customer-deploy
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`](https://github.com/thunderbird/platform-infrastructure/blob/main/docs/keycloak-customer-auth-migration.md).
Epic: [platform-infrastructure#132](https://github.com/thunderbird/platform-infrastructure/issues/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](https://github.com/thunderbird/platform-infrastructure/issues/579)).
## Layout
```
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/`. 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`.
## Build / validate
```bash
./util/kustomize-build-all.sh # builds every overlay (CI gate)
kustomize build overlays/tb-dev # or a single overlay
```
## Exposure model
- **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 `/admin`
denied at the edge (Cloudflare Access).
- **Realm `tbpro` lives in the shared Neon DB** (validated via isolated Neon
branches) — there is no `--import-realm` and no data migration.
## DB connectivity (Neon over PrivateLink)
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`.
## Placeholders / per-env values
| Token / value | Source |
|-------|--------|
| `REPLACE_MZLA_ECR/keycloak-customer` (`kustomization.yaml` `images:`) | the per-account mzla ECR mirror (done, [platform-infrastructure#558](https://github.com/thunderbird/platform-infrastructure/pull/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//keycloak-customer-db` and
`mzla//keycloak-customer-admin` (`{username, password}`).
`mzla/shared-services/cloudflare-operator` already exists (read cross-account; used by the cutover Cloudflare resources).
## Not yet included (cutover follow-ups, #142)
- Public Cloudflare tunnel (`auth.tb.pro`) + tailnet admin ingress + 3 replicas (files present, unreferenced).
- Public `/admin` deny for tb-prod (Cloudflare Access).
- Repoint `KC_DB_URL_HOST` from the validation branch to the live shared Neon endpoint.