A Cluster API infrastructure provider for
STACKIT, built on the official
STACKIT Go SDK. It provisions
self-managed Kubernetes clusters on STACKIT's IaaS compute service (services/iaas) —
the same role CAPD (Docker) or CAPO (OpenStack) play for their platforms: this
repository supplies the infrastructure CRDs and controllers, while the standard
upstream CAPI kubeadm bootstrap and control-plane providers handle the actual
Kubernetes bootstrapping.
Given a Cluster + StackitCluster + KubeadmControlPlane +
StackitMachineTemplate(s) + MachineDeployment, the controllers in this repo:
StackitCluster— creates (or adopts, ifspec.network.idis set) an isolated network, a security group (SSH, Kubernetes API, and unrestricted intra-cluster traffic), and reserves a public IP for the control-plane endpoint.StackitMachine— creates a STACKIT server for eachMachine, attaching the cluster's network/security group, waiting for the bootstrap data secret, and (for the first control-plane machine) attaching the cluster's reserved public IP.StackitClusterIdentity— points at aSecretholding STACKIT credentials (a service account key or bearer token), so differentStackitClusters can use different STACKIT projects/credentials.
CRDs: StackitCluster, StackitMachine, StackitMachineTemplate,
StackitClusterIdentity (all infrastructure.cluster.x-k8s.io/v1alpha1), implementing
the Cluster API v1beta2 contract.
- Single control-plane endpoint, no managed load balancer. The control-plane
endpoint is a single reserved public IP attached to the first control-plane machine —
it does not fail over automatically if that machine is replaced. For real HA,
run kube-vip as a static pod on the control-plane machines
(the standard approach for bare-IaaS CAPI providers without a managed L4 LB), or
set
spec.controlPlaneEndpointon theStackitClusterto point at your own externally managed load balancer instead of letting the controller allocate one. Wiring STACKIT's Load Balancer service (services/loadbalancer/services/lbapplicationin the SDK) in as a first-class option is a natural follow-up. - No ClusterClass /
StackitClusterTemplatesupport yet. - No SSH key auto-provisioning.
StackitMachine.spec.sshKeyNamemust reference an existing STACKIT key pair; the controllers don't create one for you. - No webhooks. Validation is enforced via CRD OpenAPI schema (required fields, string patterns) rather than admission webhooks, so there's no cert-manager dependency, but immutability rules (e.g. "you can't change a StackitMachine's imageId after creation") aren't enforced at the API level.
-
Go 1.24+
-
A STACKIT project and a service account key (or bearer token) with permissions to manage IaaS resources in that project
-
A management cluster with Cluster API core, kubeadm bootstrap, and kubeadm control-plane providers already installed, e.g. via:
clusterctl init # install clusterctl curl -L https://github.com/kubernetes-sigs/cluster-api/releases/latest/download/clusterctl-linux-amd64 -o clusterctl chmod +x clusterctl sudo mv clusterctl /usr/local/bin/clusterctl -
A STACKIT image with a Kubernetes-ready OS (containerd, kubeadm/kubelet preinstalled, or use image-builder to build one) — note its ID.
First apply the core components, That installs clusters.cluster.x-k8s.io, machines.cluster.x-k8s.io, machinesets, machinedeployments, etc. Once those CRDs exist, your stackitcluster and stackitmachine controllers will successfully start their Cluster/Machine EventSources and the errors will stop repeating.
kubectl apply -f https://github.com/kubernetes-sigs/cluster-api/releases/download/v1.14.0/core-components.yamlmake manifests generate # regenerate CRDs/RBAC and deepcopy code after any api/ change
make test # unit tests + envtest-backed controller tests
make docker-build docker-push IMG=ghcr.io/bartvanbenthem/cluster-api-provider-stackit:latest
make install # apply the CRDs to your management cluster
make deploy IMG=ghcr.io/bartvanbenthem/cluster-api-provider-stackit:latest # deploy the managermake manifests/make generate intentionally scope controller-gen to ./api/... ./cmd/... ./internal/... ./test/... — the vendored stackit-sdk-go/ reference copy in
this repo is not part of this module and is excluded.
-
Create the credentials
SecretandStackitClusterIdentity:kubectl create secret generic my-cluster-credentials \ --from-literal=serviceAccountKey="$(cat service-account-key.json)" kubectl apply -f - <<EOF apiVersion: infrastructure.cluster.x-k8s.io/v1alpha1 kind: StackitClusterIdentity metadata: name: my-cluster-credentials spec: secretRef: name: my-cluster-credentials EOF
-
Render
templates/cluster-template.yamlwith the variables it needs (see the comment block at the top of that file for the full list) and apply it:export CLUSTER_NAME=my-cluster export NAMESPACE=default export STACKIT_PROJECT_ID=<your project id> export STACKIT_IMAGE_ID=<your image id> export STACKIT_SERVICE_ACCOUNT_KEY="$(cat service-account-key.json)" export KUBERNETES_VERSION=v1.31.0 clusterctl generate yaml --from templates/cluster-template.yaml | kubectl apply -f -
(
clusterctl generate yaml --from <file>performs the same${VAR}substitutionclusterctl generate clusterdoes, without requiring this provider to be published to aclusterctlprovider repository yet.envsubst < templates/cluster-template.yaml | kubectl apply -f -works identically.) -
Watch it come up:
kubectl get cluster,stackitcluster,kubeadmcontrolplane,machines,stackitmachines clusterctl describe cluster my-cluster
metadata.yaml at the repo root is the clusterctl provider metadata file (contract
v1beta2); once this provider has a tagged GitHub release with CRD/manager manifests
attached, clusterctl init --infrastructure stackit can install it directly, and a
clusterctl.yaml provider entry can point at the release instead of local files.
api/v1alpha1/— CRD Go types (StackitCluster,StackitMachine,StackitMachineTemplate,StackitClusterIdentity)internal/cloud/— thin wrapper aroundstackit-sdk-go/services/iaas/v2api(networks, security groups, servers, public IPs, failure domains), built around the SDK's owniaas.DefaultAPIinterface so it's mockable in testsinternal/controller/— the four reconcilerstemplates/cluster-template.yaml— a full working cluster definition (Cluster+StackitCluster+KubeadmControlPlane+StackitMachineTemplate×2 +KubeadmConfigTemplate+MachineDeployment)config/— kustomize manifests (CRDs, RBAC, manager Deployment)stackit-sdk-go/— a vendored reference copy of the STACKIT SDK for local browsing; this module actually depends on the publishedgithub.com/stackitcloud/stackit-sdk-gomodule viago.mod, not this directory