# zitadel-configurator A minimal CDK for Terraform (CDKTF) TypeScript app that provisions resources in a ZITADEL instance. The included example stack configures the ZITADEL provider and creates a demo organization ("geoffs-makers-guild"). This directory is intended for local development and experimentation against a local ZITADEL instance (via Docker Compose or a local Kubernetes cluster using kind + Helm). ## Prerequisites - Node.js >= 20.9 and npm - CDKTF CLI (either install globally or use npx) - Install: `npm i -g cdktf-cli@latest` - Or run via npx: `npx cdktf --help` - One of the following ZITADEL runtimes: - Docker + Docker Compose (quickest) - or Kubernetes (kind), Helm, kubectl - Optional: OpenSSL (to generate a strong master key) ## Getting a local ZITADEL Option A — Docker Compose (recommended to start): - From the repository root, create `.zitadel.env` with a strong master key. Example: ```dotenv ZITADEL_MASTERKEY=$(openssl rand -base64 32) ``` Alternatively, run `openssl rand -base64 32` and paste the result as the value of `ZITADEL_MASTERKEY`. - Start ZITADEL and its login UI: ```bash docker compose -f compose.zitadel.yml up -d ``` - Wait until services are healthy. The compose file will write two files to the repository root: - `admin.pat` — a Personal Access Token (PAT) with IAM_OWNER role (use this for Terraform/ZITADEL provider authentication) - `login-client.pat` — a PAT for the login service - Useful URLs: - API: http://localhost:8080 - Login UI: http://localhost:3000/ui/v2/login Option B — Kubernetes (kind + Helm): - Scripts are provided under `k8s/` to spin up a local cluster and install Traefik, PostgreSQL, and ZITADEL with example values. - From this directory: ```bash cd cluster ./install-dev-platform.sh ``` - The Helm example uses the host `pg-insecure.127.0.0.1.sslip.io` routed through Traefik, mapped to your local ports 80/443. - To uninstall and clean up: ```bash ./uninstall-dev-platform.sh ``` ## Configure and use CDKTF - Install dependencies (inside this `zitadel-configurator` directory): ```bash npm install ``` - Generate provider bindings (creates/updates the `.gen` folder): ```bash npm run get ``` - Synthesize the Terraform JSON (outputs to `cdktf.out/`): ```bash npm run synth ``` You can also run CDKTF via `npx cdktf synth`. - Deploy the stack (interactive approval by default): ```bash npx cdktf deployCdktf ``` - Destroy the stack when done: ```bash npx cdktf destroy ``` ## Authentication and configuration - The example code in `main.ts` reads a dotenv file one level up: `../.zitadel.env`. - It currently expects `ZITADEL_MASTERKEY` in that file because the Docker Compose setup uses it to initialize ZITADEL. - The ZITADEL Terraform provider requires a token for API access (PAT or service account), not the master key. - When you start ZITADEL via Docker Compose in this repo, an admin PAT is written to `../admin.pat` (repository root). Use that for provider authentication. - If you want to use the PAT with the current example, update `main.ts` to read the PAT and pass it to the provider's `token` field. For example: ```ts import { readFileSync } from "node:fs"; const adminPat = readFileSync("../admin.pat", "utf8").trim(); new ZitadelProvider(this, "zitadel", { domain: "http://localhost:8080", // for Docker Compose token: adminPat, }); ``` - For the Kubernetes example, the domain in `main.ts` is set to `https://pg-insecure.127.0.0.1.sslip.io`. Keep that if you are using the kind + Traefik + Helm setup; otherwise change it to your environment. ## Commands reference - `npm run get` — generates provider bindings from `cdktf.json` (`.gen/` folder). - `npm run build` — type-checks and compiles TypeScript to JavaScript. - `npm run synth` — synthesizes Terraform JSON to `cdktf.out/`. - `npx cdktf deployCdktf` — deploys the synthesized stack. - `npx cdktf destroy` — destroys the deployed resources. - `npm test` — runs Jest (with `cdktf.Testing.setupJest`), useful for unit testing constructs. ## Directory layout - `main.ts` — CDKTF app entrypoint. Defines a `TerraformStack` that configures the ZITADEL provider and creates a demo Org. - `.gen/` — auto-generated provider constructs (created by `cdktf get`). - `cdktf.json` — CDKTF project configuration (`app` is `npx ts-node main.ts`). - `k8s/` — helper scripts to run a local K8s cluster and install ZITADEL with Helm. ## Troubleshooting ### Common Issues and Solutions #### TLS Certificate Errors with Kubernetes Setup If you encounter "x509: certificate signed by unknown authority" or "issuer does not match" errors: 1. **Install cert-manager** (if not already installed): ```bash kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.15.3/cert-manager.yaml kubectl wait --for=condition=ready pod -l app.kubernetes.io/name=cert-manager -n cert-manager --timeout=300s ``` 2. **Create a self-signed certificate** for the local domain: ```bash # Create the certificate manually openssl req -x509 -newkey rsa:4096 -keyout tls.key -out tls.crt -days 365 -nodes -subj "/CN=machine.127.0.0.1.sslip.io" # Create Kubernetes TLS secret kubectl create secret tls zitadel-tls --cert=tls.crt --key=tls.key ``` 3. **Update main.ts configuration** - Remove `insecure: true` flag and use proper JWT authentication: ```typescript const provider = new ZitadelProvider(this, "zitadel", { domain: "machine.127.0.0.1.sslip.io", jwtProfileJson: JSON.stringify(JSON.parse(readFileSync(path.resolve("zitadel-admin-sa.json").toString(), 'utf-8'))), // Remove: insecure: true, // This causes issuer mismatch errors }); ``` #### Other Common Issues - Provider bindings missing (`.gen/providers/zitadel/...`): run `npm run get`. - Auth errors on deployCdktf: ensure you are using a valid service account JSON or PAT, not the master key. - `machine.127.0.0.1.sslip.io` does not resolve: use the Docker Compose setup and set provider domain to `http://localhost:8080`, or ensure your kind+Traefik install is running and ports 80/443 are mapped. - Node version errors: ensure Node >= 20.9 as specified in `package.json`. ## Security Do not commit secrets. Keep `.zitadel.env`, `admin.pat`, and other credentials out of version control. ## License MPL-2.0