VirtualMachine¶
VirtualMachine is the user-facing CRD. Everything in banlieue's design is
oriented around keeping its shape small, uniform, and provider-agnostic.
The authoritative definition lives in
crates/banlieue-api/src/banlieue/virtualmachine.rs.
Generated CRD YAML lives in deploy/crds/ and is produced by the crdgen
binary — see Architecture.
Shape (illustrative)¶
apiVersion: banlieue.io/v1alpha1
kind: VirtualMachine
metadata:
name: db-prod-01
spec:
classRef:
name: db-prod-large # name of a VMClass (CPU/memory/disk shape)
imageRef:
name: ubuntu-22-04 # name of a VMImage (boot image)
placement:
providerSelector:
matchLabels: { dc: dc1, env: prod } # which Provider(s) may schedule this VM
userData: # optional cloud-init / ignition / sysprep
secretRef: # or configMapRef for non-sensitive data
name: db-prod-01-cloudinit
key: user-data # defaults to "user-data" when omitted
desiredPowerState: PoweredOn
Note what is not there: no vsphere: block, no proxmox: block, no
backend-specific knobs. That's deliberate; see
Abstraction principle.
Status, uniformly¶
VirtualMachine.status follows the K8s conventions: a conditions[] array
plus a small set of well-known fields. Every provider produces the same
condition vocabulary:
Condition type |
Meaning |
|---|---|
Ready |
The VM exists, is provisioned, and is reachable. |
Scheduled |
A Provider matching placement has been selected. |
PlacementValid |
The requested VMClass/VMImage/placement combination is resolvable. |
InfrastructureReady |
The backend infrastructure CR reports Ready. |
Migrating |
(optional) A recreate-based migration to a new Provider/failure domain is in progress. |
status.initialization.provisioned (a boolean, not a condition) tracks
whether the backend has ever accepted the spec.
Status is mirrored from the underlying infrastructure CR; the main
controller never sets provisioned=true on its own. See
Architecture → Provision a VM.
Lifecycle¶
Spec field reference¶
The list below is illustrative for Phase 0–1A. Use
kubectl explain virtualmachine.spec(or the API reference) for the authoritative shape.
classRef.name(string, required) — references aVMClass(CPU / memory / disks).imageRef.name(string, required) — references aVMImage(boot image).placement.providerSelector/placement.failureDomainSelector(label selectors, optional) — whichProvider(s)/failure domains may schedule this VM. There is no direct-by-nameProviderreference; the scheduler matches labels.desiredPowerState(string, optional) —PoweredOn(default) |PoweredOff|Suspended.userData(object, optional) — references a Secret (secretRef) or ConfigMap (configMapRef) carrying the cloud-init / ignition / sysprep payload (exactly one must be set). See ADR-0025 and ADR-0038.
Per-VM overrides (deltas, not primary definitions)¶
A VirtualMachine inherits its hardware shape and network topology from the
VMClass it references. Two optional fields let you override specific values
for a single VM without creating a new class:
| Field | What it overrides | Type |
|---|---|---|
hardwareOverride.cpus |
CPUs from VMClass.spec.hardware.cpus |
u32? |
hardwareOverride.memoryMiB |
Memory from VMClass.spec.hardware.memoryMiB |
u32? |
hardwareOverride.diskOverrides |
Disk sizes from VMClass.spec.hardware.disks |
list, keyed by name |
networkOverrides |
IPAM on a named interface from VMClass.spec.network.interfaces |
list, keyed by name |
These are deltas, not primary definitions. The VMClass remains the
authoritative source for the VM's shape. Only the fields you set in an
override replace the class value; everything else is inherited unchanged.
Use overrides sparingly. Their purpose is to accommodate the rare VM that
genuinely needs a different budget than its class defines — for example, a
database primary bumped to 16 CPUs while all other replicas use the 4-CPU
class shape, one VM that needs a larger data disk, or one VM that needs a
static IP while the rest use DHCP. If you find yourself setting the same
override on every VM of a given class, create a new VMClass instead.
spec:
classRef:
name: db-prod-large
# Delta: bump memory + data disk for this one VM; CPUs and OS disk stay as
# the class defines.
hardwareOverride:
memoryMiB: 65536
diskOverrides:
- name: data
sizeGiB: 2000
# Delta: pin eth0 to a static address; other interfaces use the class IPAM.
networkOverrides:
- name: eth0
static:
address: 192.0.2.90
prefix: 24
gateway: 192.0.2.1
nameservers: [192.0.2.53]
Related CRDs¶
- VMClass — flavour / size shape (CPU, memory, disk).
- VMImage — boot image source.
- Provider — which backend serves this VM.
The infrastructure CRDs (VSphereMachine, future ProxmoxMachine,
LibvirtMachine) are documented under Provider Model and
Infrastructure CRDs & CAPI. The user normally doesn't
touch them.