3.4 KiB
3.4 KiB
Zitadel Bootstrap
1. Terraform — Vault KV + database engine
vault kv put secret/cloudflare/api-token api-token="<cloudflare-api-token>"
vault kv put secret/postgres/admin username="********" password="<postgres-admin-password>"
cd terraform/internal/vault
../../scripts/tofu-versitygw-state apply \
-var="internal_domain=quorate.internal" \
-var='users=["<admin-user>"]' \
-var="admin_user=<admin-user>"
2. PostgreSQL — roles and database
cd terraform/internal/postgres
../../scripts/tofu-versitygw-state apply
3. Network policies
kubectl --context default apply -f vendor/platform/postgres/network-policies.yaml
kubectl --context default apply -f vendor/platform/vault/network-policies.yaml
vault read database/config/postgres
4. cert-manager — Cloudflare token + Let's Encrypt issuer
kubectl --context default apply -f vendor/platform/cert-manager/config/vso.yaml
kubectl --context default apply -f vendor/platform/cert-manager/config/issuers.yaml
kubectl --context default get secret cloudflare-api-token -n cert-manager
5. Gateway R
flux reconcile kustomization platform-cilium-config --context default -n flux-system --with-source
The gateway-relay-tls Certificate triggers a DNS-01 ACME challenge. Monitor:
kubectl --context default describe certificate gateway-relay-tls -n kube-system
Cloudflare declares auth.quorate.dev from the OCI relay state in terraform/external/cloudflare.
6. Zitadel namespace + network policies + VSO
kubectl --context default create namespace zitadel
# Pre-create the service account so VSO can authenticate before Helm runs
kubectl --context default create serviceaccount zitadel -n zitadel
kubectl --context default apply -f vendor/platform/zitadel/network-policies.yaml
kubectl --context default apply -f vendor/platform/zitadel/vso.yaml
Wait for both secrets:
kubectl --context default get secret zitadel-masterkey -n zitadel
kubectl --context default get secret zitadel-db -n zitadel
7. Helm install
helm repo add zitadel https://charts.zitadel.com
helm upgrade --install zitadel zitadel/zitadel \
--namespace zitadel \
-f vendor/platform/zitadel/values.yaml
8. HTTPRoute
kubectl --context default apply -f vendor/platform/zitadel/route.yaml
9. Post-deploy — organization and OIDC clients
Once Zitadel is up and the IAM admin machine key secret exists, mirror it to Vault for Terraform:
kubectl --context default get secret iam-admin -n zitadel -o jsonpath='{.data.iam-admin\.json}' | base64 -d > iam-admin.json
vault kv put secret/zitadel/iam-admin iam-admin.json=@iam-admin.json
cd terraform/internal/zitadel
../../scripts/tofu-versitygw-state apply -var="zitadel_domain=auth.quorate.dev"
This creates the primary service organization, the shared service project, and the Forgejo OIDC application.
The Forgejo OIDC client material is mirrored into Vault for later VSO sync. Use the non-secret outputs when configuring or verifying Forgejo's OAuth2 authentication source:
tofu output forgejo_oidc_authentication_name
tofu output forgejo_oidc_discovery_url
tofu output forgejo_oidc_redirect_uri
tofu output forgejo_oidc_vault_secret_path
The Forgejo authentication source name must stay aligned with the redirect URI: https://forge.quorate.internal/user/oauth2/Zitadel/callback.