A Cluster API infrastructure provider for Xen Orchestra. Manages the full lifecycle of VMs on XenServer / XCP-ng pools as Kubernetes worker and control plane nodes.
Prerequisites: A management cluster (Kind, k3s, etc.), clusterctl, Xen Orchestra access (VM template UUID, pool UUID, network name).
# 1. Install CAPI
clusterctl init --bootstrap kubeadm --control-plane kubeadm
# 2. Deploy the vates provider
kubectl apply -f https://raw.githubusercontent.com/vatesfr/cluster-api-provider-vates/refs/heads/main/dist/install.yaml
# 3. Create the XO credentials secret
kubectl create secret generic xo-credentials -n capi-system \
--from-literal=url="https://<your-xoa>" \
--from-literal=token="<your-xo-token>" \
--from-literal=insecure="true"All VM templates must have cloud-init support enabled and Xen guest tools installed and running. Export your Xen Orchestra values and generate the cluster from the kubeadm template:
export CP_HOST=<your-cp-vip> # control plane VIP
export CP_PORT=6443
export CP_LB=kube-vip
export CP_SUBNET=16
export VM_NAME_PREFIX=my-cluster
export XO_TEMPLATE_UUID=<your-vm-template-uuid> # no pool ID, must be bootable
export XO_POOL_UUID=<your-pool-uuid>
export XO_NETWORK_UUID=<your-network-uuid>
clusterctl generate cluster my-cluster \
--from templates/kubeadm/base/clusterctl/almalinux-fromscratch.yaml \
--kubernetes-version v1.36.1 \
--control-plane-machine-count 3 --worker-machine-count 2 | kubectl apply -f -The kubeadm flow also ships ClusterClass-based variants (managed topologies,
almalinux-prefilled / almalinux-fromscratch) used through the base/ +
overlays/ layout. This requires ClusterTopology enabled and is an alternative
to the flat template above. See
templates/kubeadm/README.md for the full file
contents.
clusterctl needs to know where the provider lives, via
~/.config/cluster-api/clusterctl.yaml (the file clusterctl reads — not
~/.config/clusterctl/).
For local development, one command regenerates dist/, refreshes the local
clusterctl overrides and creates the config file (if missing):
make -f Makefile.dev dev-overridesIf an existing config does not register vates (the command warns about it), add the entry manually:
providers:
- name: vates
type: InfrastructureProvider
url: file://${HOME}/.config/cluster-api/overrides/infrastructure-vates/v0.1.0/infrastructure-components.yamlFor a published release, register the GitHub release instead (no repo clone needed):
providers:
- name: vates
url: https://github.com/vatesfr/cluster-api-provider-vates/releases/latest/infrastructure-components.yaml
type: InfrastructureProviderThen:
clusterctl init --infrastructure vates:v0.1.0
clusterctl generate cluster my-cluster --infrastructure vates:v0.1.0 \
--control-plane-machine-count 3 --worker-machine-count 2clusterctl generate cluster (without --from) uses the provider's default
cluster-template.yaml — shipped in dist/ for releases. See
RELEASING.md for how to publish a release.
The vates provider also supports Talos Linux as an
immutable, cloud-init-free alternative to kubeadm. The TalosControlPlane and
TalosConfig CRDs come from the Talos bootstrap / control plane providers
(CABPT / CACPPT). Install them alongside the vates provider:
clusterctl init --bootstrap talos --control-plane talos
dist/install.yamldeploys the vates provider but not CAPI or the Talos CRDs. If you install the vates provider this way, you must still run theclusterctl initabove forTalosControlPlane/TalosConfigto exist. See templates/talos/README.md for both installation options.
The default vates RBAC only binds the kubeadm control plane (KCP). For the Talos
flow, grant the Talos providers (CACPPT / CABPT) access to the XOMachineTemplate
resources:
kubectl apply -k config/rbac/talosPrerequisites: a Talos VM template built for the nocloud platform with
the siderolabs/xen-guest-agent extension, never booted, and with
viridian: false in XO.
The templates/talos/base/ templates use placeholders and must not be
edited directly. Instead, create an overlay to hold your environment's
values (real UUIDs, VIP address, etc.).
Create a directory for your environment with a kustomization.yaml that pulls
in base/ and patches each resource with your values:
templates/talos/overlays/my-env/
├── kustomization.yaml
├── patch-xomachinetemplate-cp.yaml # templateID, poolID, networkID
├── patch-xomachinetemplate-worker.yaml # templateID, poolID, networkID
├── patch-controlplane.yaml # control plane VIP + machine config
└── patch-xocluster.yaml # control plane endpoint
Wherever a YAML contains a <your-...-uuid> or <your-cp-vip> placeholder,
replace it with your Xen Orchestra template ID, pool UUID, network UUID, and
control plane VIP. Then apply:
kubectl apply -k templates/talos/overlays/my-env/See templates/talos/README.md for the complete file contents.
Contributors building from source (build/push loop for kind and k3s, clusterctl overrides, tests, debugging): see DEVELOPMENT.md.
├── api/ # CRD types (+kubebuilder markers)
├── cmd/ # Manager entry point
├── internal/
│ ├── bootstrap/ # Bootstrap providers (kubeadm, talos)
│ ├── controller/ # Reconciliation logic
│ └── kubevip/ # kube-vip static pod injection
├── config/
│ ├── crd/ # Generated CRDs (DO NOT EDIT)
│ ├── manager/ # Manager Deployment
│ ├── rbac/ # RBAC: role.yaml generated (DO NOT EDIT), bindings/ + talos/ hand-written
├── templates/
│ ├── kubeadm/ # kubeadm cluster templates
│ │ ├── base/ # ClusterClass + machinetemplates (placeholders)
│ │ ├── overlays/ # per-environment values (create one)
│ │ ├── clusterctl/ # Template for clusterctl generate
│ │ └── packer/ # AlmaLinux cloud image builder
│ ├── talos/ # Talos cluster templates (base + overlays)
│ └── README.md # Template usage guide
├── examples/ # Example manifests (kind)
├── dist/ # Generated release artifacts
│ ├── install.yaml # kubectl apply bundle
│ ├── infrastructure-components.yaml # clusterctl bundle
│ ├── cluster-template.yaml # clusterctl template (kubeadm almalinux-fromscratch)
│ └── chart/ # Helm chart
# Generate dist/ from the current source
make release-manifests IMG=ghcr.io/vatesfr/cluster-api-provider-vates:latestdist/ contains the three assets required by clusterctl:
infrastructure-components.yaml, metadata.yaml and cluster-template.yaml.
See RELEASING.md for the full release workflow.
Copyright 2026.
Licensed under the Apache License, Version 2.0.