GCP GKE + Kubernetes
Show the whole prompt
Read https://intentius.io/chant/tutorials/gke-kubernetes/.
Using `examples/k8s-gke-microservice` as the model, write the Config Connector and Kubernetes sources this repository needs, with a `WorkloadIdentityServiceAccount` per workload.
Run `npm run build` and `npx chant lint` until both pass, and open a pull request with the sources.
List in its description the deploy steps and the teardown order a person follows. Do not run the deploy scripts, `gcloud` or `kubectl apply` against a GCP project.
Never deploy to a real cloud account or shared environment (with `chant run`, `chant components` or a platform's own CLI), approve (a pull request review, `chant approve` or `chant run approve`), override a policy denial (`chant approve policy-override`), or merge; never cut or publish a release (`chant release cut --yes` or `chant release publish`), push or delete a `ci/*` tag (`chant ci tick` pushes them), or change the value of an existing flag; never touch `.chant/allowed_signers` or `chant/lifecycle`.Optional: hand this page to your coding agent
Read https://intentius.io/chant/tutorials/gke-kubernetes/.Using `examples/k8s-gke-microservice` as the model, write the Config Connector and Kubernetes sources this repository needs, with a `WorkloadIdentityServiceAccount` per workload.Run `npm run build` and `npx chant lint` until both pass, and open a pull request with the sources.List in its description the deploy steps and the teardown order a person follows. Do not run the deploy scripts, `gcloud` or `kubectl apply` against a GCP project.Never deploy to a real cloud account or shared environment (with `chant run`, `chant components` or a platform's own CLI), approve (a pull request review, `chant approve` or `chant run approve`), override a policy denial (`chant approve policy-override`), or merge; never cut or publish a release (`chant release cut --yes` or `chant release publish`), push or delete a `ci/*` tag (`chant ci tick` pushes them), or change the value of an existing flag; never touch `.chant/allowed_signers` or `chant/lifecycle`.Two chant lexicons, one src/ directory: the GCP lexicon produces Config Connector YAML that creates real GCP resources; the K8s lexicon produces kubectl-ready YAML for workloads. A single .env file connects the two: Config Connector outputs (SA emails) go in, and K8s composites read them.
What you’ll build
Section titled “What you’ll build”┌─────────────────────────────────────────────────────────┐│ GCP Lexicon (Config Connector) (~15 resources) ││ ├── VPC + Subnets + Cloud NAT ││ ├── GKE Cluster + Node Pool (Workload Identity) ││ ├── 4× GCP Service Accounts ││ ├── IAM Policy Members (WI bindings + role grants) ││ └── Cloud DNS Managed Zone │└────────────────────┬────────────────────────────────────┘ │ SA emails via .env → config.ts┌────────────────────▼────────────────────────────────────┐│ K8s Lexicon (~20 resources) ││ ├── Namespace (quotas, limits, network policy) ││ ├── AutoscaledService (Deployment + HPA + PDB) ││ ├── WorkloadIdentityServiceAccount (GKE) ││ ├── GceIngress + GkeExternalDnsAgent ││ ├── GcePdStorageClass ││ ├── GkeFluentBitAgent (Cloud Logging) ││ └── GkeOtelCollector (Cloud Trace + Monitoring) │└─────────────────────────────────────────────────────────┘What you’ll learn
Section titled “What you’ll learn”- How Config Connector turns GCP resources into K8s CRDs, and why that means one
kubectl applycreates real GCP infrastructure - The cross-lexicon value flow: CC outputs ->
.env->config.ts-> K8s composite props - How
WorkloadIdentityServiceAccountwires a K8s SA to a GCP SA (annotation + IAM binding) - The deploy order that matters: CC resources first, K8s workloads second, and why teardown reverses it
GKE control plane free (one zonal cluster), Cloud NAT ~$32/mo, 3× e2-medium nodes ~$75/mo. Total ~$107/mo (us-central1 list price, checked 2026-08 against chant 0.46.0; GCP list prices change and vary by region, so re-price before relying on this number). Tear down after testing.
Get started
Section titled “Get started”Deploy the k8s-gke-microservice example. My GCP project is <your-project-id>.See examples/k8s-gke-microservice/ for the full README, deploy workflow, and teardown instructions.
Key patterns
Section titled “Key patterns”Config Connector as the GCP–K8s bridge
Section titled “Config Connector as the GCP–K8s bridge”Config Connector resources look like regular K8s objects but they represent real GCP resources. When you kubectl apply a ContainerCluster CRD, Config Connector calls the GKE API and creates the cluster. When you delete it, the cluster is deleted too.
// src/infra/cluster.ts — GKE cluster as a K8s CRDexport const cluster = new ContainerCluster({ metadata: { name: "gke-microservice", namespace: gcpProjectId }, spec: { location: "us-central1-a", workloadIdentityConfig: { workloadPool: `${gcpProjectId}.svc.id.goog` }, // ... },});The management cluster runs Config Connector and manages all GCP infra this way. The workload cluster runs your app.
Cross-lexicon wiring via .env
Section titled “Cross-lexicon wiring via .env”After npm run deploy-infra, Config Connector has created the GCP service accounts. Their email addresses are in the CC resource status, and npm run load-outputs extracts them and writes them to .env:
APP_GSA_EMAIL=app-sa@my-project.iam.gserviceaccount.comEXTERNAL_DNS_GSA_EMAIL=external-dns-sa@my-project.iam.gserviceaccount.comThen npm run build:k8s reads these from .env via config.ts and passes them to K8s composites:
// src/k8s/app.ts — the SA email wires GCP identity to K8s workloadexport const appSa = WorkloadIdentityServiceAccount({ name: "app-sa", gcpServiceAccountEmail: config.appGsaEmail, // from .env});WorkloadIdentityServiceAccount sets the iam.gke.io/gcp-service-account annotation on the K8s ServiceAccount. GKE’s Workload Identity mutating webhook injects the credential into pods that use this SA, with no JSON key files or secrets.
Deploy and teardown order
Section titled “Deploy and teardown order”Build (both lexicons) → kubectl apply CC resources (GCP infra) → load-outputs (SA emails → .env) → Build K8s manifests (with real emails) → kubectl apply K8s workloads
Teardown (reverse): kubectl delete K8s workloads ← ingress controller must be running to clean up LB kubectl delete CC resources ← CC controller must be running to delete GCP resources delete CC service account delete GKE cluster (bootstrap cluster)Always delete K8s resources before CC resources. If CC resources are deleted first, the GCE load balancer provisioned by the ingress object becomes orphaned.
Further reading
Section titled “Further reading”- GCP Config Connector lexicon — resource reference and composites
- GKE Composites — WorkloadIdentityServiceAccount, GceIngress, and more
- Kubernetes lexicon — core composites reference
- Agent Integration guide — using chant skills with Claude Code