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 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!

After defining it, you can make this data available to the various templating engines Input types offered by Kapitan, allowing you to reuse it.

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 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.

Credits