Skip to main content

MachineRequest

A MachineRequest represents a request to provision a virtual machine on an infrastructure provider.

API Version

butler.butlerlabs.dev/v1alpha1

Scope

Namespaced

Short Name

mr

Description

MachineRequest is the interface contract between Butler's orchestration controllers and infrastructure provider controllers. The bootstrap controller creates MachineRequest resources for management cluster nodes. The butler-controller creates them for tenant cluster workers. Provider controllers (butler-provider-harvester, butler-provider-nutanix, etc.) watch for MachineRequest resources, provision the requested VM, and update the status with the assigned IP address.

The MachineRequest spec is provider-agnostic. All provider-specific details (endpoint, network, image defaults) come from the referenced ProviderConfig.

Specification

Full Example

apiVersion: butler.butlerlabs.dev/v1alpha1
kind: MachineRequest
metadata:
name: butler-mgmt-cp-0
namespace: butler-system
spec:
providerRef:
name: harvester-prod
namespace: butler-system
machineName: butler-mgmt-cp-0
role: control-plane
cpu: 4
memoryMB: 16384
diskGB: 100
extraDisks:
- sizeGB: 500
storageClass: longhorn
image: "default/talos-v1.9.2"
userData: |
#cloud-config
...
labels:
butler.butlerlabs.dev/cluster: butler-mgmt
butler.butlerlabs.dev/role: control-plane

Spec Fields

FieldTypeRequiredValidationDescription
providerRefProviderReferenceYes--References the ProviderConfig with infrastructure credentials.
machineNamestringYes1-63 chars, DNS-safeDesired VM name. Must be unique within the provider's namespace or project.
roleMachineRoleYesEnumMachine role: control-plane or worker.
cpuint32Yes1-128Virtual CPU cores.
memoryMBint32Yesmin 1024Memory in megabytes.
diskGBint32Yesmin 10Root disk size in gigabytes.
extraDisks[]DiskSpecNo--Additional disks to attach.
imagestringNo--OS image override. Format is provider-specific (see below). Defaults to the image configured in ProviderConfig.
userDatastringNo--Cloud-init user data. Typically contains the Talos machine configuration.
networkDatastringNo--Cloud-init network configuration.
labelsmap[string]stringNo--Key-value pairs applied to the VM in the provider.

DiskSpec

FieldTypeRequiredValidationDescription
sizeGBint32Yesmin 1Disk size in gigabytes.
storageClassstringNo--Provider-specific storage class or tier.

Image Format by Provider

ProviderFormatExample
Harvesternamespace/image-namedefault/talos-v1.9.2
NutanixUUIDa1b2c3d4-e5f6-7890-abcd-ef1234567890
ProxmoxTemplate ID or image name9000
GCPImage family or self linkprojects/my-project/global/images/talos-v1-9-2
AWSAMI IDami-0abcdef1234567890
AzureImage reference/subscriptions/.../images/talos-v1-9-2

Status

status:
phase: Running
providerID: "abc123-def456"
ipAddress: "10.40.0.10"
ipAddresses:
- "10.40.0.10"
macAddress: "52:54:00:12:34:56"
conditions:
- type: Ready
status: "True"
lastTransitionTime: "2026-03-10T12:00:00Z"
reason: "VMRunning"
message: "Virtual machine is running"
lastUpdated: "2026-03-10T12:00:00Z"
observedGeneration: 1

Status Fields

FieldTypeDescription
phaseMachinePhaseCurrent lifecycle phase (see Phases below).
providerIDstringProvider-specific VM identifier (Harvester VM UID, Nutanix VM UUID, etc.).
ipAddressstringPrimary IP address. Set when phase reaches Running.
ipAddresses[]stringAll IP addresses assigned to the machine.
macAddressstringPrimary MAC address.
failureReasonstringMachine-readable failure reason.
failureMessagestringHuman-readable failure details.
conditions[]ConditionStandard Kubernetes conditions.
lastUpdatedTimeTimestamp of the last status update.
observedGenerationint64Last observed spec generation.

Phases

PhaseDescription
PendingRequest received, not yet processed by the provider controller.
CreatingProvider controller is creating the VM.
RunningVM is running and has an IP address.
FailedVM creation failed. Check failureReason and failureMessage.
DeletingVM is being deleted.
DeletedVM has been deleted.
UnknownVM state cannot be determined.

Provider Controller Contract

Every provider controller must:

  1. Watch MachineRequest resources filtered by its provider type
  2. Read credentials from the ProviderConfig referenced by providerRef
  3. Create a VM matching the requested resources (CPU, memory, disk)
  4. Update status.phase through the lifecycle: Pending, Creating, Running
  5. Set status.ipAddress when the VM obtains an IP
  6. Add a finalizer to ensure VM cleanup on deletion
  7. Delete the VM and remove the finalizer during CR deletion
  8. Record Kubernetes events for audit trail

kubectl Output

$ kubectl get mr -n butler-system
NAME MACHINE ROLE PHASE IP AGE
butler-mgmt-cp-0 butler-mgmt-cp-0 control-plane Running 10.40.0.10 30m
butler-mgmt-cp-1 butler-mgmt-cp-1 control-plane Running 10.40.0.11 30m
butler-mgmt-cp-2 butler-mgmt-cp-2 control-plane Running 10.40.0.12 30m
butler-mgmt-w-0 butler-mgmt-w-0 worker Running 10.40.0.20 28m

See Also