This is a Cluster API infrastructure provider for MAAS.
- Kubernetes v1.29.0+
- MAAS 3.0+
- Cluster API v1.5.0+
Refer image-generation/
MAAS in-memory deployment allows machines to run directly from RAM without writing to disk. This feature is useful for ephemeral workloads, testing environments, or scenarios where you want to preserve disk state.
To use the in-memory deployment feature, your MAAS installation must be running one of the following versions:
| MAAS Version | Status |
|---|---|
| >= 3.5.10 | ✅ Supported |
| >= 3.6.3 | ✅ Supported |
| >= 3.7.1 | ✅ Supported |
- Minimum RAM: Machines must have at least 16GB of RAM for proper functionality when using in-memory deployment.
To enable in-memory deployment, set deployInMemory: true in your MaasMachineTemplate spec:
apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
kind: MaasMachineTemplate
metadata:
annotations:
name: mt-worker-memory
namespace: test
spec:
template:
spec:
deployInMemory: true
image: custom/your-image
minCPU: 4
minMemory: 16384
resourcePool: default
tags:
- memory- Create kind cluster
make docker-build- Setup clusterctl configuration
~/.cluster-api/clusterctl.yaml
# MAAS access endpoint and key
MAAS_API_KEY: <maas-api-key>
MAAS_ENDPOINT: http://<maas-endpoint>/MAAS
MAAS_DNS_DOMAIN: maas.domain
# Cluster configuration
KUBERNETES_VERSION: v1.33.5
CONTROL_PLANE_MACHINE_IMAGE: custom/u-2204-0-k-1335-0
CONTROL_PLANE_MACHINE_MINCPU: 4
CONTROL_PLANE_MACHINE_MINMEMORY: 8192
WORKER_MACHINE_IMAGE: custom/u-2204-0-k-1335-0
WORKER_MACHINE_MINCPU: 4
WORKER_MACHINE_MINMEMORY: 8192
# Selecting machine based on resourcepool (optional) and machine tag (optional)
CONTROL_PLANE_MACHINE_RESOURCEPOOL: resorcepool-controller
CONTROL_PLANE_MACHINE_TAG: hello-world
WORKER_MACHINE_RESOURCEPOOL: resourcepool-worker
WORKER_MACHINE_TAG: hello-world
- Initialize infrastructure
clusterctl init --infrastructure maas:v0.8.0clusterctl init substitutes MAAS_ENDPOINT/MAAS_API_KEY into the
capmaas-manager-bootstrap-credentials secret (in the capmaas-system namespace)
and wires it into the controller — you do not need to create the secret by hand.
- Generate and create cluster
clusterctl generate cluster t-cluster --infrastructure=maas:v0.8.0 --kubernetes-version v1.33.5 --control-plane-machine-count=1 --worker-machine-count=3 | kubectl apply -f -
make test- Set
IMGto the controller image you control (registry + image + tag). This same image must be used fordocker-build,docker-push, anddev-manifestsso that the generatedinfrastructure-components.yamlpoints at the image you actually pushed. Export it once so every step picks it up:
export IMG=<your-registry>/cluster-api-provider-maas-controller-amd64:v0.8.0- Build and push the controller image:
make docker-build && make docker-push- Generate dev manifests.
dev-manifestsrequiresIMGto be set — it errors out if it is empty, since an unsetIMGproduces manifests with an empty controller image:
make dev-manifests IMG=$IMG- Move _build/dev/ directory contents to ~/.cluster-api/overrides v0.8.0 depending on version you are working with
.
├── clusterctl.yaml
├── overrides
│ ├── infrastructure-maas
│ └── v0.8.0
│ ├── cluster-template.yaml
│ ├── infrastructure-components.yaml
│ └── metadata.yaml
└── version.yaml
# Test MAAS API integration
./maas-test-linux --test-vm-host --node-ip=<node-ip> --maas-endpoint=http://<maas-server>:5240/MAAS --maas-api-key="YOUR_MAAS_API_KEY" --zone=default --resource-pool=default
- Run
clusterctl init --infrastructure maas:v0.8.0- Generate cluster using
clusterctl generate cluster t-cluster --infrastructure=maas:v0.8.0 | kubectl apply -f -or
clusterctl generate cluster t-cluster --infrastructure=maas:v0.8.0 --kubernetes-version v1.33.5 > my_cluster.yaml
kubectl apply -f my_cluster.yamlor
clusterctl generate cluster t-cluster --infrastructure=maas:v0.8.0 --kubernetes-version v1.33.5 --control-plane-machine-count=1 --worker-machine-count=3 > my_cluster.yaml
kubectl apply -f my_cluster.yamlThis provider supports dynamic LXD VM creation for workload clusters. This involves two main stages:
- HCP — Host Control Plane: convert bare-metal MAAS machines into LXD VM hosts.
- WLC — Workload Cluster: provision LXD VMs on those hosts for workload clusters.
👉 See docs/HCP_WLC_GUIDE.md for a step-by-step guide (prerequisites, templates, and field reference).
We've created test utilities to validate the LXD integration:
- LXD Initialization Test: Tests LXD initialization using the official LXD Go client.
- VM Host Registration Test: Tests VM host registration with MAAS using direct API calls.
- MAAS API Test: Tests MAAS API integration for VM host management and VM creation.
To build and transfer these test utilities to a target node:
cd lxd-test-tmp
./build-and-transfer.sh --host <target-host> [--key <path/to/key.pem>] [--user <username>]Then on the target node:
# Test LXD initialization
sudo ./lxd-test-linux --storage-backend=zfs --storage-size=50 --network-bridge=br0
# Test VM host registration
./vmhost-test-linux --node-ip=<node-ip> --maas-endpoint=http://<maas-server>:5240/MAAS --maas-api-key="YOUR_MAAS_API_KEY" --zone=default --resource-pool=default
# Test MAAS API integration
./maas-test-linux --test-vm-host --node-ip=<node-ip> --maas-endpoint=http://<maas-server>:5240/MAAS --maas-api-key="YOUR_MAAS_API_KEY" --zone=default --resource-pool=defaultThe provider uses the MAAS API to manage machines and LXD VMs. It does not use direct LXD socket connections or CLI commands, ensuring it works correctly even when the controller is running on a different host than the LXD host.
Please read CONTRIBUTING.md for details on our code of conduct, and the process for submitting pull requests to us.