Files
cluster/deploy/dev/configurations
2025-08-15 18:59:10 -04:00
..
2025-08-15 18:59:10 -04:00
2025-08-15 18:59:10 -04:00
2025-08-15 18:59:10 -04:00
2025-08-15 18:59:10 -04:00
2025-08-15 18:59:10 -04:00
2025-08-15 18:59:10 -04:00
2025-08-15 18:59:10 -04:00

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:

    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:

    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:

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:

    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:

    ./uninstall-dev-platform.sh
    

Configure and use CDKTF

  • Install dependencies (inside this zitadel-configurator directory):

    npm install
    
  • Generate provider bindings (creates/updates the .gen folder):

    npm run get
    
  • Synthesize the Terraform JSON (outputs to cdktf.out/):

    npm run synth
    

    You can also run CDKTF via npx cdktf synth.

  • Deploy the stack (interactive approval by default):

    npx cdktf deployCdktf
    
  • Destroy the stack when done:

    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:

      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):

    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:

    # 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:

    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