Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Quick Start

Prerequisites

Install go, docker, kubectl, kind, clusterctl, and the stackit CLI. You also need a STACKIT project, service-account JSON key, existing network, image, and machine type.

Furthermore, make sure that the provided service-account has an appropriate set of permissions.

Place the downloaded service-account JSON key at .stackit/cluster-api-provider-stackit.json inside the repo (create the .stackit/ directory if it does not exist yet). It is listed in .gitignore, so the key is never committed, and the path works identically for every contributor regardless of where the repo is checked out.

export STACKIT_PROJECT_ID=<project-uuid>
export STACKIT_REGION=eu01
export STACKIT_NETWORK_ID=<network-uuid>
export STACKIT_IMAGE_ID=<image-uuid>
export STACKIT_MACHINE_TYPE=c2i.4
export STACKIT_SSH_KEY_NAME=""
export STACKIT_SERVICE_ACCOUNT_JSON_FILE=./.stackit/cluster-api-provider-stackit.json
export STACKIT_SERVICE_ACCOUNT_JSON_B64="$(base64 < "${STACKIT_SERVICE_ACCOUNT_JSON_FILE}" | tr -d '\n')"
export STACKIT_CLOUD_CONTROLLER_MANAGER_IMAGE=ghcr.io/stackitcloud/cloud-provider-stackit/cloud-controller-manager:v1.35.3

The default template (templates/cluster-template.yaml) does not configure SSH access. To use an SSH key, add sshKeyName: <key-name> to the StackitMachineTemplate specs before creating the workload cluster. If you use the bastion variant instead (templates/cluster-template-bastion.yaml), set STACKIT_SSH_KEY_NAME above to your key name, it is substituted into that template directly.

Create the management cluster

Optional: kind-config.yaml for enterprise proxies (e.g. Zscaler)

If your machine sits behind a TLS-intercepting enterprise proxy such as Zscaler, outbound HTTPS calls made from inside the kind node container (pulling images, talking to the STACKIT API, etc.) will fail certificate validation. The node runs as its own container with its own OS certificate store, which does not include the proxy's root CA even though your host already trusts it. Mount the host's CA bundle into the node at the same path it expects:

kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
  extraMounts:
  - hostPath: /etc/ssl/certs/ca-certificates.crt
    containerPath: /etc/ssl/certs/ca-certificates.crt
    readOnly: true

Save this as kind-config.yaml in the repo root before running kind create cluster below. If you are not behind such a proxy, drop the --config kind-config.yaml flag from the command.

kind create cluster --name capi-stackit
kubectl config use-context kind-capi-stackit

clusterctl init \
  --config hack/clusterctl-local.yaml \
  --core cluster-api \
  --bootstrap kubeadm \
  --control-plane kubeadm

Install credentials and provider

kubectl create secret generic stackit-credentials \
  --namespace default \
  --from-literal=project-id="${STACKIT_PROJECT_ID}" \
  --from-file=serviceaccount.json="${STACKIT_SERVICE_ACCOUNT_JSON_FILE}"

export IMG=cluster-api-provider-stackit:dev
make docker-build IMG="${IMG}"
kind load docker-image "${IMG}" --name capi-stackit
make deploy IMG="${IMG}"

kubectl rollout status \
  -n cluster-api-provider-stackit-system \
  deployment/cluster-api-provider-stackit-controller-manager

Create a workload cluster

export CLUSTER_NAME=stackit-workload
export NAMESPACE=default
export KUBERNETES_VERSION=v1.35.3
export KUBERNETES_APT_REPOSITORY_MINOR=v1.35
export CONTROL_PLANE_MACHINE_COUNT=1
export WORKER_MACHINE_COUNT=1
export STACKIT_CREDENTIALS_SECRET_NAME=stackit-credentials

clusterctl generate cluster "${CLUSTER_NAME}" \
  --from templates/cluster-template.yaml \
  --target-namespace "${NAMESPACE}" \
  > cluster.yaml
kubectl apply -f cluster.yaml

Watch progress:

kubectl get cluster,machine,stackitcluster,stackitmachine -n "${NAMESPACE}"
kubectl logs \
  -n cluster-api-provider-stackit-system \
  deployment/cluster-api-provider-stackit-controller-manager \
  -c manager \
  --tail=100

After the workload API is reachable, install a CNI:

clusterctl get kubeconfig "${CLUSTER_NAME}" -n "${NAMESPACE}" > /tmp/"${CLUSTER_NAME}".kubeconfig
make install-workload-cni WORKLOAD_KUBECONFIG=/tmp/"${CLUSTER_NAME}".kubeconfig

Clean up

kubectl delete cluster "${CLUSTER_NAME}" -n "${NAMESPACE}"
kubectl get cluster,machine,stackitcluster,stackitmachine -A

make undeploy
make uninstall
kind delete cluster --name capi-stackit

If deletion is interrupted, inspect remaining cloud resources:

stackit server list --project-id "${STACKIT_PROJECT_ID}" --region "${STACKIT_REGION}"
stackit load-balancer list --project-id "${STACKIT_PROJECT_ID}" --region "${STACKIT_REGION}"