Skip to content

Kapitan Overview

Kapitan at a glance

%%{ init: { securityLevel: 'loose'} }%%
graph LR
    classDef pink fill:#f9f,stroke:#333,stroke-width:4px,color:#000,font-weight: bold;
    classDef blue fill:#00FFFF,stroke:#333,stroke-width:4px,color:#000,font-weight: bold;
    TARGET1 --> KAPITAN
    TARGET2 --> KAPITAN
    TARGETN --> KAPITAN
    KAPITAN --> EXTERNAL
    KAPITAN --> GENERATORS
    KAPITAN --> HELM
    KAPITAN --> JINJA
    KAPITAN --> JSONNET
    KAPITAN --> KADET
    EXTERNAL --> OUTPUT
    GENERATORS --> OUTPUT
    JINJA --> OUTPUT
    JSONNET --> OUTPUT
    KADET --> OUTPUT
    HELM --> OUTPUT
    GKMS --> REFERENCES
    AWSKMS --> REFERENCES
    VAULT --> REFERENCES
    OTHER --> REFERENCES
    PLAIN --> REFERENCES
    OUTPUT --> TARGETN_OUTPUT
    OUTPUT --> TARGET1_OUTPUT 
    OUTPUT --> TARGET2_OUTPUT 
    REFERENCES --> KAPITAN
    TARGET1_OUTPUT --> DOCUMENTATION 
    TARGET1_OUTPUT --> KUBERNETES
    TARGET1_OUTPUT --> SCRIPTS 
    TARGET1_OUTPUT --> TERRAFORM
    CLASSES --> TARGET1
    CLASSES --> TARGET2
    CLASSES --> TARGETN

    subgraph "Inventory"
        CLASSES[classes]
        TARGET1(["target 1"]):::pink
        TARGET2(["target 2"])
        TARGETN(["target N"])
    end

    subgraph "references"
        direction TB
        GKMS["GCP KMS"]
        AWSKMS["AWS KMS"]
        VAULT["Hashicorp Vault"]
        OTHER["others"]
        PLAIN["plain"]
        REFERENCES["references"]
    end

    KAPITAN(("<img src='/images/kapitan_logo.png'; width='80'/>")):::blue
    click EXTERNAL "/compile#external"

    subgraph "Input Types" 
        EXTERNAL["external"]
        GENERATORS["generators"]
        HELM["helm"]
        JINJA["jinja"]
        JSONNET["jsonnet"]
        KADET["kadet"]
    end

    OUTPUT{{"compiled output"}}:::blue



    subgraph " "
        TARGET1_OUTPUT([target1]):::pink
        DOCUMENTATION["docs"]
        KUBERNETES["manifests"]
        SCRIPTS["scripts"]
        TERRAFORM["terraform"]
    end

    TARGET2_OUTPUT(["target 2"])
    TARGETN_OUTPUT(["target N"])

Essential concepts

Inventory

The Inventory is a hierarchical database of variables, defined in yaml files, that are passed to the targets during compilation.

The Inventory is the heart of Kapitan.

Using simple reusable yaml files (classes), you can represent as a Single Source Of Truth (SSOT) everything that matters in your setup, for instance you can define:

  • kubernetes components definitions
  • terraform resources
  • business concepts
  • documentation and tooling
  • ...anything else you want!

Once you have it defined, you can reuse this data can be made available to the many templating engines Input types available to Kapitan.

Find more detaled explanation in the inventory section of the documentation.

Input types

On compilation, Kapitan "renders" the Inventory and makes it available to templates that can generate any you any configuration you want, including Kubernetes manifests, documentation/playbooks, Terraform configuration or even scripts.

Generators

Generators are simplest way of getting started with Kapitan and require no code at all. Check out our Kapitan Reference repository to get started or our Read our blog post Keep your ship together with Kapitan.

The simplest way to get started with Kapitan. Generators are universal templates that are a simplified way to generate configuration files (for instance, Kubernetes manifests) without using any templating at all.

Kadet

Easily define and reuse complex Python objects that serialize into JSON or YAML

Use kadet, our home built Python library, to easily generate json and yaml manifests for your applications.

Using kadet is simple as using Python

examples/kubernetes/components/nginx-kadet/__init__.py
from kapitan.inputs import kadet

kubelib = kadet.load_from_search_paths("kubelib")
inv = kadet.inventory()

name = "nginx"
labels = kadet.BaseObj.from_dict({"app": name})
nginx_container = kubelib.Container(
    name=name, image=inv.parameters.nginx.image, ports=[{"containerPort": 80}]
)

svc_selector = {"app": name}
svc_port = kadet.BaseObj()
svc_port.root.name = "http"
svc_port.root.port = 80
svc_port.root.targetPort = 80


def main():
    return {
        "nginx_deployment": kubelib.Deployment(name=name, labels=labels, containers=[nginx_container]),
        "nginx_service": kubelib.Service(name=name, labels=labels, ports=[svc_port], selector=svc_selector),
    }

kadet is what generators are being built with. See and example

Head over to kapicorp/kadet for more details

Find help in #kapitan

Jsonnet

A powerful DSL for elegant description of JSON data

Use the jsonnet input type to compile jsonnet code, and have access to a large amount of available jsonnet libraries like bitnami-labs/kube-libsonnet

Find help in #kapitan or #jsonnet

examples/kubernetes/components/nginx-jsonnet/main.jsonnet
local svc = import "./service.jsonnet";
local deployment = import "./deployment.jsonnet";


{
    "app-service": svc.nginx_svc,
    "app-deployment": deployment.nginx_deployment,
}

Head over to jsonnet to learn more

Jinja2

Jinja is a fast, expressive, extensible templating engine

Good old Jinja to create text based templates for scripts and documentation.

Don't underestimate the power of this very simple approach to create templated scripts and documentation!

examples/kubernetes/scripts/setup_cluster.sh
#!/bin/bash -eu

# Copyright 2019 The Kapitan Authors
# SPDX-FileCopyrightText: 2020 The Kapitan Authors <kapitan-admins@googlegroups.com>
#
# SPDX-License-Identifier: Apache-2.0

{% set i = inventory.parameters %}
{% set cluster = i.cluster %}

{% if cluster.type == "gke" %}
gcloud container clusters get-credentials {{cluster.name}} --zone {{cluster.zone}} --project {{i.project}}
{% elif cluster.type == "self-hosted" %}

kubectl config set-credentials $USER --client-certificate=$HOME/credentials/$USER.crt --client-key=$HOME/credentials/$USER.key
kubectl config set-cluster {{cluster.id}} --server={{cluster.kubernetes.master.api}} --certificate-authority={{cluster.kubernetes.master.ca}} --embed-certs={{cluster.kubernetes.master.embed}}

{% elif cluster.type == "minikube" %}

{% endif %}

Find help in #kapitan

Helm

The package manager for Kubernetes

Kapitan can also be used to manage Helm, giving you access to its enourmous catalogues of Helm charts.

examples/kubernetes/inventory/classes/component/nginx-helm.yml

external dependencies are used to automatically fetch helm charts in this example.

Please use the kapitan compile --fetch flag if the chart has not been downloaded already

parameters:
  namespace:
  nginx:
    version: 4.4.0
    replicas: 2
    name: ${target_name}
    namespace: ${target_name}
  kapitan:
    dependencies:
      - type: helm
        output_path: charts/nginx-ingress
        source: https://kubernetes.github.io/ingress-nginx
        chart_name: ingress-nginx
    compile:
      - output_path: .
        input_type: helm
        input_paths:
          - charts/nginx-ingress
        helm_values:
          controller:
            name: ${nginx:name}
        helm_params:
          name: ${nginx:name}
          namespace: ${nginx:namespace}

Find help in #kapitan

References

Use Kapitan to securely generate and manage secrets with GPG, AWS KMS, gCloud KMS and Vault.

Tip

Use Tesoro, our Kubernetes Admission Controller, to complete your integration with Kubernetes for secure secret decryption on-the-fly.

Setup your repository

Note

We are currently working on improving the experience to give you an even quicker experience with Kapitan

Quickstart

kapicorp/kapitan-reference repository is meant to be a way to bootstrap your Kapitan setup to get you up and running.

It is meant to help you make use of best practices and libraries that can make Kapitan the ultimate tool for all your configuration needs.

$ git clone git@github.com:kapicorp/kapitan-reference.git kapitan-templates
$ cd kapitan-templates

$ ./kapitan compile
Compiled postgres-proxy (1.51s)
Compiled tesoro (1.70s)
Compiled echo-server (1.64s)
Compiled mysql (1.67s)
Compiled gke-pvm-killer (1.17s)
Compiled prod-sockshop (4.74s)
Compiled dev-sockshop (4.74s)
Compiled tutorial (1.68s)
Compiled global (0.76s)
Compiled examples (2.60s)
Compiled pritunl (2.03s)
Compiled sock-shop (4.36s)

From Scratch (Advanced)

Warning

the kapitan init command leaves you with a bare configuration. Setting up Kapitan might require time.

Please use the Quickstart setup if you want to get started quicker.

If you want to start off with a clean kapitan project, you can run kapitan init --directory <directory> to populate a new directory with the recommended kapitan folder structure.

The bare minimum structure that makes use of kapitan features may look as follows:

.
├── components
│   ├── mycomponent.jsonnet
├── templates
├── ├── README.md
├── inventory
│   ├── classes
│   │   ├── common.yml
│   └── targets
│       ├── dev.yml
│       ├── staging.yml
│       └── prod.yml
├── refs
│   ├── targets
│   │   ├── prod
│   │   │   └── password
└───├── common
        └── example-com-tls.key
  • components: template files for kadet, jsonnet and helm
  • templates: stores Jinja2 templates for scripts and documentation
  • inventory/targets: target files
  • inventory/classes: inventory classes to be inherited by targets
  • refs: references files

Credits