Kapitan: The Inventory-First Templating Tool for GitOps Workflows
A multi-target renderer that turns structured data into deployable code
What is Kapitan?
It’s a templating engine, but with structure. Designed for complex Kubernetes and Terraform setups where one repository manages dozens of environments, clusters, and teams — each with its own configuration, secrets, and versions.
Forget “one values.yaml per team.” Kapitan gives you an inventory. A proper one. Then it renders out everything — Helm, Kustomize, JSON, Terraform, plain YAML — based on that tree.
You’ve got five clusters.
Three cloud providers.
Two generations of deployment logic.
And your team needs to track who owns what, who overrides which defaults, and how to keep secrets out of the repo.
That’s where Kapitan comes in.
It’s not a deployment tool. It’s what runs before deployment — the thing that turns intent into code, cleanly and repeatably.
Where It’s Being Used
– GitOps setups with dozens of microservices and environment-specific overlays.
– CI pipelines that generate final manifests from partials and reusable Jinja libraries.
– Teams that store all infra logic in Git — but need separation between inventory, templates, secrets, and rendering output.
– Security-conscious orgs that use GPG or Vault to keep secrets encrypted until the last moment.
Key Characteristics
Feature | Practical Outcome |
Inventory as Code | Separate `classes` and `parameters` define teams, clusters, apps — deeply structured |
Multi-format Templates | Supports Jinja2, Helm, Kustomize, JSONNET — mix and match per target |
Targeting System | Define per-app outputs: one repo can render 30 different apps/clusters |
Secrets Management | Built-in GPG/Vault support — secrets decrypted only on render |
Reclass Integration | Merge multiple classes and overrides — infrastructure DRY by default |
Command-Line Usage | Single binary. No daemons. Works in any GitOps pipeline |
Modular Projects | Reuse common config blocks across many services and targets |
Output Structure Control | Fully control how final files are named, grouped, and committed |
Cross-Cloud Friendly | Doesn’t care what’s underneath — just renders to files |
No Runtime Required | Everything happens client-side — no control plane, no API to babysit |
What You Actually Need
– Git repository with structure (inventory/, templates/, secrets/, etc.)
– Python 3.x
– GPG keys (or Vault access) if using encrypted secrets
– YAML and Jinja2 familiarity
To install:
pip install kapitan
Or with Docker:
docker run –rm -v $PWD:/src deepmind/kapitan \
compile –search-paths . –inventory inventory/ –targets <your-target>
A basic `inventory/` layout includes:
inventory/
├── classes/
│ └── base.yml
├── targets/
│ └── app-dev.yml
├── secrets/
│ └── app-dev/…
Kapitan reads it, renders the templates (usually from `templates/`), and spits out structured output in `compiled/`.
What Users Actually Say
“We dropped Helm for Kapitan because we needed layering — and didn’t want to rebuild values files for every cluster.”Set featured image
“It forces teams to structure configs. That was painful at first, but worth it.”
“Secrets stay encrypted until CI — works well with Vault, and makes GitOps a bit less terrifying.”
One Note
Kapitan isn’t for simple setups. If you’ve got two services and one dev environment, this is probably too much.
But once your infra spans multiple regions, clusters, tenants, or teams — and you need reproducibility, safety, and structure — Kapitan becomes less of a tool and more of a contract.
It doesn’t care what’s underneath. It just renders what should be.