kdlctl is a Go CLI for deploying apps and microservices to Google Cloud from a KDL-based deployment file. It supports Cloud Run, gRPC and Caddy workloads, managed platform resources, Cloud Build-based deploy orchestration, and testable NATS/GitHub integration hooks for GitOps-style workflows.
- Changelog:
CHANGELOG.md - Docs:
docs/and GitHub Pages athttps://djburkhart.github.io/kdlctl/ - Releases: GitHub Releases
- Next release prep:
v0.2.1is staged inCHANGELOG.md
deploy.kdlas the source of truth for project, environment, Cloud Run services, gRPC servers, Caddy servers, databases, caches, messaging, logging, and NATS configuration- Cobra-based CLI with
init,validate,plan,deploy,status,rollback, andnatscommands - Direct Cloud Build submission for workloads and managed infrastructure, including Cloud SQL, Redis, Pub/Sub topics, and Cloud Logging resources
- Optional NATS event publishing for async orchestration
- Cloud Run rollback support via the Cloud Run Admin API
kdlctl/
├── .github/workflows
├── cmd/kdlctl
├── examples/{complex,invalid,valid}
├── internal/cli
├── internal/config
├── internal/deploy
├── internal/gcp
├── internal/github
├── internal/nats
├── internal/templates
├── CHANGELOG.md
├── LICENSE
├── Makefile
├── pkg/types
├── cloudbuild.yaml
└── README.md
- Enable the Cloud Build and Cloud Run APIs in your GCP project.
- Authenticate with Application Default Credentials:
gcloud auth application-default login - Make sure your Cloud Run image already exists in Artifact Registry.
- Create a starter config:
go run ./cmd/kdlctl init
go install github.com/djburkhart/kdlctl/cmd/kdlctl@latest- Coverage target: start with 70%+ across
internal/andpkg/ - Current focused coverage work has raised key packages well beyond that floor, with full coverage already reached in
internal/githubandpkg/types - Fixture variants live under
examples\valid\deploy.kdl,examples\invalid\deploy.kdl, andexamples\complex\deploy.kdl testifypowers assertions andtestify/mock-based NATS and GCP client tests so the suite does not need live credentials- GitHub Actions uploads
coverage.outto Coveralls on pushes and pull requests for repo coverage tracking and PR feedback
make test
make test-racekdlctl now includes a Hugo docs site powered by the Doks theme under docs/.
Local docs development expects Node.js 24. The docs package installs Hugo Extended through npm.
make docs-install
make docs-dev
make docs-build.github\workflows\test.ymlrunsgo test -parallel 4, enforces the coverage floor, and uploads coverage to Coveralls.github\workflows\codeql.ymluses the Node 24-compatible CodeQL action line.github\workflows\release.ymlbuilds tagged release archives and publishes GitHub Releases fromv*tagsCHANGELOG.mdis the release-notes source of truth; the next prepared release entry isv0.2.1
See examples/deploy.kdl for a complete sample. kdlctl supports workload blocks like cloud-run, grpc-server, and caddy-server, plus managed infrastructure blocks such as cloud-sql, redis, pubsub-topic, logging-bucket, and logging-sink.
project "my-gcp-project" region="us-central1" {
environment "prod" {
cloud-run "api-service" {
image "us-central1-docker.pkg.dev/my-gcp-project/apps/api-service:latest"
cpu 1
memory "512Mi"
min-instances 1
max-instances 20
concurrency 80
}
grpc-server "payments-grpc" {
image "us-central1-docker.pkg.dev/my-gcp-project/apps/payments-grpc:latest"
port 8443
}
caddy-server "edge-caddy" {
image "us-central1-docker.pkg.dev/my-gcp-project/apps/caddy-edge:latest"
port 8080
}
cloud-sql "primary-db" {
database-version "POSTGRES_16"
tier "db-custom-1-3840"
availability-type "REGIONAL"
storage-gb 50
}
redis "sessions-cache" {
tier "STANDARD_HA"
memory-gb 2
redis-version "REDIS_7_0"
}
pubsub-topic "app-events" {
retention "604800s"
}
logging-bucket "application-logs" {
retention-days 30
}
}
}go run ./cmd/kdlctl init
go run ./cmd/kdlctl validate --env prod
go run ./cmd/kdlctl plan --env prod
go run ./cmd/kdlctl deploy --env prod
go run ./cmd/kdlctl deploy --env prod --service payments-grpc
go run ./cmd/kdlctl deploy --env prod --service primary-db
go run ./cmd/kdlctl deploy --env prod --service api-service --async
go run ./cmd/kdlctl deploy --env prod --via-nats
go run ./cmd/kdlctl status --build BUILD_ID
go run ./cmd/kdlctl rollback --env prod --service api-service --revision api-service-00012-abc
go run ./cmd/kdlctl nats publish --subject deploy.requested '{"env":"prod"}'
go run ./cmd/kdlctl nats subscribe --subject deploy.status.prod.>KDLCTL_FILEKDLCTL_PROJECT_IDKDLCTL_REGIONKDLCTL_NATS_URLKDLCTL_GITHUB_TOKEN
deploysubmits a Cloud Build job that runsgcloud run deployagainst the image specified indeploy.kdl.grpc-servertargets are deployed with Cloud Run HTTP/2 enabled so gRPC services can be reached through managed ingress.caddy-servertargets are deployed as Cloud Run services as well; Cloud Run still terminates external TLS, so Caddy should listen on the configured internal port.cloud-sqlprovisions Cloud SQL instances; repeated deploys patch tier, storage, and availability settings when the instance already exists.redisprovisions Memorystore Redis instances; repeated deploys update size and Redis version where supported.pubsub-topic,logging-bucket, andlogging-sinkresources are created or updated in place throughgcloud.status --env <env>listens ondeploy.status.<env>.>over NATS.- Environment inheritance is supported with
extends="<base-env>". - Pushing a
v*tag triggers the GitHub release workflow, which runs tests, builds release archives, and publishes a GitHub Release using the matchingCHANGELOG.mdentry. - The main test workflow runs
go test -parallel 4with a 70% coverage gate overinternal/...andpkg/....
