Video Thumbnail for Lesson
12.5: Kluctl (Full Build)

Kluctl (Full Build)

Kluctl allows us to manage all of our application services along with third‑party components using a single declarative configuration. After expanding the demo project the root deployment.yaml glues everything together:

vars:
  - file: config/{{ args.environment }}.yaml

deployments:
  - path: namespaces
  - barrier: true
  - include: third-party
  - barrier: true # postgres depends on cloudnative-pg being installed
  - include: services

commonLabels:
  devopsdirective.com/course: "kubernetes-course"

Each service directory has environment‑specific files under config and a manifests folder with templated Kubernetes resources. The third-party directory installs components such as Traefik and CloudNativePG from Helm charts. A chart definition looks like:

helmChart:
  repo: https://traefik.github.io/charts
  chartName: traefik
  chartVersion: 20.8.0
  releaseName: traefik
  namespace: traefik
  output: helm-rendered.yaml

Kluctl renders the chart and then applies the output via Kustomize. Barriers ensure that the CRDs from these charts exist before dependent resources are applied. Our PostgreSQL database is defined using the CloudNativePG Cluster resource where the instance count is templated per environment:

apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
  name: cnpg-minimal
  namespace: postgres
spec:
  enableSuperuserAccess: true
  instances: {{ postgres.instances }}
  storage:
    size: 1Gi
  superuserSecret:
    name: cnpg-minimal-superuser

Database migrations run before the APIs start thanks to pre‑deploy hooks:

metadata:
  annotations:
    kluctl.io/hook: pre-deploy
    kluctl.io/hook-weight: 1

Deploying is as simple as kluctl deploy <target>. The target configuration selects the Kubernetes context and values such as the hostname. Kluctl shows a diff of what will change and applies the manifests in order. If anything fails while resources come up you can safely rerun the command until everything is healthy.

After applying the staging configuration the application becomes available through the Traefik load balancer. Switching to the production context and running the same command provisions the stack in GKE. Scaling an API is as easy as changing a value in the environment config and redeploying—the diff clearly shows the updated replica count.

Kluctl gives us Helm‑style templating without the extra boilerplate and provides an excellent diff against the live cluster. In the CI/CD section we will look at how to automate these deployments using the Kluctl GitOps controller.