Skip to content

Kapitan vs Helm vs Kustomize

Kapitan, Helm, and Kustomize all help you manage Kubernetes configuration, but they solve different problems at different layers. Choosing the right tool—or combining them—depends on your team's size, the complexity of your environments, and how much reuse you need across infrastructure systems.

Quick comparison

Helm Kustomize Kapitan
Primary goal Package and distribute Kubernetes applications Patch and customize existing manifests Generate and organize configuration across environments and tools
Templating Go templates (values.yaml) None (pure YAML overlays) Jsonnet, Jinja2, Kadet, Helm, Kustomize, CUE
Reuse across environments One chart, many values.yaml files Bases and overlays per environment Hierarchical inventory with classes and targets
Multi-tool workflows Kubernetes only Kubernetes only Kubernetes, Terraform, scripts, docs, secrets
Secrets management External tools (Sealed Secrets, Vault Agent, etc.) External tools Built-in references (GPG, KMS, Vault)
Best for Distributing reusable charts Overlaying environment-specific patches Complex, multi-environment, multi-tool configuration

When to use Helm

Helm is the Kubernetes package manager. It is the best choice when:

  • You want to install third-party software on your cluster (for example, Prometheus, nginx-ingress, cert-manager).
  • You are building a reusable application chart that other teams will install with different values.yaml files.
  • You need versioning and rollback for releases.

Helm's strength is packaging. Its weakness is that every environment needs its own values.yaml file, and values are not easily shared with non-Helm tools. If you have fifty microservices and each needs a slightly different Helm values file, you can end up with a lot of similar YAML that is hard to keep consistent.

Kapitan can help here: you can render Helm charts inside Kapitan using the Helm input type, drive the values from the Kapitan inventory, and keep the chart configuration alongside your other infrastructure configuration.

When to use Kustomize

Kustomize is built into kubectl and is the best choice when:

  • You already have plain Kubernetes YAML manifests that you want to customize per environment.
  • You prefer patch-based customization over templating.
  • You want a tool that is simple, Kubernetes-native, and does not introduce a new language.

Kustomize's strength is simplicity. Its weakness is that it only works with existing YAML files, and it does not help you generate configuration from scratch or share data with Terraform, scripts, or documentation. As your environments grow, the number of overlays and patches can become difficult to manage.

Kapitan can help here: you can use Kustomize as an input type to apply patches to manifests generated by other Kapitan input types, or you can generate the base manifests with Jsonnet or Kadet and then patch them with Kustomize.

When to use Kapitan

Kapitan is a configuration management framework. It is the best choice when:

  • You manage Kubernetes manifests, Terraform resources, scripts, and documentation in the same repository.
  • You need a single source of truth for values that are reused across Helm charts, Kustomize overlays, Jsonnet templates, and Terraform modules.
  • You want built-in secrets management that works with GPG, AWS KMS, GCP KMS, Azure Key Vault, or HashiCorp Vault.
  • You have many environments (development, staging, production, multiple regions) and want to model them with a hierarchical inventory instead of many similar values files.

Kapitan does not replace Helm or Kustomize. It integrates with both. You can use Kapitan to:

  • Generate Helm values.yaml files from the inventory and then render the chart with the Helm input type.
  • Generate base Kubernetes manifests with Jsonnet and patch them with Kustomize.
  • Keep your bucket_name, namespace, and replica_count in one place and use them in Kubernetes ConfigMaps, Terraform resources, and Helm values at the same time.

Common patterns

Helm inside Kapitan

Use the Helm input type to render an upstream chart while overriding values from the Kapitan inventory:

parameters:
  kapitan:
    compile:
      - output_path: .
        input_type: helm
        input_paths:
          - components/charts/nginx-ingress
        helm_values:
          controller:
            name: my-controller
        helm_params:
          name: my-release
          namespace: my-namespace

Kustomize inside Kapitan

Use the Kustomize input type to apply patches to manifests generated by another Kapitan input type:

parameters:
  kapitan:
    compile:
      - output_path: manifests
        input_type: kustomize
        input_paths:
          - components/kustomize/overlays/production

Plain YAML vs Kapitan inventory

Without Kapitan, you might copy namespace: production into every Helm values file, Kustomize overlay, and Terraform variable file. With Kapitan, you define it once in an inventory class and reference it everywhere:

# inventory/classes/environments/production.yml
parameters:
  environment: production
  namespace: production
# inventory/targets/web.yml
classes:
  - environments.production
  - components.web

parameters:
  kapitan:
    compile:
      - output_path: manifests
        input_type: jinja2
        input_paths:
          - templates/deployment.yml.j2

Summary

  • Use Helm for packaging and distributing Kubernetes applications.
  • Use Kustomize for patching existing manifests per environment.
  • Use Kapitan when you need a unified inventory that drives Helm, Kustomize, Jsonnet, Terraform, and secrets together.

Next steps