The blueprint designer in a VCF Automation 9.1 All Apps organization offers sixteen items in three groups. Drag one onto the canvas and you get a few lines of YAML. What you may write underneath them is spread across the VM Service, VKS, NSX VPC and Automation guides. For some items, it’s written down nowhere at all.
This guide puts it in one place. For each item, you get:
- what it creates, and the YAML behind it;
- every field the platform accepts;
- a minimal snippet, and recipes for the common jobs;
- the status fields worth reading;
- the traps we hit.
Three things make it more than a list from memory, which, given my memory, is just as well:
- The field lists come from the platform. VCF Automation publishes the schema of every blueprint resource type through its API. The designer carries the schema of every palette item. The Supervisor publishes the definition of every Kubernetes kind it serves, and VCF Automation’s VPC API publishes its own. Where they disagree (and they do), the tables follow what the platform enforces.
- Every snippet was checked. Each one went through VCF Automation’s validation API, and every Kubernetes manifest through a server-side dry run on the Supervisor. Five test blueprints (all of them in the downloads) deployed every item for real. The remaining recipes are ones our lab catalog deploys every day.
- The traps are real. Several of the most useful lines in this guide come from things that went wrong while testing: a NAT rule that ignored its port, a firewall rule that grew an “Any”, a request that waits for an address that can never come.
We checked it on our lab platform, f06:
- VCF Automation 9.1.0;
- a Supervisor on Kubernetes 1.32.9, with the VM Operator API at
v1alpha5; - VKS with ClusterClasses up to
builtin-generic-v3.6.0, and Kubernetes releases up to 1.35.5; - NSX VPCs.
Names in the examples (f06, nested-pod, vpc-student05,
vsan-default-storage-policy) are ours; use yours.
In the field tables, Values gives a field’s choices and default. Where the
schema has neither, it gives an example, marked e.g.: the value from our
tested blueprints wherever one of them set the field, otherwise a typical one.
For an object or a list, the example is a short YAML flow value built from its
fields (... marks the ones left out). And <...> stands for a name of yours.
The shape of a blueprint
An All Apps blueprint is YAML with formatVersion: 2, its inputs, its
resources and its outputs:
formatVersion: 2
inputs:
vmName:
type: string
title: VM name
default: web-01
pattern: '^[a-z0-9]([-a-z0-9]*[a-z0-9])?$'
size:
type: string
title: Size
default: small
oneOf:
- {title: Small, const: small}
- {title: Medium, const: medium}
resources:
namespace:
type: CCI.Supervisor.Namespace
properties:
name: team-a-dev
existing: true
vm1:
type: CCI.Supervisor.Resource
properties:
context: ${resource.namespace.id}
manifest:
apiVersion: vmoperator.vmware.com/v1alpha5
kind: VirtualMachine
metadata:
name: ${input.vmName}
spec:
className: ${'best-effort-' + input.size}
imageName: ubuntu-24.04-server-cloudimg-amd64
storageClass: vsan-default-storage-policy
outputs:
vmName:
value: ${resource.vm1.object.metadata.name}
What the expressions can read:
| Expression | Value |
|---|---|
${input.<name>} | A request input. An input group from a property group is ${input.<group>.<property>}. |
${resource.<name>.<property>} | Another resource’s property; this also orders the two. object holds the live Kubernetes object of a Supervisor Resource. |
${propgroup.<group>.<property>} | A constant property group’s value. |
${secret.<name>} | A VCF Automation secret, from the organization or the project. |
${env.deploymentName}, ${count.index} | The deployment’s name; the instance number in a counted resource. |
${to_k8s_name(env.deploymentName, 63)} | A string made safe for a Kubernetes name, as Broadcom’s own samples use for generateName. |
Besides type and properties, each resource has dependsOn (an explicit
order) and allocatePerInstance (see count below). formatVersion: 2 also
allows metadata, variables, and an output named __deploymentOverview,
whose Markdown value becomes the deployment’s overview page.
How the palette maps to YAML
Behind the sixteen items there are only five resource types, and one of them
isn’t in the palette. Most items are a type with part of its YAML already
filled in. For the workload items, that’s a Kubernetes apiVersion and
kind; for the VPC items, it’s a VPC configuration kind.
| Palette item | YAML type | Pre-filled |
|---|---|---|
| Supervisor Namespace | CCI.Supervisor.Namespace | |
| VPC group | ||
| VPC | CCI.VPC | |
| VPC Configuration | CCI.VPC.Configuration | nothing: you set kind |
| Attachment | CCI.VPC.Configuration | kind: VPCAttachment |
| IP Address Allocation | CCI.VPC.Configuration | kind: VPCIPAddressAllocation |
| NAT Rule | CCI.VPC.Configuration | kind: VPCNATRule |
| Group | CCI.VPC.Configuration | kind: VPCNetworkSecurityGroup |
| Gateway Firewall Policy | CCI.VPC.Configuration | kind: VPCGatewayFirewallPolicy |
| Workload group | ||
| Supervisor Resource | CCI.Supervisor.Resource | nothing: any manifest |
| Virtual Machine | CCI.Supervisor.Resource | vmoperator.vmware.com/v1alpha5 VirtualMachine |
| Virtual Machine Group | CCI.Supervisor.Resource | vmoperator.vmware.com/v1alpha5 VirtualMachineGroup |
| Virtual Machine Service | CCI.Supervisor.Resource | vmoperator.vmware.com/v1alpha3 VirtualMachineService |
| Subnet | CCI.Supervisor.Resource | crd.nsx.vmware.com/v1alpha1 Subnet |
| Persistent Volume Claim | CCI.Supervisor.Resource | v1 PersistentVolumeClaim |
| Secret | CCI.Supervisor.Resource | v1 Secret |
| Kubernetes Cluster | CCI.Supervisor.Resource | cluster.x-k8s.io/v1beta1 Cluster |
| (not in the palette) | Util.PasswordEntry |
Four consequences, worth knowing before any of the detail:
- Anything the Supervisor understands can go in a blueprint. The workload
items are shortcuts. The generic Supervisor Resource takes any manifest the
namespace accepts. Our lab blueprints rely on a kind the palette doesn’t
offer,
SubnetConnectionBindingMap, to carry VLANs. - The VPC items are a closed list.
CCI.VPC.Configurationtakes exactly the five kinds above. A VPC’s load balancer is a sixth kind in VCF Automation’s VPC API, and a blueprint can’t make one (see VPC). - VCF Automation validates the outside, the platform the inside. The
validation API checks the resource type’s own properties: required fields,
patterns, the namespace’s two shapes. It doesn’t look inside a
manifestor aconfigs[].spec: in our test,powerState: Sidewayspassed validation. Those are checked when the request runs. - The designer’s schemas are not the platform’s. The palette’s forms come from schemas bundled with VCF Automation, while the Supervisor and the VPC API check against their own. They disagree in a handful of places, listed next.
Where the designer and the platform disagree
We compared each palette item’s schema with the platform’s definition of the
same apiVersion and kind. We went field by field (every bit as gripping
as it sounds) and tested every difference:
| Item | The designer offers | What the platform does |
|---|---|---|
| Virtual Machine | affinity.zoneAffinity, affinity.zoneAntiAffinity, and VM affinity terms named ...IgnoredDuringExecution | Rejects them as unknown fields. VM affinity and anti-affinity take requiredDuringSchedulingPreferredDuringExecution and preferredDuringSchedulingPreferredDuringExecution. |
| Virtual Machine | no linuxPrep.password, linuxPrep.scriptText, crypto.vTPMMode, currentSnapshotName, or disk options at volume level | Accepts all of them. |
| Virtual Machine | bootOptions.firmware as BIOS or EFI, and bootOptions.enterBootSetup | spec.bootOptions.firmware: Unsupported value: "BIOS": supported values: "bios", "efi", and strict decoding error: unknown field "spec.bootOptions.enterBootSetup". |
Virtual Machine v1alpha4, v1alpha3 | network.nameServers | The field is nameservers, lower case. |
| Subnet | regionName, ipBlockNames, description | Rejects them. Accepts vlanConnectionName, which the designer doesn’t show. |
| Persistent Volume Claim | accessMode | strict decoding error: unknown field "spec.accessMode". The field is accessModes. |
| Kubernetes Cluster | cluster.x-k8s.io/v1beta1 | Serves it, with cluster.x-k8s.io/v1beta1 Cluster is deprecated; use cluster.x-k8s.io/v1beta2 Cluster. |
| Group | vmSelectors[].selector, podSelectors[].selector | spec.vmSelectors[0]: Required value: must specify at least one selector. The field is labelSelector; the API also offers propertySelector. |
| Gateway Firewall Policy | ruleCount | Computed by the API; not accepted. A rule’s from is required, though the schema says empty means any. |
None of this stops the designer from saving a blueprint. It surfaces when the request runs.
What every resource shares
Properties on every type
| Property | On | What it does |
|---|---|---|
count | all | How many instances to create. Default 1. |
allocatePerInstance | all (beside type) | Required for ${count.index}: without it the validator refuses the blueprint with should have allocatePerInstance property set to True. |
dependsOn | all (beside type) | Explicit order. A reference to another resource orders the two already. |
context | Supervisor Resource items | Required. The namespace the manifest goes into: ${resource.<namespace>.id}. |
existing | Namespace, Supervisor Resource items | true adopts what already exists instead of creating it. |
wait | Supervisor Resource items, VPC Configuration | When the resource counts as done. |
Recipe, two Secrets from one resource:
sec:
type: CCI.Supervisor.Resource
allocatePerInstance: true
properties:
count: 2
context: ${resource.ns.id}
manifest:
apiVersion: v1
kind: Secret
metadata:
name: ${'ref-s-' + count.index}
type: Opaque
stringData:
note: created by instance ${count.index}
The deployment then holds sec[0] and sec[1], and the namespace
ref-s-0 and ref-s-1.
wait: when a resource is finished
Without a wait, a Supervisor Resource is finished as soon as the Supervisor
accepts the manifest. That’s fine for a Secret, and wrong for a VM whose
address an output needs. wait takes conditions, fields, or both:
wait:
conditions: # status.conditions[] of the object
- type: Ready
status: "True"
- type: Ready
status: "False"
reason: Failed
indicatesFailure: true # this one fails the resource instead of finishing it
fields: # any field of the object, by path
- path: status.powerState
value: PoweredOn
skipWaitOnDelete: false # true: deletion does not wait for the object to be gone
A Supervisor Resource can also watch log output with executionLogs:
progressMessagePattern while a matching message appears, and
failureMessagePattern to fail the resource.
The designer pre-fills a wait for some items:
| Item | Designer’s default wait |
|---|---|
| Virtual Machine | condition VirtualMachineCreated = True |
| Virtual Machine Group | condition Ready = True |
| NAT Rule, Group | condition Realized = True |
| everything else | none |
The VM’s default came from a 9.0 problem: VM status could come back empty,
and Broadcom’s KB 435137 gave this wait as the workaround. That condition
is true before the VM is even on, let alone has an address.
VCF Automation also waits by itself in one place: a Virtual Machine Service
of type LoadBalancer is not finished until it has an external address,
with or without a wait. In a VPC without a load balancer, that address
never comes, and the request stays in progress until it times out. Ours was
still PARTIAL after ten minutes, with the service <pending> on the
Supervisor.
Reading a resource’s live state
Every Supervisor Resource exposes the object as the Supervisor sees it under
object, and a VPC Configuration exposes its objects under configs:
outputs:
vmIp:
value: ${resource.vm1.object.status.network.primaryIP4}
vmHost:
value: ${resource.vm1.object.status.nodeName}
lbIp:
value: ${resource.webLb.object.status.loadBalancer.ingress[0].ip}
publicIp:
value: ${resource.publicIp.configs[0].spec.allocationIPs}
Outputs are computed once, when the request finishes, and not refreshed
afterwards. A VM that waited only for PoweredOn finished before its guest
reported an address, and its IP output stayed empty for good. Waiting on the
condition that marks the guest’s network as configured fixes it. This one
gave the output 172.30.0.2:
wait:
conditions:
- type: VirtualMachineGuestNetworkConfigSynced
status: "True"
Checking a manifest before you deploy it
The fastest check we found is a server-side dry run with strict field validation, against the namespace the blueprint will use:
kubectl apply --dry-run=server --validate=strict -n <namespace> -f vm.yaml
It runs the Supervisor’s schema checks and admission webhooks, flags unknown
fields, and creates nothing. It works for every workload kind. It does not
work for the VPC kinds: VCF Automation’s VPC API ignores dryRun and creates
the object, as one of our probes found.
Supervisor Namespace
type: CCI.Supervisor.Namespace. Creates a vSphere Namespace through VCF
Automation, inside the project’s allocation, or adopts one that exists.
Everything in the Workload group needs one: their context points at it.
The schema has two shapes, and the validator enforces them: an existing
namespace takes name and existing: true and nothing else; a new one needs
generateName, className, regionName and vpcName.
| Property | Notes |
|---|---|
generateName | New namespace. Prefix; VCF Automation adds - and five random characters (ns-ref-bstk7). Must match ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$, so it cannot end in a hyphen. |
className | New namespace. The namespace class: limits, VM classes, storage classes and content libraries. |
regionName | New namespace. The region. |
vpcName | New namespace. The VPC its workloads use: an existing VPC’s name, or ${resource.<vpc>.name}. |
name + existing: true | Existing namespace. name alone matches neither shape. |
zones[] | Per vSphere Zone: name, cpuLimit, cpuReservation, memoryLimit, memoryReservation, all five required. |
storageClasses[] | name (the storage policy as the namespace names it) and limit. |
vmClasses[], contentSources[] | VM classes and image sources beyond the class’s own. |
sharedSubnetNames[], infraPolicyNames[], segName, description | Shared subnets, extra infrastructure policies, an Avi Service Engine Group, a description. |
Every field the platform accepts (25)
Field Type Req. Values Description namestring e.g. team-a-devSupervisor namespace name countinteger default 1The number of resource instances to be created. zonesarray of object e.g. [{name: domain-c9, cpuLimit: 4000M}]Zone overrides for the namespace zones[].namestring yes e.g. domain-c9Name of the zone zones[].cpuLimitstring yes e.g. 4000MCPU limit in M or G zones[].memoryLimitstring yes e.g. 8192MiMemory limit in Mi, Gi, or Ti zones[].cpuReservationstring yes e.g. 0MCPU reservation in M or G zones[].memoryReservationstring yes e.g. 0MiMemory reservation in Mi, Gi, or Ti segNamestring e.g. Default-GroupName of the Service Engine Group vpcNamestring e.g. vpc-student05Name of the vpc existingboolean default falseUse existing supervisor namespace classNamestring e.g. nested-podName of the supervisor namespace class vmClassesarray of object e.g. [{name: best-effort-small}]VM Class overrides for the namespace vmClasses[].namestring yes e.g. best-effort-smallName of the vm class regionNamestring e.g. f06Name of the region descriptionstring e.g. Team sandboxDescription of the supervisor namespace generateNamestring e.g. ns-demoSupervisor namespace generateName contentSourcesarray of object e.g. [{name: my-library, type: ContentLibrary}]Content Source overrides for the namespace contentSources[].namestring yes e.g. my-libraryName of the content source contentSources[].typestring yes default ContentLibraryType of the content source storageClassesarray of object e.g. [{name: vSAN Default Storage Policy, limit: 100Gi}]Storage Class overrides for the namespace storageClasses[].namestring yes e.g. vSAN Default Storage PolicyName of the storage class storageClasses[].limitstring yes e.g. 100GiStorage Class limit in Mi, Gi, or Ti infraPolicyNamesarray of string e.g. [<infrastructure policy>]Non-mandatory Infra Policy names sharedSubnetNamesarray of string e.g. [<shared subnet>]Name of subnets
Minimal, a new namespace with the zone and storage our class doesn’t set:
namespace:
type: CCI.Supervisor.Namespace
properties:
generateName: ns-demo
className: nested-pod
regionName: f06
vpcName: vpc-student05
storageClasses:
- name: vSAN Default Storage Policy
limit: 100Gi
zones:
- name: domain-c9
cpuLimit: 4000M
cpuReservation: 0M
memoryLimit: 8192Mi
memoryReservation: 0Mi
Recipes
A quota sized from the request, so a namespace never outgrows what was asked for. Our lab blueprints compute the limits from the requested sizes:
storageClasses: - name: vSAN Default Storage Policy limit: "${input.hosts * 200 + 'Gi'}" zones: - name: domain-c9 cpuLimit: "${input.hosts * 8000 + 'M'}" cpuReservation: 0M memoryLimit: "${input.hosts * 32768 + 'Mi'}" memoryReservation: 0MiDeploy into a namespace that already exists, for example one an administrator prepared:
namespace: type: CCI.Supervisor.Namespace properties: name: team-a-dev existing: true
Status worth reading: ${resource.<ns>.id} is
cci:<project>:<namespace>, which context takes.
Gotchas
- Whether
zonesandstorageClassesare optional depends on the namespace class. Ours sets neither, and VCF Automation refused the minimal shape in turn:Zone should be specified in Namespace or in Namespace class, thenStorage Class should be specified in Namespace or in Namespace class. - The zone
nameis the vSphere Zone. A Supervisor without zones still has one, named after its cluster (domain-c9on f06). - A VM can only use a VM class the namespace allows and an image from its content sources. The validator cannot know either; the request finds out.
VPC
type: CCI.VPC. Creates an NSX VPC in a region. Most blueprints use an
existing VPC, through the namespace’s vpcName. This item is for a
blueprint that brings its own network.
| Property | Notes |
|---|---|
generateName | Required. VCF Automation names the VPC <generateName>-<project>-<5 characters>: vpc-ref-default-project-y3698. |
regionName | Required. The region. |
privateIPs[] | The VPC’s private CIDRs. Empty uses the project’s default. |
Every field the platform accepts (4)
Field Type Req. Values Description countinteger default 1The number of resource instances to be created. privateIPsarray of string e.g. [10.200.0.0/20]List of private IPs to be used in the VPC regionNamestring yes e.g. f06Region name for the VPC generateNamestring yes e.g. vpc-appPrefix for the generated name of the VPC
vpc:
type: CCI.VPC
properties:
generateName: vpc-app
regionName: f06
privateIPs:
- 10.200.0.0/20
Status worth reading: id (cci:vpc:<project>:<name>), which every VPC
Configuration takes as vpc, and name, which a namespace takes as
vpcName.
Gotchas
- A new VPC reaches nothing outside itself until it has an
Attachment to a VPC connectivity profile; give the namespace
dependsOnon the attachment. privateIPsmust not overlap the connectivity profile’s Private Transit Gateway blocks, and the error only comes at attachment time:private IP CIDR 172.31.64.0/20 overlaps with private TGW IP block CIDR 172.31.0.0/16.- A blueprint cannot give its VPC a load balancer. In VCF Automation’s
VPC API the load balancer is its own kind,
LoadBalancer, andCCI.VPC.Configurationrefuses it:Failed to match exactly one schema (matched 0 out of 5). Without one, a LoadBalancer service never gets an address (and its request never finishes, seewait), and Broadcom’s VPC page warns that a VPC without load balancing cannot run VKS. For either, use a VPC made in the UI with Enable load balancing on, and name it in the namespace’svpcName.
VPC Configuration
type: CCI.VPC.Configuration. One item for every object that lives inside a
VPC, and kind chooses which. The five palette entries below are this item
with kind filled in. Each configs[] entry becomes one object, so one
resource can create several rules or groups of the same kind.
| Property | Notes |
|---|---|
vpc | Required. The VPC’s id: ${resource.vpc.id}, or an existing VPC’s cci:vpc:<project>:<name>. |
kind | Required. VPCAttachment, VPCIPAddressAllocation, VPCNATRule, VPCNetworkSecurityGroup or VPCGatewayFirewallPolicy, and nothing else. |
apiVersion | vpc.nsx.vmware.com/v1alpha1. |
configs[] | Required. Per object: generateName (required), spec, labels, annotations. |
wait | Applies to every object in configs. |
Every field the platform accepts (20)
Field Type Req. Values Description vpcstring yes e.g. ${resource.vpc.id}ID of the parent VPC this resource is associated with. kindstring yes e.g. VPCNATRuleThe kind of the resource (e.g., VPCNetworkSecurityGroup, VPCIPAddressAllocation, VPCNATRule, VPCAttachment). waitobject e.g. {fields: [{path: status.conditions[0].status, value: True}], ...}Wait conditions applied to all config resources. All resources must satisfy these conditions before the operation is considered complete. wait.fieldsarray of object e.g. [{path: status.conditions[0].status, value: True}]List of field conditions to wait for. wait.fields[].pathstring yes e.g. status.conditions[0].statusJSONPath to the field to check (e.g., status.phase). wait.fields[].valuestring yes e.g. TrueThe expected value of the field. Use ‘*’ for any non-null value. wait.fields[].indicatesFailureboolean default falseWhether this field condition indicates a failure state. wait.conditionsarray of object e.g. [{type: Realized, reason: <condition reason>}]List of status conditions to wait for. wait.conditions[].typestring yes e.g. RealizedThe type of the condition (e.g., Ready, Realized). wait.conditions[].reasonstring e.g. <condition reason>Optional reason for the condition. wait.conditions[].statusstring yes e.g. TrueThe expected status of the condition (e.g., True, False). wait.conditions[].indicatesFailureboolean default falseWhether this condition indicates a failure state. wait.skipWaitOnDeleteboolean default falseWhether to skip waiting for conditions during delete operations. countinteger default 1The number of resource instances to be created. configsarray of object yes e.g. [{generateName: dnat-web, spec: {action: DNAT, translatedNetwork: 10.200.0.10}}]List of resources associated with the VPC. configs[].specobject e.g. {action: DNAT, translatedNetwork: 10.200.0.10}The specification of the associated resource. configs[].labelsobject e.g. {app: web}Labels for categorizing the resource. configs[].annotationsobject e.g. {owner: team-a}Annotations for additional metadata about the resource. configs[].generateNamestring yes e.g. dnat-webA prefix for generating a unique name for the resource. apiVersionstring e.g. vpc.nsx.vmware.com/v1alpha1The API version of the resource.
Three things hold for all five kinds:
generateNameis the name, not a prefix. VCF Automation names the object<vpc>:<generateName>, as written: our group wasvpc-ref-default-project-y3698:web. Keep it unique per kind in the VPC.- VCF Automation fills in
spec.vpcNameandspec.regionNamefrom thevpcproperty; leave them out. - Another resource reads an object as
configs[n]:${resource.webGroup.configs[0].name}is the full name a firewall rule needs, and${resource.publicIp.configs[0].spec.allocationIPs}is the address an allocation got.
The shape, for every kind:
natRules:
type: CCI.VPC.Configuration
properties:
vpc: ${resource.vpc.id}
apiVersion: vpc.nsx.vmware.com/v1alpha1
kind: VPCNATRule
configs:
- generateName: dnat-web
spec: { ... }
- generateName: dnat-ssh
spec: { ... }
Attachment
kind: VPCAttachment. Attaches the VPC to a VPC connectivity profile, which
decides its transit gateway, its external IP blocks and whether it gets a
default outbound NAT.
spec field | Notes |
|---|---|
vpcConnectivityProfileName | Required. The profile, as NSX names it (f06’s is default--f06). |
preferredDefaultSNATIP | The address for the VPC’s automatic SNAT. It must be free in the external block; empty lets NSX choose. |
Every field the platform accepts (2)
Field Type Req. Values Description spec.preferredDefaultSNATIPstring e.g. 192.168.144.30PreferredDefaultSNATIP specifies the translated IP for VPC auto SNAT rules. The specified IP must be available. spec.vpcConnectivityProfileNamestring yes e.g. default--f06VPCConnectivityProfileName specifies the name of the VPC Connectivity Profile associated with the VPC.
attach:
type: CCI.VPC.Configuration
properties:
vpc: ${resource.vpc.id}
apiVersion: vpc.nsx.vmware.com/v1alpha1
kind: VPCAttachment
configs:
- generateName: attach
spec:
vpcConnectivityProfileName: default--f06
With the attachment realized, NSX adds the VPC’s default SNAT rule and its
address by itself (ours: 10.200.0.0/20 to 192.168.144.14).
IP Address Allocation
kind: VPCIPAddressAllocation. Reserves addresses from one of the VPC’s IP
blocks, typically an external address for a NAT rule.
spec field | Notes |
|---|---|
ipAddressBlockVisibility | Private (default), PrivateTGW or External. The NSX API’s own default is External. |
allocationSize | How many addresses, a power of 2. Either this or allocationIPs. |
allocationIPs | Specific addresses, as a CIDR (192.168.0.1/32). |
ipBlockName | A particular block, when the visibility has more than one. |
Every field the platform accepts (4)
Field Type Req. Values Description spec.allocationIPsstring e.g. 192.168.144.18The specific IP addresses from IPBlock that needs to be requested. If specified, it should be passed like 192.168.0.0/24 or 192.168.0.1/32. spec.allocationSizeinteger e.g. 1Allocation IP address size for auto allocating IPs from IPBlock. The IP addresses will be auto allocated from unused IP addresses based on allocation size. spec.ipAddressBlockVisibilitystring e.g. ExternalVisibility of IP address block. Must be External, Private or PrivateTGW. Note: the default Private Visibility is different from NSX API’s default External Visibility. spec.ipBlockNamestring e.g. :f06-vpc-ext02IPBlock name for allocating IP address.
publicIp:
type: CCI.VPC.Configuration
dependsOn: [attach]
properties:
vpc: ${resource.vpc.id}
apiVersion: vpc.nsx.vmware.com/v1alpha1
kind: VPCIPAddressAllocation
configs:
- generateName: web-ip
spec:
ipAddressBlockVisibility: External
allocationSize: 1
The allocated address appears in the object’s own spec:
${resource.publicIp.configs[0].spec.allocationIPs} gave 192.168.144.18.
An external allocation needs the attachment first, hence the dependsOn.
NAT Rule
kind: VPCNATRule. A NAT rule on the VPC’s gateway. The designer’s default
wait is Realized.
spec field | Notes |
|---|---|
action | Required. SNAT, DNAT, Reflexive, NoSNAT or NoDNAT. |
translatedNetwork | Required. For SNAT, one address from the VPC’s external block. |
sourceNetwork | One address, a comma-separated list, or a CIDR. Mandatory for SNAT. |
destinationNetwork | One address; empty means any. |
serviceEntry | protocol (TCP, UDP, ICMP), sourcePorts, destinationPorts, translatedPorts. See the warning. |
sequenceNumber | Priority, default 0. |
firewallMatch | MatchInternalAddress (default), MatchExternalAddress or ByPass. |
enabled, logging | Defaults true and false. |
Every field the platform accepts (13)
Field Type Req. Values Description spec.actionstring yes e.g. DNATAction represents action of NAT Rule. Valid values: SNAT, DNAT, Reflexive, NoSNAT and NoDNAT. spec.destinationNetworkstring e.g. 192.168.144.18DestinationNetwork represents the destination network. The value can be a single IPv4 address or CIDR, or a comma separated list of IPv4 addresses. spec.enabledboolean e.g. trueNAT Rule enabled flag Enabled indicates whether the NAT rule is enabled or disabled. The default is True. spec.firewallMatchstring e.g. MATCH_INTERNAL_ADDRESSFirewallMatch indicates how the firewall matches the address after NATing if firewall stage is not skipped. spec.loggingboolean e.g. trueNAT Rule logging flag Logging indicates whether the logging of NAT rule is enabled or disabled. The default is False. spec.sequenceNumberinteger default 0SequenceNumber decides the priority of a NAT rule. Valid range is [0, 2147481599]. Default is 0. spec.serviceEntryobject e.g. {destinationPorts: "22", protocol: TCP}spec.serviceEntry.destinationPortsstring e.g. "22"The destination ports to match. If specified, it must be either a single port (e.g. “8080”) or a port range (e.g. “8090-8095”). spec.serviceEntry.protocolstring yes e.g. TCPProtocol supports TCP, UDP and ICMP v4. spec.serviceEntry.sourcePortsstring e.g. 1024-65535The source ports to match. If specified, it must be either a single port (e.g. “8080”) or a port range (e.g. “8090-8095”). spec.serviceEntry.translatedPortsstring e.g. "2222"The translated ports. If specified, it must be either a single port (e.g. “8080”) or a port range (e.g. “8090-8095”). spec.sourceNetworkstring e.g. 10.200.0.0/28SourceNetwork represents the source network address. The value can be a single IPv4 address or CIDR, or a comma separated list of IPv4 addresses. spec.translatedNetworkstring yes e.g. 10.200.0.10TranslatedNetwork represents the translated network address. The field is required and must contain a single IPv4 address for SNAT, DNAT and Reflexive.
dnatSsh:
type: CCI.VPC.Configuration
properties:
vpc: ${resource.vpc.id}
apiVersion: vpc.nsx.vmware.com/v1alpha1
kind: VPCNATRule
configs:
- generateName: dnat-ssh
spec:
action: DNAT
destinationNetwork: ${resource.publicIp.configs[0].spec.allocationIPs}
translatedNetwork: 10.200.0.10
serviceEntry:
protocol: TCP
destinationPorts: "22"
Warning: the port did not reach NSX. VCF Automation’s API kept the
serviceEntry (TCP 22), but the rule NSX realized had service: null: a
DNAT of every port on 192.168.144.18 to the private address. Treat a NAT
rule as a whole-address mapping. To publish one port, use a
Virtual Machine Service of type LoadBalancer,
which forwards only its ports and follows the VM’s address.
Group
kind: VPCNetworkSecurityGroup. A group of addresses, VMs or pods that
firewall rules can name. Default wait: Realized.
spec field | Notes |
|---|---|
ipAddresses[] | Addresses, ranges or CIDRs. |
vmSelectors[] | labelSelector (VMs by label, so new VMs with the label join), namespaceSelector, and propertySelector (VMs by Name, OSName or ComputerName, with Equals, Contains, StartsWith, EndsWith, NotEquals). |
podSelectors[] | labelSelector and namespaceSelector for pods. |
vms[] | Specific VMs, by instanceUUID. |
vpcNetworkSecurityGroupNames[] | Other groups, nested. |
Every field the platform accepts (35)
Field Type Req. Values Description spec.ipAddressesarray of string e.g. [10.200.0.0/28]List of IPs or CIDRs to be included in this VPCNetworkSecurityGroup. Each entry can be a single IP address, an IP range, or a subnet in CIDR notation. spec.podSelectorsarray of object e.g. [{labelSelector: {matchLabels: {app: web}}, ...}]List of Pod label selectors that will dynamically select Pods to include in this VPCNetworkSecurityGroup. spec.podSelectors[].labelSelectorobject e.g. {matchLabels: {app: web}}A label selector is a label query over a set of resources. The result of matchLabels and matchExpressions are ANDed. spec.podSelectors[].labelSelector.matchExpressionsarray of object e.g. [{key: app, operator: In}]matchExpressions is a list of label selector requirements. The requirements are ANDed. spec.podSelectors[].labelSelector.matchExpressions[].keystring yes e.g. appkey is the label key that the selector applies to. spec.podSelectors[].labelSelector.matchExpressions[].operatorstring yes e.g. Inoperator represents a key’s relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. spec.podSelectors[].labelSelector.matchExpressions[].valuesarray of string e.g. [web]values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. spec.podSelectors[].labelSelector.matchLabelsobject e.g. {app: web}matchLabels is a map of {key,value} pairs. spec.podSelectors[].namespaceSelectorobject e.g. {matchExpressions: [{key: app, operator: In}], matchLabels: {app: web}}A label selector is a label query over a set of resources. The result of matchLabels and matchExpressions are ANDed. spec.podSelectors[].namespaceSelector.matchExpressionsarray of object e.g. [{key: app, operator: In}]matchExpressions is a list of label selector requirements. The requirements are ANDed. spec.podSelectors[].namespaceSelector.matchExpressions[].keystring yes e.g. appkey is the label key that the selector applies to. spec.podSelectors[].namespaceSelector.matchExpressions[].operatorstring yes e.g. Inoperator represents a key’s relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. spec.podSelectors[].namespaceSelector.matchExpressions[].valuesarray of string e.g. [web]values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. spec.podSelectors[].namespaceSelector.matchLabelsobject e.g. {app: web}matchLabels is a map of {key,value} pairs. spec.vmSelectorsarray of object e.g. [{labelSelector: {matchLabels: {app: web}}, ...}]List of Virtual Machine label selectors that will dynamically select VMs to include in this VPCNetworkSecurityGroup. spec.vmSelectors[].labelSelectorobject e.g. {matchLabels: {app: web}}A label selector is a label query over a set of resources. The result of matchLabels and matchExpressions are ANDed. spec.vmSelectors[].labelSelector.matchExpressionsarray of object e.g. [{key: app, operator: In}]matchExpressions is a list of label selector requirements. The requirements are ANDed. spec.vmSelectors[].labelSelector.matchExpressions[].keystring yes e.g. appkey is the label key that the selector applies to. spec.vmSelectors[].labelSelector.matchExpressions[].operatorstring yes e.g. Inoperator represents a key’s relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. spec.vmSelectors[].labelSelector.matchExpressions[].valuesarray of string e.g. [web]values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. spec.vmSelectors[].labelSelector.matchLabelsobject e.g. {app: web}matchLabels is a map of {key,value} pairs. spec.vmSelectors[].namespaceSelectorobject e.g. {matchExpressions: [{key: app, operator: In}], matchLabels: {app: web}}A label selector is a label query over a set of resources. The result of matchLabels and matchExpressions are ANDed. spec.vmSelectors[].namespaceSelector.matchExpressionsarray of object e.g. [{key: app, operator: In}]matchExpressions is a list of label selector requirements. The requirements are ANDed. spec.vmSelectors[].namespaceSelector.matchExpressions[].keystring yes e.g. appkey is the label key that the selector applies to. spec.vmSelectors[].namespaceSelector.matchExpressions[].operatorstring yes e.g. Inoperator represents a key’s relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. spec.vmSelectors[].namespaceSelector.matchExpressions[].valuesarray of string e.g. [web]values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. spec.vmSelectors[].namespaceSelector.matchLabelsobject e.g. {app: web}matchLabels is a map of {key,value} pairs. spec.vmSelectors[].propertySelectorobject e.g. {matchExpressions: [{key: Name, operator: StartsWith}]}PropertySelector represents a set of conditions on VM properties. All MatchExpressions are ANDed; a VM must satisfy all expressions to match. spec.vmSelectors[].propertySelector.matchExpressionsarray of object e.g. [{key: Name, operator: StartsWith}]MatchExpressions is a list of property selector requirements. Each requirement consists of a key, operator, and value. spec.vmSelectors[].propertySelector.matchExpressions[].keystring yes e.g. NameKey is the VM property to match. Valid keys are Name, OSName and ComputerName. spec.vmSelectors[].propertySelector.matchExpressions[].operatorstring yes e.g. StartsWithOperator defines how the Key is compared against Value. Valid operators are Equals, Contains, StartsWith, EndsWith and NotEquals. spec.vmSelectors[].propertySelector.matchExpressions[].valuestring yes e.g. web-Value is the target value to match against the VM property. spec.vmsarray of object e.g. [{instanceUUID: 5010c9b4-1f2e-4d3c-8b7a-6e5f4d3c2b1a}]List of Virtual Machine references that will be included in this VPCNetworkSecurityGroup. spec.vms[].instanceUUIDstring yes e.g. 5010c9b4-1f2e-4d3c-8b7a-6e5f4d3c2b1aInstanceUUID of the VM being referenced. spec.vpcNetworkSecurityGroupNamesarray of string e.g. [db-servers]List of VPCNetworkSecurityGroup names that will be included in this VPCNetworkSecurityGroup.
webGroup:
type: CCI.VPC.Configuration
properties:
vpc: ${resource.vpc.id}
apiVersion: vpc.nsx.vmware.com/v1alpha1
kind: VPCNetworkSecurityGroup
configs:
- generateName: web
spec:
vmSelectors:
- labelSelector:
matchLabels: {tier: web}
Every VPC also has a group named default, made by NSX.
Gateway Firewall Policy
kind: VPCGatewayFirewallPolicy. Rules on the VPC’s gateway, for traffic
entering and leaving the VPC. The distributed firewall inside the VPC is a
separate thing.
spec field | Notes |
|---|---|
rules[] | Per rule: name (unique in the policy), action (Allow default, Drop, Reject, JumpToApplication), direction (InOut default, In, Out), from[] and to[] (each entry groupName or ipAddress), services[] (networkServiceName, or l4PortSet with l4Protocol, destinationPorts, sourcePorts), ipProtocol, log, disabled, notes, tag, sourcesExcluded, destinationsExcluded, appliedTo. |
category | LocalGatewayRules (default) or Default. |
priority | Order against other policies, default 0. |
stateful, tcpStrict | Stateful inspection; a full TCP handshake before data. |
description, locked |
Every field the platform accepts (35)
Field Type Req. Values Description spec.categorystring e.g. LocalGatewayRulesPre-defined categories for classifying a VPC Gateway Firewall policy.There are two pre-defined categories. They are “LocalGatewayRules” and “Default”. spec.descriptionstring e.g. Inbound HTTPSDescription for the firewall policy. spec.isDefaultboolean default falseA flag to indicate whether rule is a default rule spec.lockedboolean default falseLocked indicates whether a security policy should be locked spec.priorityinteger default 0This field is used to resolve conflicts between multiple Rules under Security or Gateway Policy for a Domain. If no priority is specified in the payload, a value of 0 is assigned by default. spec.rulesarray of object e.g. [{action: Allow, name: https-in}]Rules that are a part of this FirewallPolicy spec.rules[].actionstring e.g. AllowAction to be applied to all the services spec.rules[].appliedToobject e.g. {gatewayAttachmentNames: [<transit gateway attachment>], ...}spec.rules[].appliedTo.gatewayAttachmentNamesarray of string e.g. [<transit gateway attachment>]This field is only applicable when the rule is defined for Transit Gateway Firewall policy spec.rules[].appliedTo.gatewayNamesarray of string e.g. [<transit gateway>]This field is only applicable when the rule is defined for Transit Gateway Firewall policy spec.rules[].appliedTo.groupNamesarray of string e.g. [<group>]This field is only applicable when the rule is defined for Distributed Firewall policy spec.rules[].destinationsExcludedboolean e.g. trueDestinationsExcluded indicates that the rule applies to all destinations except those specified in the ‘To’ field. spec.rules[].directionstring e.g. InDirection defines direction of traffic. spec.rules[].disabledboolean default falseDisabled indicates if the rule is enabled/disabled. spec.rules[].fromarray of object e.g. [{ipAddress: 0.0.0.0/0, groupName: admin-hosts}]From defines the source of the traffic. If empty, it defaults to “Any”, matching all sources. spec.rules[].from[].groupNamestring e.g. admin-hostsspec.rules[].from[].ipAddressstring e.g. 0.0.0.0/0spec.rules[].ipProtocolstring e.g. IPV4IpProtocol indicates type of IP packet that should be matched while enforcing the rule. Only IPV_4 protocol is supported for new rules, IPV4_IPV6 is only allowed for default rules. spec.rules[].isDefaultboolean default falseIsDefault is a flag to indicate whether rule is a default rule. spec.rules[].logboolean e.g. trueLog indicates if traffic matching this rule should be logged. spec.rules[].namestring yes e.g. https-inName for the rule. Must be unique within the policy. spec.rules[].notesstring e.g. HTTPS from anywhereNotes for the rule. spec.rules[].servicesarray of object e.g. [{l4PortSet: {destinationPorts: [443], l4Protocol: TCP}, networkServiceName: :HTTPS}]Services specifies the network services (protocols and ports) to which this rule applies. If empty or null ,it defaults to “Any” , then this rule applies to all services. spec.rules[].services[].l4PortSetobject e.g. {destinationPorts: [443], l4Protocol: TCP}L4PortSetServiceEntry is a ServiceEntry that represents TCP or UDP protocol. spec.rules[].services[].l4PortSet.destinationPortsarray of string e.g. [443]DestinationPorts defines the destination port or port range to match. For example: [“443”], [“8080-8090”]. If empty, matches any destination port. spec.rules[].services[].l4PortSet.l4Protocolstring yes e.g. TCPL4Protocol specifies the Layer 4 protocol (TCP or UDP). spec.rules[].services[].l4PortSet.sourcePortsarray of string e.g. [1000-2000]SourcePorts defines the source port or port range to match. For example: [“80”], [“1000-2000”]. If empty, matches any source port. spec.rules[].services[].networkServiceNamestring e.g. :HTTPSspec.rules[].sourcesExcludedboolean e.g. trueSourcesExcluded indicates that the rule applies to all sources except those specified in the ‘From’ field. When true, the ‘From’ field acts as an exclusion list. spec.rules[].tagstring e.g. webTag applied on the rule. spec.rules[].toarray of object e.g. [{groupName: ${resource.webGroup.configs[0].name}, ipAddress: 10.200.0.10}]To defines the destination of the traffic. If empty, it defaults to “Any”, matching all destinations. spec.rules[].to[].groupNamestring e.g. ${resource.webGroup.configs[0].name}spec.rules[].to[].ipAddressstring e.g. 10.200.0.10spec.statefulboolean default falseStateful or Stateless nature of security policy is enforced on all rules in this security policy. spec.tcpStrictboolean default falseEnsures that a 3 way TCP handshake is done before the data packets are sent. tcp_strict=true is supported only for stateful security policies.
Recipe, HTTPS from anywhere to the web group:
gwPolicy:
type: CCI.VPC.Configuration
dependsOn: [attach]
properties:
vpc: ${resource.vpc.id}
apiVersion: vpc.nsx.vmware.com/v1alpha1
kind: VPCGatewayFirewallPolicy
configs:
- generateName: web-in
spec:
stateful: true
rules:
- name: https-in
action: Allow
direction: In
from:
- ipAddress: 0.0.0.0/0
to:
- groupName: ${resource.webGroup.configs[0].name}
services:
- networkServiceName: ":HTTPS"
Gotchas
fromis required, whatever the field’s description says: without it,spec.rules[0].from: Required value. Write0.0.0.0/0for any source.- Name a service rather than a port set. A rule that lists only an
l4PortSetgetsnetworkServiceName: Anyadded by the API, and NSX realizes it as servicesANYbeside the raw TCP 443 entry. WithnetworkServiceName: ":HTTPS"NSX holds exactly/infra/services/HTTPS. The API lists 415 services, all with a leading colon (:DNS,:HTTPS,:SSH); without the colon it refuses:Network service name must start with a colon (:), such as :HTTP. groupNametakes the group’s full name,<vpc>:<generateName>, whichconfigs[0].namesupplies.- The gateway firewall has to be active in the VPC’s security profile for any of this to be enforced.
Supervisor Resource
type: CCI.Supervisor.Resource. Any Kubernetes object in the namespace,
described by manifest. Every workload item that follows is this type with
apiVersion and kind filled in, so everything here applies to them.
| Property | Notes |
|---|---|
context | Required. ${resource.<namespace>.id}. |
manifest | Required. The object: apiVersion, kind, metadata, spec. A change to manifest or context recreates the object. |
wait | As above. |
existing | true adopts an object that already exists. |
object | Computed: the live object. |
Every field the platform accepts (18)
Field Type Req. Values Description waitobject e.g. {fields: [{path: status.powerState, value: PoweredOn}], ...}resource yaml wait.fieldsarray of object e.g. [{path: status.powerState, value: PoweredOn}]List of fields for whose value needs to be waited for resource to be finished wait.fields[].pathstring yes e.g. status.powerStateThe path of the field within the Kubernetes resource wait.fields[].valuestring yes e.g. PoweredOnThe value that needs to be met for the wait to be finished. wait.fields[].indicatesFailureboolean e.g. trueWhen the condition is met, indicates failure if set to true wait.conditionsarray of object e.g. [{type: VirtualMachineGuestNetworkConfigSynced, status: True}]List of conditions that indicate success/failure of resource wait.conditions[].typestring yes e.g. VirtualMachineGuestNetworkConfigSyncedThe condition type for which to wait wait.conditions[].reasonstring e.g. <condition reason>The condition reason for which to wait wait.conditions[].statusstring yes e.g. TrueThe value of the condition that needs to be met wait.conditions[].indicatesFailureboolean e.g. trueWhen the condition is met, indicates failure if set to true wait.executionLogsobject e.g. {failureMessagePattern: (?i)error, progressMessagePattern: (?i)creating}The message to fetch from the logs while the resource is being created. This is only supported for Kubernetes Jobs. wait.executionLogs.failureMessagePatternstring e.g. (?i)errorThe message pattern to check for to fail the resource creation. If the message is found in the logs, the resource creation will be marked as failed. wait.executionLogs.progressMessagePatternstring yes e.g. (?i)creatingThe message pattern to check for to indicate that the resource creation is in progress. If the message is found in the logs, it will be shown as part of the deployment. wait.skipWaitOnDeleteboolean e.g. trueIf false, do not wait for resources to be gone before completing countinteger default 1The number of resource instances to be created. contextstring yes e.g. ${resource.namespace.id}The CCI.Supervisor.Namespace resource id existingboolean default falseUse existing supervisor namespace manifestobject yes e.g. {apiVersion: vmoperator.vmware.com/v1alpha5, kind: VirtualMachine, spec: ...}The yaml representation of the Kubernetes resource
Recipe, a kind the palette doesn’t have. Our labs carry three VLANs over one trunk subnet with binding maps:
bmMgmt:
type: CCI.Supervisor.Resource
properties:
context: ${resource.namespace.id}
manifest:
apiVersion: crd.nsx.vmware.com/v1alpha1
kind: SubnetConnectionBindingMap
metadata: {name: bm-mgmt}
spec: {subnetName: sn-mgmt, targetSubnetName: sn-trunk, vlanTrafficTag: 1610}
On the 9.1 Supervisor the namespace’s API also offers, among others,
VirtualMachineReplicaSet, VirtualMachineSnapshot, VirtualMachineImage,
SubnetSet, ConfigMap and, with Avi, the Gateway API kinds.
Gotchas
manifestcan be a string as well as a map. Our generator writes one per host as a string, because a VM with optional sections is easier to build as text:manifest: "${...}"works as long as the expression returns valid YAML.- Broadcom’s day-2 page warns that bindings don’t work for Supervisor Resources in day-2 operations; a day-2 action has to take the resource as an input.
Virtual Machine
CCI.Supervisor.Resource with apiVersion: vmoperator.vmware.com/v1alpha5,
kind: VirtualMachine. A VM Service VM: built from a VM class (CPU, memory,
devices) and an image, and configured on first boot by cloud-init, Sysprep,
LinuxPrep or vApp properties.
The most used fields; the complete list of 266 follows.
spec field | Notes |
|---|---|
className | The VM class. Changing it later resizes the VM. |
imageName | The image: its resource name (vmi-0f0136a489b21d06c) or its display name (ubuntu-24.04-server-cloudimg-amd64), if that is unique among the namespace’s and the cluster’s images. |
storageClass | The storage class for the VM’s disks. |
powerState | PoweredOn (default), PoweredOff, Suspended. |
guestID | The guest OS identifier. Required when the VM has a CD-ROM. Immutable while powered on. |
network | hostName, domainName, nameservers, searchDomains, disabled, and interfaces[]: name (required), network (a Subnet or SubnetSet), addresses[], gateway4, dhcp4, mtu, routes[], nameservers[], searchDomains[], guestDeviceName, macAddr. Without interfaces, the VM joins the namespace’s default network. |
bootstrap | One of cloudInit (inline cloudConfig, rawCloudConfig from a Secret, sshAuthorizedKeys), sysprep (inline or rawSysprep from a Secret), linuxPrep (timeZone, hardwareClockIsUTC, password, scriptText), vAppConfig (properties, rawProperties). |
volumes[] | Extra disks from Persistent Volume Claims: name, persistentVolumeClaim.claimName, and per volume controllerType (SCSI default, NVME, SATA, IDE), controllerBusNumber, unitNumber, diskMode, sharingMode, applicationType, removable. |
hardware | cdrom[] (an ISO image, connected, allowGuestControl) and the controllers: scsiControllers[], nvmeControllers[], sataControllers[], ideControllers[]. |
advanced | bootDiskCapacity, defaultVolumeProvisioningMode (Thin, Thick, ThickEagerZero), changeBlockTracking. |
promoteDisksMode | Online (default), Offline, Disabled. See the gotchas. |
bootOptions | firmware (bios, efi: lower case, whatever the designer suggests), efiSecureBoot, bootOrder, bootDelay, bootRetry, bootRetryDelay, networkBootProtocol. |
readinessProbe | tcpSocket.port, guestHeartbeat.thresholdStatus, or guestInfo[], with periodSeconds and timeoutSeconds. |
affinity | vmAffinity and vmAntiAffinity, each requiredDuringSchedulingPreferredDuringExecution (must hold) or preferredDuringSchedulingPreferredDuringExecution (best effort): a labelSelector and a topologyKey. Needs groupName. |
groupName | The Virtual Machine Group the VM belongs to; the group then places it. |
crypto | encryptionClassName, useDefaultKeyProvider (default true), vTPMMode. |
minHardwareVersion | A floor for the virtual hardware version: NVMe needs 14 or later. |
nextRestartTime | Set to now to restart the VM, per restartMode. |
powerOffMode, suspendMode, restartMode | TrySoft (default), Soft, Hard. |
currentSnapshotName, policies[], biosUUID, instanceUUID | Revert to a snapshot, attach policies, pin identifiers. |
Every field the platform accepts (266)
Field Type Req. Values Description spec.advancedobject e.g. {bootDiskCapacity: 40Gi, defaultVolumeProvisioningMode: Thin}Advanced describes a set of optional, advanced VM configuration options. spec.advanced.bootDiskCapacityint or string e.g. 40GiBootDiskCapacity is the capacity of the VM’s boot disk – the first disk from the VirtualMachineImage from which the VM was deployed. spec.advanced.changeBlockTrackingboolean e.g. trueChangeBlockTracking is a flag that enables incremental backup support for this VM, a feature utilized by external backup systems such as VMware Data Recovery. spec.advanced.defaultVolumeProvisioningModestring Thin, Thick, ThickEagerZeroDefaultVolumeProvisioningMode specifies the default provisioning mode for persistent volumes managed by this VM. spec.affinityobject e.g. {vmAntiAffinity: {preferredDuringSchedulingPreferredDuringExecution: [{topologyKey: , ...}]}}Affinity describes the VM’s scheduling constraints. spec.affinity.vmAffinityobject e.g. {preferredDuringSchedulingPreferredDuringExecution: [{labelSelector: {matchLabels: {, ...}}}]}VMAffinity describes affinity scheduling rules related to other VMs. spec.affinity.vmAffinity.preferredDuringSchedulingPreferredDuringExecutionarray of object e.g. [{labelSelector: {matchLabels: {app: web}}, topologyKey: kubernetes.io/hostname}]PreferredDuringSchedulingPreferredDuringExecution describes affinity requirements that should be met, but the VM can still be scheduled if the requirement cannot be satisfied. spec.affinity.vmAffinity.preferredDuringSchedulingPreferredDuringExecution[].labelSelectorobject e.g. {matchLabels: {app: web}}LabelSelector is a label query over a set of VMs. When omitted, this term matches with no VMs. spec.affinity.vmAffinity.preferredDuringSchedulingPreferredDuringExecution[].labelSelector.matchExpressionsarray of object e.g. [{key: app, operator: In}]matchExpressions is a list of label selector requirements. The requirements are ANDed. spec.affinity.vmAffinity.preferredDuringSchedulingPreferredDuringExecution[].labelSelector.matchExpressions[].keystring yes e.g. appkey is the label key that the selector applies to. spec.affinity.vmAffinity.preferredDuringSchedulingPreferredDuringExecution[].labelSelector.matchExpressions[].operatorstring yes e.g. Inoperator represents a key’s relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. spec.affinity.vmAffinity.preferredDuringSchedulingPreferredDuringExecution[].labelSelector.matchExpressions[].valuesarray of string e.g. [web]values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. spec.affinity.vmAffinity.preferredDuringSchedulingPreferredDuringExecution[].labelSelector.matchLabelsobject e.g. {app: web}matchLabels is a map of {key,value} pairs. spec.affinity.vmAffinity.preferredDuringSchedulingPreferredDuringExecution[].topologyKeystring yes e.g. kubernetes.io/hostnameTopologyKey describes where this VM should be co-located (affinity) or not co-located (anti-affinity). spec.affinity.vmAffinity.requiredDuringSchedulingPreferredDuringExecutionarray of object e.g. [{labelSelector: {matchLabels: {app: web}}, topologyKey: kubernetes.io/hostname}]RequiredDuringSchedulingPreferredDuringExecution describes affinity requirements that must be met or the VM will not be scheduled. spec.affinity.vmAffinity.requiredDuringSchedulingPreferredDuringExecution[].labelSelectorobject e.g. {matchLabels: {app: web}}LabelSelector is a label query over a set of VMs. When omitted, this term matches with no VMs. spec.affinity.vmAffinity.requiredDuringSchedulingPreferredDuringExecution[].labelSelector.matchExpressionsarray of object e.g. [{key: app, operator: In}]matchExpressions is a list of label selector requirements. The requirements are ANDed. spec.affinity.vmAffinity.requiredDuringSchedulingPreferredDuringExecution[].labelSelector.matchExpressions[].keystring yes e.g. appkey is the label key that the selector applies to. spec.affinity.vmAffinity.requiredDuringSchedulingPreferredDuringExecution[].labelSelector.matchExpressions[].operatorstring yes e.g. Inoperator represents a key’s relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. spec.affinity.vmAffinity.requiredDuringSchedulingPreferredDuringExecution[].labelSelector.matchExpressions[].valuesarray of string e.g. [web]values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. spec.affinity.vmAffinity.requiredDuringSchedulingPreferredDuringExecution[].labelSelector.matchLabelsobject e.g. {app: web}matchLabels is a map of {key,value} pairs. spec.affinity.vmAffinity.requiredDuringSchedulingPreferredDuringExecution[].topologyKeystring yes e.g. kubernetes.io/hostnameTopologyKey describes where this VM should be co-located (affinity) or not co-located (anti-affinity). spec.affinity.vmAntiAffinityobject e.g. {preferredDuringSchedulingPreferredDuringExecution: [{topologyKey: kubernetes.io/hos, ...}]}VMAntiAffinity describes anti-affinity scheduling rules related to other VMs. spec.affinity.vmAntiAffinity.preferredDuringSchedulingPreferredDuringExecutionarray of object e.g. [{topologyKey: kubernetes.io/hostname, labelSelector: {matchLabels: {app: web}}}]PreferredDuringSchedulingPreferredDuringExecution describes anti-affinity requirements that should be met, but the VM can still be scheduled if the requirement cannot be satisfied. spec.affinity.vmAntiAffinity.preferredDuringSchedulingPreferredDuringExecution[].labelSelectorobject e.g. {matchLabels: {app: web}}LabelSelector is a label query over a set of VMs. When omitted, this term matches with no VMs. spec.affinity.vmAntiAffinity.preferredDuringSchedulingPreferredDuringExecution[].labelSelector.matchExpressionsarray of object e.g. [{key: app, operator: In}]matchExpressions is a list of label selector requirements. The requirements are ANDed. spec.affinity.vmAntiAffinity.preferredDuringSchedulingPreferredDuringExecution[].labelSelector.matchExpressions[].keystring yes e.g. appkey is the label key that the selector applies to. spec.affinity.vmAntiAffinity.preferredDuringSchedulingPreferredDuringExecution[].labelSelector.matchExpressions[].operatorstring yes e.g. Inoperator represents a key’s relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. spec.affinity.vmAntiAffinity.preferredDuringSchedulingPreferredDuringExecution[].labelSelector.matchExpressions[].valuesarray of string e.g. [web]values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. spec.affinity.vmAntiAffinity.preferredDuringSchedulingPreferredDuringExecution[].labelSelector.matchLabelsobject e.g. {app: web}matchLabels is a map of {key,value} pairs. spec.affinity.vmAntiAffinity.preferredDuringSchedulingPreferredDuringExecution[].topologyKeystring yes e.g. kubernetes.io/hostnameTopologyKey describes where this VM should be co-located (affinity) or not co-located (anti-affinity). spec.affinity.vmAntiAffinity.requiredDuringSchedulingPreferredDuringExecutionarray of object e.g. [{labelSelector: {matchLabels: {app: web}}, topologyKey: kubernetes.io/hostname}]RequiredDuringSchedulingPreferredDuringExecution describes anti-affinity requirements that must be met or the VM will not be scheduled. spec.affinity.vmAntiAffinity.requiredDuringSchedulingPreferredDuringExecution[].labelSelectorobject e.g. {matchLabels: {app: web}}LabelSelector is a label query over a set of VMs. When omitted, this term matches with no VMs. spec.affinity.vmAntiAffinity.requiredDuringSchedulingPreferredDuringExecution[].labelSelector.matchExpressionsarray of object e.g. [{key: app, operator: In}]matchExpressions is a list of label selector requirements. The requirements are ANDed. spec.affinity.vmAntiAffinity.requiredDuringSchedulingPreferredDuringExecution[].labelSelector.matchExpressions[].keystring yes e.g. appkey is the label key that the selector applies to. spec.affinity.vmAntiAffinity.requiredDuringSchedulingPreferredDuringExecution[].labelSelector.matchExpressions[].operatorstring yes e.g. Inoperator represents a key’s relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. spec.affinity.vmAntiAffinity.requiredDuringSchedulingPreferredDuringExecution[].labelSelector.matchExpressions[].valuesarray of string e.g. [web]values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. spec.affinity.vmAntiAffinity.requiredDuringSchedulingPreferredDuringExecution[].labelSelector.matchLabelsobject e.g. {app: web}matchLabels is a map of {key,value} pairs. spec.affinity.vmAntiAffinity.requiredDuringSchedulingPreferredDuringExecution[].topologyKeystring yes e.g. kubernetes.io/hostnameTopologyKey describes where this VM should be co-located (affinity) or not co-located (anti-affinity). spec.biosUUIDstring e.g. 4210d2a5-6d0e-4f6e-9c3a-0b1f2e3d4c5bBiosUUID describes the desired BIOS UUID for a VM. If omitted, this field defaults to a random UUID. spec.bootOptionsobject e.g. {bootDelay: 5s, bootOrder: [{name: <device name>, type: Disk}]}BootOptions describes the settings that control the boot behavior of the virtual machine. These settings take effect during the next power-on of the virtual machine. spec.bootOptions.bootDelaystring e.g. 5sBootDelay is the delay before starting the boot sequence. The boot delay specifies a time interval between virtual machine power on or restart and the beginning of the boot sequence. spec.bootOptions.bootOrderarray of object e.g. [{name: <device name>, type: Disk}]BootOrder represents the boot order of the virtual machine. After list is exhausted, default BIOS boot device algorithm is used for booting. spec.bootOptions.bootOrder[].namestring e.g. <device name>Name represents the name of the bootable device. It is required for Disk and Network device types, while ignored for CDRom device types. spec.bootOptions.bootOrder[].typestring yes Disk, Network, CDRomType represents the type of bootable device. The available device types are: - Disk - Network - CDRom spec.bootOptions.bootRetrystring default DisabledBootRetry specifies whether a virtual machine that fails to boot will try again. spec.bootOptions.bootRetryDelaystring e.g. 10sBootRetryDelay specifies a time interval between virtual machine boot failure and the subsequent attempt to boot again. spec.bootOptions.efiSecureBootstring Enabled, Disabled; default DisabledEFISecureBoot specifies whether the virtual machine’s firmware will perform signature checks of any EFI images loaded during startup. spec.bootOptions.firmwarestring bios, efiFirmware represents the firmware for the virtual machine to use. Any update to this value after the virtual machine has already been created will be ignored. spec.bootOptions.networkBootProtocolstring IP4, IP6; default IP4NetworkBootProtocol is the protocol to attempt during PXE network boot or NetBoot. The available protocols are: - IP4 – PXE (or Apple NetBoot) over IPv4. spec.bootstrapobject e.g. {cloudInit: {cloudConfig: {timezone: Europe/London, users: [{name: ops, ...}]}}}Bootstrap describes the desired state of the guest’s bootstrap configuration. If omitted, a default bootstrap method may be selected based on the guest OS identifier. spec.bootstrap.cloudInitobject e.g. {cloudConfig: {timezone: Europe/London, users: [{name: ops, ...}]}}CloudInit may be used to bootstrap Linux guests with Cloud-Init or Windows guests that support Cloudbase-Init. spec.bootstrap.cloudInit.cloudConfigobject e.g. {timezone: Europe/London, users: [{name: ops, hashed_passwd: {key: ops-passwd, ...}}]}CloudConfig describes a subset of a Cloud-Init CloudConfig, used to bootstrap the VM. spec.bootstrap.cloudInit.cloudConfig.defaultUserEnabledboolean e.g. trueDefaultUserEnabled may be set to true to ensure even if the Users field is not empty, the default user is still created on systems that have one defined. spec.bootstrap.cloudInit.cloudConfig.runcmdany e.g. [systemctl enable --now nginx]RunCmd allows running one or more commands on the guest. The entries in this list can adhere to two, different formats: Format 1 – a string that contains the command and its arguments, ex. spec.bootstrap.cloudInit.cloudConfig.ssh_pwauthboolean e.g. trueSSHPwdAuth sets whether or not to accept password authentication. In order for this config to be applied, SSH may need to be restarted. spec.bootstrap.cloudInit.cloudConfig.timezonestring e.g. Europe/LondonTimezone describes the timezone represented in /usr/share/zoneinfo. spec.bootstrap.cloudInit.cloudConfig.usersarray of object e.g. [{name: ops, hashed_passwd: {key: ops-passwd, name: web-pw}}]Users allows adding/configuring one or more users on the guest. spec.bootstrap.cloudInit.cloudConfig.users[].create_groupsboolean e.g. trueCreateGroups is a flag that may be set to false to disable creation of specified user groups. Defaults to true when Name is not “default”. spec.bootstrap.cloudInit.cloudConfig.users[].expiredatestring e.g. 2027-01-01ExpireData is the date on which the user’s account will be disabled. spec.bootstrap.cloudInit.cloudConfig.users[].gecosstring e.g. Operations userGecos is an optional comment about the user, usually a comma-separated string of the user’s real name and contact information. spec.bootstrap.cloudInit.cloudConfig.users[].groupsarray of string e.g. [sudo]Groups is an optional list of groups to add to the user. spec.bootstrap.cloudInit.cloudConfig.users[].hashed_passwdobject e.g. {key: ops-passwd, name: web-pw}HashedPasswd is a hash of the user’s password that will be applied even if the specified user already exists. spec.bootstrap.cloudInit.cloudConfig.users[].hashed_passwd.keystring yes e.g. ops-passwdKey is the key in the secret that specifies the requested data. spec.bootstrap.cloudInit.cloudConfig.users[].hashed_passwd.namestring yes e.g. web-pwName is the name of the secret. spec.bootstrap.cloudInit.cloudConfig.users[].homedirstring e.g. /home/opsHomedir is the optional home directory for the user. Defaults to “/home/” when Name is not “default”. spec.bootstrap.cloudInit.cloudConfig.users[].inactiveinteger e.g. 30Inactive optionally represents the number of days until the user is disabled. spec.bootstrap.cloudInit.cloudConfig.users[].lock_passwdboolean e.g. falseLockPasswd disables password login. Defaults to true when Name is not “default”. spec.bootstrap.cloudInit.cloudConfig.users[].namestring yes e.g. opsName is the user’s login name. When set to “default”, all other fields from this User must be nil. spec.bootstrap.cloudInit.cloudConfig.users[].no_create_homeboolean e.g. trueNoCreateHome prevents the creation of the home directory. Defaults to false when Name is not “default”. spec.bootstrap.cloudInit.cloudConfig.users[].no_log_initboolean e.g. trueNoLogInit prevents the initialization of lastlog and faillog for the user. Defaults to false when Name is not “default”. spec.bootstrap.cloudInit.cloudConfig.users[].no_user_groupboolean e.g. trueNoUserGroup prevents the creation of the group named after the user. Defaults to false when Name is not “default”. spec.bootstrap.cloudInit.cloudConfig.users[].passwdobject e.g. {key: <key in the Secret>, name: <Secret name>}Passwd is a hash of the user’s password that will be applied only to a newly created user. To apply a new, hashed password to an existing user please use HashedPasswd instead. spec.bootstrap.cloudInit.cloudConfig.users[].passwd.keystring yes e.g. <key in the Secret>Key is the key in the secret that specifies the requested data. spec.bootstrap.cloudInit.cloudConfig.users[].passwd.namestring yes e.g. <Secret name>Name is the name of the secret. spec.bootstrap.cloudInit.cloudConfig.users[].primary_groupstring e.g. opsPrimaryGroup is the primary group for the user. Defaults to the value of the Name field when it is not “default”. spec.bootstrap.cloudInit.cloudConfig.users[].selinux_userstring e.g. staff_uSELinuxUser is the SELinux user for the user’s login. spec.bootstrap.cloudInit.cloudConfig.users[].shellstring e.g. /bin/bashShell is the path to the user’s login shell. spec.bootstrap.cloudInit.cloudConfig.users[].snapuserstring e.g. ops@example.comSnapUser specifies an e-mail address to create the user as a Snappy user through “snap create-user”. spec.bootstrap.cloudInit.cloudConfig.users[].ssh_authorized_keysarray of string e.g. [ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOkJfr8Q3cNq ops@example]SSHAuthorizedKeys is a list of SSH keys to add to the user’s authorized keys file. spec.bootstrap.cloudInit.cloudConfig.users[].ssh_import_idarray of string e.g. [gh:octocat]SSHImportID is a list of SSH IDs to import for the user. spec.bootstrap.cloudInit.cloudConfig.users[].ssh_redirect_userboolean e.g. trueSSHRedirectUser may be set to true to disable SSH logins for this user. Any SSH login as this user will timeout with a message to login instead as the default user. spec.bootstrap.cloudInit.cloudConfig.users[].sudostring e.g. ALL=(ALL) NOPASSWD:ALLSudo is a sudo rule to apply to the user. When omitted, no sudo rules will be applied to the user. spec.bootstrap.cloudInit.cloudConfig.users[].systemboolean e.g. trueSystem is an optional flag that indicates the user should be created as a system user with no home directory. Defaults to false when Name is not “default”. spec.bootstrap.cloudInit.cloudConfig.users[].uidinteger e.g. 1001UID is the user’s ID. When omitted the guest will default to the next available number. spec.bootstrap.cloudInit.cloudConfig.write_filesarray of object e.g. [{path: /etc/nginx/conf.d/lab.conf, content: server_tokens off;}]WriteFiles allows adding files to the guest file system. spec.bootstrap.cloudInit.cloudConfig.write_files[].appendboolean e.g. trueAppend specifies whether or not to append the content to an existing file if the file specified by Path already exists. spec.bootstrap.cloudInit.cloudConfig.write_files[].contentany e.g. server_tokens off;Content is the optional content to write to the provided Path. When omitted an empty file will be created or existing file will be modified. spec.bootstrap.cloudInit.cloudConfig.write_files[].deferboolean e.g. trueDefer indicates to defer writing the file until Cloud-Init’s “final” stage, after users are created and packages are installed. spec.bootstrap.cloudInit.cloudConfig.write_files[].encodingstring b64, base64, gz, gzip, gz+b64, gz+base64, gzip+b64, gzip+base64, text/plain; default text/plainEncoding is an optional encoding type of the content. spec.bootstrap.cloudInit.cloudConfig.write_files[].ownerstring default root:rootOwner is an optional “owner:group” to chown the file. spec.bootstrap.cloudInit.cloudConfig.write_files[].pathstring yes e.g. /etc/nginx/conf.d/lab.confPath is the path of the file to which the content is decoded and written. spec.bootstrap.cloudInit.cloudConfig.write_files[].permissionsstring default 0644Permissions an optional set of file permissions to set. “0###”. When omitted the guest will default this value to “0644”. spec.bootstrap.cloudInit.instanceIDstring e.g. web-01-v2InstanceID is the cloud-init metadata instance ID. If omitted, this field defaults to the VM’s BiosUUID. spec.bootstrap.cloudInit.rawCloudConfigobject e.g. {key: user-data, name: jump-bootstrap}RawCloudConfig describes a key in a Secret resource that contains the CloudConfig data used to bootstrap the VM. spec.bootstrap.cloudInit.rawCloudConfig.keystring yes e.g. user-dataKey is the key in the secret that specifies the requested data. spec.bootstrap.cloudInit.rawCloudConfig.namestring yes e.g. jump-bootstrapName is the name of the secret. spec.bootstrap.cloudInit.sshAuthorizedKeysarray of string e.g. [ssh-ed25519 AAAA... ops@admin]SSHAuthorizedKeys is a list of public keys that CloudInit will apply to the guest’s default user. spec.bootstrap.cloudInit.useGlobalNameserversAsDefaultboolean e.g. trueUseGlobalNameserversAsDefault will use the global nameservers specified in the NetworkSpec as the per-interface nameservers when the per-interface nameservers is not provided. spec.bootstrap.cloudInit.useGlobalSearchDomainsAsDefaultboolean e.g. trueUseGlobalSearchDomainsAsDefault will use the global search domains specified in the NetworkSpec as the per-interface search domains when the per-interface search domains is not provided. spec.bootstrap.cloudInit.waitOnNetwork4boolean e.g. trueWaitOnNetwork4 indicates whether the cloud-init datasource should wait for an IPv4 address to be available before writing the instance-data. spec.bootstrap.cloudInit.waitOnNetwork6boolean e.g. trueWaitOnNetwork6 indicates whether the cloud-init datasource should wait for an IPv6 address to be available before writing the instance-data. spec.bootstrap.linuxPrepobject e.g. {password: {name: <Secret name>, key: password}, ...}LinuxPrep may be used to bootstrap Linux guests. The guest’s networking stack is configured by Guest OS Customization (GOSC). spec.bootstrap.linuxPrep.customizeAtNextPowerOnboolean e.g. trueCustomizeAtNextPowerOn describes when customization is performed on the VM. When set to false, the VM will not be customized at the next power on. spec.bootstrap.linuxPrep.expirePasswordAfterNextLoginboolean e.g. trueExpirePasswordAfterNextLogin indicates whether or not the root account is required to change their password after the next login. spec.bootstrap.linuxPrep.hardwareClockIsUTCboolean e.g. trueHardwareClockIsUTC specifies whether the hardware clock is in UTC or local time. spec.bootstrap.linuxPrep.passwordobject e.g. {name: <Secret name>, key: password}Password is the new root password for the machine. When not explicitly specified, the Key field for the selector defaults to password.spec.bootstrap.linuxPrep.password.keystring default passwordKey is the key in the secret that specifies the requested data. spec.bootstrap.linuxPrep.password.namestring yes e.g. <Secret name>Name is the name of the secret. spec.bootstrap.linuxPrep.scriptTextobject e.g. {from: {key: <key in the Secret>, name: <Secret name>}, value: '#!/bin/sh ...'}ScriptText is the script to run before and after customization. Please see https://knowledge.broadcom.com/external/article?legacyId=1026614 for script examples. spec.bootstrap.linuxPrep.scriptText.fromobject e.g. {key: <key in the Secret>, name: <Secret name>}From is specified to reference a value from a Secret resource. spec.bootstrap.linuxPrep.scriptText.from.keystring yes e.g. <key in the Secret>Key is the key in the secret that specifies the requested data. spec.bootstrap.linuxPrep.scriptText.from.namestring yes e.g. <Secret name>Name is the name of the secret. spec.bootstrap.linuxPrep.scriptText.valuestring e.g. '#!/bin/sh ...'Value is used to directly specify a value. spec.bootstrap.linuxPrep.timeZonestring e.g. Europe/LondonTimeZone is a case-sensitive timezone, such as Europe/Sofia. Valid values are based on the tz (timezone) database used by Linux and other Unix systems. spec.bootstrap.sysprepobject e.g. {rawSysprep: {key: <key in the Secret>, name: <Secret name>}, ...}Sysprep may be used to bootstrap Windows guests. The guest’s networking stack is configured by Guest OS Customization (GOSC). spec.bootstrap.sysprep.customizeAtNextPowerOnboolean e.g. trueCustomizeAtNextPowerOn describes when customization is performed on the VM. When set to false, the VM will not be customized at the next power on. spec.bootstrap.sysprep.rawSysprepobject e.g. {key: <key in the Secret>, name: <Secret name>}RawSysprep describes a key in a Secret resource that contains an XML string of the Sysprep text used to bootstrap the VM. spec.bootstrap.sysprep.rawSysprep.keystring yes e.g. <key in the Secret>Key is the key in the secret that specifies the requested data. spec.bootstrap.sysprep.rawSysprep.namestring yes e.g. <Secret name>Name is the name of the secret. spec.bootstrap.sysprep.sysprepobject e.g. {guiRunOnce: {commands: [powershell -File C:\setup.ps1]}, ...}Sysprep is an object representation of a Windows sysprep.xml answer file. This field encloses all the individual keys listed in a sysprep.xml file. spec.bootstrap.sysprep.sysprep.expirePasswordAfterNextLoginboolean e.g. trueExpirePasswordAfterNextLogin indicates whether or not the local Administrators group accounts are required to change their password after the next login. spec.bootstrap.sysprep.sysprep.guiRunOnceobject e.g. {commands: [powershell -File C:\setup.ps1]}GUIRunOnce is a representation of the Sysprep GuiRunOnce key. spec.bootstrap.sysprep.sysprep.guiRunOnce.commandsarray of string e.g. [powershell -File C:\setup.ps1]Commands is a list of commands to run at first user logon, after guest customization. spec.bootstrap.sysprep.sysprep.guiUnattendedobject e.g. {autoLogonCount: 1, password: {name: <Secret name>, key: password}}GUIUnattended is a representation of the Sysprep GUIUnattended key. spec.bootstrap.sysprep.sysprep.guiUnattended.autoLogonboolean e.g. trueAutoLogon determine whether the machine automatically logs on as Administrator. spec.bootstrap.sysprep.sysprep.guiUnattended.autoLogonCountinteger e.g. 1AutoLogonCount specifies the number of times the machine should automatically log on as Administrator. spec.bootstrap.sysprep.sysprep.guiUnattended.passwordobject e.g. {name: <Secret name>, key: password}Password is the new administrator password for the machine. To specify that the password should be set to blank (that is, no password), set the password value to NULL. spec.bootstrap.sysprep.sysprep.guiUnattended.password.keystring yes default passwordKey is the key in the secret that specifies the requested data. spec.bootstrap.sysprep.sysprep.guiUnattended.password.namestring yes e.g. <Secret name>Name is the name of the secret. spec.bootstrap.sysprep.sysprep.guiUnattended.timeZoneinteger default 85TimeZone is the time zone index for the virtual machine.ly/3Rzv8oL. Defaults to UTC. spec.bootstrap.sysprep.sysprep.identificationobject e.g. {domainAdmin: svc-join@example.local, domainAdminPassword: {name: <Secret name>, ...}}Identification is a representation of the Sysprep Identification key. spec.bootstrap.sysprep.sysprep.identification.domainAdminstring e.g. svc-join@example.localDomainAdmin is the domain user account used for authentication if the virtual machine is joining a domain. spec.bootstrap.sysprep.sysprep.identification.domainAdminPasswordobject e.g. {name: <Secret name>, key: domain_admin_password}DomainAdminPassword is the password for the domain user account used for authentication if the virtual machine is joining a domain. spec.bootstrap.sysprep.sysprep.identification.domainAdminPassword.keystring yes default domain_admin_passwordKey is the key in the secret that specifies the requested data. spec.bootstrap.sysprep.sysprep.identification.domainAdminPassword.namestring yes e.g. <Secret name>Name is the name of the secret. spec.bootstrap.sysprep.sysprep.identification.domainOUstring e.g. OU=Servers,DC=example,DC=localDomainOU is the MachineObjectOU which specifies the full LDAP path name of the OU to which the computer belongs. spec.bootstrap.sysprep.sysprep.identification.joinWorkgroupstring e.g. WORKGROUPJoinWorkgroup is the workgroup that the virtual machine should join. spec.bootstrap.sysprep.sysprep.licenseFilePrintDataobject e.g. {autoUsers: 5, autoMode: perSeat}LicenseFilePrintData is a representation of the Sysprep LicenseFilePrintData key. spec.bootstrap.sysprep.sysprep.licenseFilePrintData.autoModestring yes perSeat, perServerAutoMode specifies the server licensing mode. spec.bootstrap.sysprep.sysprep.licenseFilePrintData.autoUsersinteger e.g. 5AutoUsers indicates the number of client licenses purchased for the VirtualCenter server being installed. spec.bootstrap.sysprep.sysprep.scriptTextobject e.g. {from: {key: <key in the Secret>, name: <Secret name>}, ...}ScriptText describes the script to run before and after customization. The script must be a Windows batch file. spec.bootstrap.sysprep.sysprep.scriptText.fromobject e.g. {key: <key in the Secret>, name: <Secret name>}From is specified to reference a value from a Secret resource. spec.bootstrap.sysprep.sysprep.scriptText.from.keystring yes e.g. <key in the Secret>Key is the key in the secret that specifies the requested data. spec.bootstrap.sysprep.sysprep.scriptText.from.namestring yes e.g. <Secret name>Name is the name of the secret. spec.bootstrap.sysprep.sysprep.scriptText.valuestring e.g. powershell -File C:\setup.ps1Value is used to directly specify a value. spec.bootstrap.sysprep.sysprep.userDataobject yes e.g. {fullName: Lab Admin, orgName: Example Ltd}UserData is a representation of the Sysprep UserData key. spec.bootstrap.sysprep.sysprep.userData.fullNamestring yes e.g. Lab AdminFullName is the user’s full name. spec.bootstrap.sysprep.sysprep.userData.orgNamestring yes e.g. Example LtdOrgName is the name of the user’s organization. spec.bootstrap.sysprep.sysprep.userData.productIDobject e.g. {name: <Secret name>, key: product_id}ProductID is a valid serial number. When not explicitly specified, the Key field for the selector defaults to domain_admin_password.spec.bootstrap.sysprep.sysprep.userData.productID.keystring yes default product_idKey is the key in the secret that specifies the requested data. spec.bootstrap.sysprep.sysprep.userData.productID.namestring yes e.g. <Secret name>Name is the name of the secret. spec.bootstrap.vAppConfigobject e.g. {properties: [{key: guestinfo.hostname, value: {from: {key: <key in the Secret>, ...}}}]}VAppConfig may be used to bootstrap guests that rely on vApp properties (how VMware surfaces OVF properties on guests) to transport data into the guest. spec.bootstrap.vAppConfig.propertiesarray of object e.g. [{key: guestinfo.hostname, value: {from: {key: <key in the Secret>, ...}}}]Properties is a list of vApp/OVF property key/value pairs. spec.bootstrap.vAppConfig.properties[].keystring yes e.g. guestinfo.hostnameKey is the key part of the key/value pair. spec.bootstrap.vAppConfig.properties[].valueobject e.g. {from: {key: <key in the Secret>, name: <Secret name>}, value: web-01}Value is the optional value part of the key/value pair. spec.bootstrap.vAppConfig.properties[].value.fromobject e.g. {key: <key in the Secret>, name: <Secret name>}From is specified to reference a value from a Secret resource. spec.bootstrap.vAppConfig.properties[].value.from.keystring yes e.g. <key in the Secret>Key is the key in the secret that specifies the requested data. spec.bootstrap.vAppConfig.properties[].value.from.namestring yes e.g. <Secret name>Name is the name of the secret. spec.bootstrap.vAppConfig.properties[].value.valuestring e.g. web-01Value is used to directly specify a value. spec.bootstrap.vAppConfig.rawPropertiesstring e.g. <ConfigMap with the OVF properties>RawProperties is the name of a Secret resource in the same Namespace as this VM where each key/value pair from the Secret is used as a vApp key/value pair. spec.classobject e.g. {kind: VirtualMachineClass, name: best-effort-small}Class describes the VirtualMachineClassInstance resource that is referenced by this virtual machine. spec.class.apiVersionstring yes e.g. vmoperator.vmware.com/v1alpha5APIVersion defines the versioned schema of this representation of an object. spec.class.kindstring yes e.g. VirtualMachineClassKind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. spec.class.namestring yes e.g. best-effort-smallName refers to a unique resource in the current namespace. spec.classNamestring e.g. best-effort-smallClassName describes the name of the VirtualMachineClass resource used to deploy this VM. spec.cryptoobject e.g. {encryptionClassName: <encryption class>, useDefaultKeyProvider: true}Crypto describes the desired encryption state of the VirtualMachine. spec.crypto.encryptionClassNamestring e.g. <encryption class>EncryptionClassName describes the name of the EncryptionClass resource used to encrypt this VM. spec.crypto.useDefaultKeyProviderboolean default trueUseDefaultKeyProvider describes the desired behavior for when an explicit EncryptionClass is not provided. spec.crypto.vTPMModestring Clone, New; default NewVTPMMode describes the desired behavior when deploying a VirtualMachine using a VirtualMachine-backed image which created from an encrypted VirtualMachine with a vTPM. spec.currentSnapshotNamestring e.g. before-upgradeCurrentSnapshotName represents the desired snapshot that the VM should point to. This field can be specified to revert the VM to a given snapshot. spec.groupNamestring e.g. webGroupName indicates the name of the VirtualMachineGroup to which this VM belongs. VMs that belong to a group do not drive their own placement, rather that is handled by the group. spec.guestIDstring e.g. vmkernel9GuestGuestID describes the desired guest operating system identifier for a VM. The logic that determines the guest ID is as follows: If this field is set, then its value is used. spec.hardwareobject e.g. {cdrom: [{name: cdrom0, image: {kind: VirtualMachineImage, ...}}]}Hardware describes the VM’s desired hardware. spec.hardware.cdromarray of object e.g. [{name: cdrom0, image: {kind: VirtualMachineImage, name: vmi-e400a813bbd5d52a5}}]Cdrom describes the desired state of the VM’s CD-ROM devices. Each CD-ROM device requires a reference to an ISO-type VirtualMachineImage or ClusterVirtualMachineImage resource as backing. spec.hardware.cdrom[].allowGuestControlboolean default trueAllowGuestControl describes whether or not a web console connection may be used to connect/disconnect the CD-ROM device. spec.hardware.cdrom[].connectedboolean default trueConnected describes the desired connection state of the CD-ROM device. When true, the CD-ROM device is added and connected to the VM. spec.hardware.cdrom[].controllerBusNumberinteger e.g. 0ControllerBusNumber describes the bus number of the controller to which this CD-ROM should be attached. spec.hardware.cdrom[].controllerTypestring e.g. SATAControllerType describes the type of the controller to which this CD-ROM should be attached. spec.hardware.cdrom[].imageobject yes e.g. {kind: VirtualMachineImage, name: vmi-e400a813bbd5d52a5}Image describes the reference to an ISO type VirtualMachineImage or ClusterVirtualMachineImage resource used as the backing for the CD-ROM. spec.hardware.cdrom[].image.kindstring yes e.g. VirtualMachineImageKind describes the type of image, either a namespace-scoped VirtualMachineImage or cluster-scoped ClusterVirtualMachineImage. spec.hardware.cdrom[].image.namestring yes e.g. vmi-e400a813bbd5d52a5Name refers to the name of a VirtualMachineImage resource in the same namespace as this VM or a cluster-scoped ClusterVirtualMachineImage. spec.hardware.cdrom[].namestring yes e.g. cdrom0Name consists of at least two lowercase letters or digits of this CD-ROM. It must be unique among all CD-ROM devices attached to the VM. spec.hardware.cdrom[].unitNumberinteger e.g. 1UnitNumber describes the desired unit number for attaching the CD-ROM to a storage controller. When omitted, the next available unit number of the selected controller is used. spec.hardware.ideControllersarray of object e.g. [{busNumber: 0}]IDEControllers describes the desired list of IDE controllers for the VM. Defaults to two IDE controllers, with bus 0 and bus 1. spec.hardware.ideControllers[].busNumberinteger yes e.g. 0BusNumber describes the desired bus number of the controller. spec.hardware.nvmeControllersarray of object e.g. [{busNumber: 0, sharingMode: None}]NVMEControllers describes the desired list of NVME controllers for the VM. spec.hardware.nvmeControllers[].busNumberinteger yes e.g. 0BusNumber describes the desired bus number of the controller. spec.hardware.nvmeControllers[].sharingModestring None, Physical; default NoneSharingMode describes the sharing mode for the controller. Defaults to None. spec.hardware.sataControllersarray of object e.g. [{busNumber: 0}]SATAControllers describes the desired list of SATA controllers for the VM. spec.hardware.sataControllers[].busNumberinteger yes e.g. 0BusNumber describes the desired bus number of the controller. spec.hardware.scsiControllersarray of object e.g. [{busNumber: 0, type: ParaVirtual}]SCSIControllers describes the desired list of SCSI controllers for the VM. spec.hardware.scsiControllers[].busNumberinteger yes e.g. 0BusNumber describes the desired bus number of the controller. spec.hardware.scsiControllers[].sharingModestring None, Physical, Virtual; default NoneSharingMode describes the sharing mode for the controller. Defaults to None. spec.hardware.scsiControllers[].typestring ParaVirtual, BusLogic, LsiLogic, LsiLogicSAS; default ParaVirtualType describes the desired type of SCSI controller. Defaults to ParaVirtual. spec.imageobject e.g. {kind: VirtualMachineImage, name: vmi-0123456789abcdef0}Image describes the reference to the VirtualMachineImage or ClusterVirtualMachineImage resource used to deploy this VM.imageName, the value of spec.image.name MUST be a Kubernetes object … spec.image.kindstring yes e.g. VirtualMachineImageKind describes the type of image, either a namespace-scoped VirtualMachineImage or cluster-scoped ClusterVirtualMachineImage. spec.image.namestring yes e.g. vmi-0123456789abcdef0Name refers to the name of a VirtualMachineImage resource in the same namespace as this VM or a cluster-scoped ClusterVirtualMachineImage. spec.imageNamestring e.g. ubuntu-24.04-server-cloudimg-amd64ImageName describes the name of the image resource used to deploy this VM. This field may be used to specify the name of a VirtualMachineImage or ClusterVirtualMachineImage resource. spec.instanceUUIDstring e.g. 5010c9b4-1f2e-4d3c-8b7a-6e5f4d3c2b1aInstanceUUID describes the desired Instance UUID for a VM. If omitted, this field defaults to a random UUID. This value is only used for the VM Instance UUID, it is not used within cloudInit. spec.minHardwareVersioninteger e.g. 21MinHardwareVersion describes the desired, minimum hardware version. The logic that determines the hardware version is as follows: 1. spec.networkobject e.g. {hostName: dc01, interfaces: [{name: eth0, addresses: [172.30.0.34/27]}]}Network describes the desired network configuration for the VM. spec.network.disabledboolean e.g. trueDisabled is a flag that indicates whether or not to disable networking for this VM. spec.network.domainNamestring e.g. lab.localDomainName describes the value the guest uses as its domain name. spec.network.hostNamestring e.g. dc01HostName describes the value the guest uses as its host name. If omitted, the name of the VM will be used. spec.network.interfacesarray of object e.g. [{name: eth0, addresses: [172.30.0.34/27]}]Interfaces is the list of network interfaces used by this VM. If the Interfaces field is empty and the Disabled field is false, then a default interface with the name eth0 will be created. spec.network.interfaces[].addressesarray of string e.g. [172.30.0.34/27]Addresses is an optional list of IP4 or IP6 addresses to assign to this interface. 192.168.0.10/24 or 2001:db8:101::a/64. spec.network.interfaces[].dhcp4boolean e.g. trueDHCP4 indicates whether or not this interface uses DHCP for IP4 networking. spec.network.interfaces[].dhcp6boolean e.g. trueDHCP6 indicates whether or not this interface uses DHCP for IP6 networking. spec.network.interfaces[].gateway4string e.g. 172.30.0.33Gateway4 is the default, IP4 gateway for this interface. If unset, the gateway from the network provider will be used. spec.network.interfaces[].gateway6string e.g. fd00::1Gateway6 is the primary IP6 gateway for this interface. If unset, the gateway from the network provider will be used. spec.network.interfaces[].guestDeviceNamestring e.g. eth0GuestDeviceName is used to rename the device inside the guest when the bootstrap provider is Cloud-Init. dvd, cdrom, sda, etc. spec.network.interfaces[].macAddrstring e.g. 00:50:56:00:00:10MACAddr is the optional MAC address of this interface. If no MAC address is provided, one will be generated by either the network provider or vCenter.nsx.vmware.com. spec.network.interfaces[].mtuinteger e.g. 1500MTU is the Maximum Transmission Unit size in bytes. spec.network.interfaces[].namestring yes e.g. eth0Name describes the unique name of this network interface, used to distinguish it from other network interfaces attached to this VM. spec.network.interfaces[].nameserversarray of string e.g. [172.30.0.34]Nameservers is a list of IP4 and/or IP6 addresses used as DNS nameservers. spec.network.interfaces[].networkobject e.g. {kind: Subnet, name: sn-mgmt}Network is the name of the network resource to which this interface is connected. If no network is provided, then this interface will be connected to the Namespace’s default network. spec.network.interfaces[].network.apiVersionstring e.g. crd.nsx.vmware.com/v1alpha1APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. spec.network.interfaces[].network.kindstring e.g. SubnetKind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. spec.network.interfaces[].network.namestring yes e.g. sn-mgmtName refers to a unique resource in the current namespace. spec.network.interfaces[].routesarray of object e.g. [{to: 172.16.0.0/16, via: 10.200.0.1}]Routes is a list of optional, static routes. spec.network.interfaces[].routes[].metricinteger e.g. 100Metric is the weight/priority of the route. spec.network.interfaces[].routes[].tostring yes e.g. 172.16.0.0/16To is either “default”, or an IP4 or IP6 address. spec.network.interfaces[].routes[].viastring yes e.g. 10.200.0.1Via is an IP4 or IP6 address. spec.network.interfaces[].searchDomainsarray of string e.g. [lab.local]SearchDomains is a list of search domains used when resolving IP addresses with DNS. spec.network.nameserversarray of string e.g. [10.200.0.2]Nameservers is a list of IP4 and/or IP6 addresses used as DNS nameservers. These are applied globally. The Cloud-Init bootstrap provider supports per-interface nameservers. spec.network.searchDomainsarray of string e.g. [lab.local]SearchDomains is a list of search domains used when resolving IP addresses with DNS. These are applied globally. The Cloud-Init bootstrap provider supports per-interface search domains. spec.nextRestartTimestring e.g. nowNextRestartTime may be used to restart the VM, in accordance with RestartMode, by setting the value of this field to “now” (case-insensitive). spec.policiesarray of object e.g. [{kind: ComputePolicy, name: <compute policy>}]Policies describes a list of policies that should be explicitly applied to this VM. Please consult a policy to determine if it may be applied directly. spec.policies[].apiVersionstring yes e.g. vsphere.policy.vmware.com/v1alpha1APIVersion defines the versioned schema of this representation of an object. spec.policies[].kindstring yes e.g. ComputePolicyKind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. spec.policies[].namestring yes e.g. <compute policy>Name refers to a unique resource in the current namespace. spec.powerOffModestring Hard, Soft, TrySoft; default TrySoftPowerOffMode describes the desired behavior when powering off a VM. There are three, supported power off modes: Hard, Soft, and TrySoft. spec.powerStatestring PoweredOff, PoweredOn, SuspendedPowerState describes the desired power state of a VirtualMachine." However, once the field is set to a non-empty value, it may no longer be set to an empty value. spec.promoteDisksModestring Online, Offline, Disabled; default OnlinePromoteDisksMode describes the mode used to promote a VM’s delta disks to full disks. The available modes are: - Disabled – Do not promote disks. spec.readinessProbeobject e.g. {guestInfo: [{key: guestinfo.ready, value: "true"}], tcpSocket: {host: 10.200.0.10, ...}}ReadinessProbe describes a probe used to determine the VM’s ready state. spec.readinessProbe.guestHeartbeatobject e.g. {thresholdStatus: green}GuestHeartbeat specifies an action involving the guest heartbeat status. spec.readinessProbe.guestHeartbeat.thresholdStatusstring yellow, green; default greenThresholdStatus is the value that the guest heartbeat status must be at or above to be considered successful. spec.readinessProbe.guestInfoarray of object e.g. [{key: guestinfo.ready, value: "true"}]GuestInfo specifies an action involving key/value pairs from GuestInfo. spec.readinessProbe.guestInfo[].keystring yes e.g. guestinfo.readyKey is the name of the GuestInfo key. The key is automatically prefixed with “guestinfo.” before being evaluated. spec.readinessProbe.guestInfo[].valuestring e.g. "true"Value is a regular expression that is matched against the value of the specified key. An empty value is the equivalent of “match any” or “.*”. spec.readinessProbe.periodSecondsinteger e.g. 10PeriodSeconds specifics how often (in seconds) to perform the probe. Defaults to 10 seconds. Minimum value is 1. spec.readinessProbe.tcpSocketobject e.g. {host: 10.200.0.10, port: 22}TCPSocket specifies an action involving a TCP port. Deprecated: The TCPSocket action requires network connectivity that is not supported in all environments. spec.readinessProbe.tcpSocket.hoststring e.g. 10.200.0.10Host is an optional host name to connect to. Host defaults to the VM IP. spec.readinessProbe.tcpSocket.portint or string yes e.g. 22Port specifies a number or name of the port to access on the VM. If the format of port is a number, it must be in the range 1 to 65535. spec.readinessProbe.timeoutSecondsinteger e.g. 10TimeoutSeconds specifies a number of seconds after which the probe times out. Defaults to 10 seconds. Minimum value is 1. spec.reservedobject e.g. {resourcePolicyName: <resource policy>}Reserved describes a set of VM configuration options reserved for system use. spec.reserved.resourcePolicyNamestring e.g. <resource policy>spec.restartModestring Hard, Soft, TrySoft; default TrySoftRestartMode describes the desired behavior for restarting a VM when spec.nextRestartTime is set to “now” (case-insensitive). spec.storageClassstring e.g. vsan-default-storage-policyStorageClass describes the name of a Kubernetes StorageClass resource used to configure this VM’s storage-related attributes. spec.suspendModestring Hard, Soft, TrySoft; default TrySoftSuspendMode describes the desired behavior when suspending a VM. There are three, supported suspend modes: Hard, Soft, and TrySoft. spec.volumesarray of object e.g. [{name: data, persistentVolumeClaim: {claimName: web-01-data, ...}}]Volumes describes a list of volumes that can be mounted to the VM. spec.volumes[].applicationTypestring OracleRAC, MicrosoftWSFCApplicationType describes the type of application for which this volume is intended to be used. spec.volumes[].controllerBusNumberinteger e.g. 0ControllerBusNumber describes the bus number of the controller to which this volume should be attached. spec.volumes[].controllerTypestring IDE, NVME, SCSI, SATAControllerType describes the type of the controller to which this volume should be attached. spec.volumes[].diskModestring IndependentNonPersistent, IndependentPersistent, NonPersistent, PersistentDiskMode describes the desired mode to use when attaching the volume. spec.volumes[].namestring yes e.g. dataName represents the volume’s name. Must be a DNS_LABEL and unique within the VM. spec.volumes[].persistentVolumeClaimobject e.g. {claimName: web-01-data, instanceVolumeClaim: {size: 50Gi, ...}}PersistentVolumeClaim represents a reference to a PersistentVolumeClaim in the same namespace. spec.volumes[].persistentVolumeClaim.claimNamestring yes e.g. web-01-dataclaimName is the name of a PersistentVolumeClaim in the same namespace as the pod using this volume. spec.volumes[].persistentVolumeClaim.instanceVolumeClaimobject e.g. {size: 50Gi, storageClass: vsan-default-storage-policy}InstanceVolumeClaim is set if the PVC is backed by instance storage. spec.volumes[].persistentVolumeClaim.instanceVolumeClaim.sizeint or string yes e.g. 50GiSize is the size of the requested instance storage volume. spec.volumes[].persistentVolumeClaim.instanceVolumeClaim.storageClassstring yes e.g. vsan-default-storage-policyStorageClass is the name of the Kubernetes StorageClass that provides the backing storage for this instance storage volume. spec.volumes[].persistentVolumeClaim.readOnlyboolean e.g. truereadOnly Will force the ReadOnly setting in VolumeMounts. Default false. spec.volumes[].removableboolean default trueRemovable describes whether or not this volume may be removed from spec.volumes. spec.volumes[].sharingModestring MultiWriter, NoneSharingMode describes the volume’s desired sharing mode. When applicationType=OracleRAC, this field defaults to MultiWriter. spec.volumes[].unitNumberinteger e.g. 1UnitNumber describes the desired unit number for attaching the volume to a storage controller. When omitted, the next available unit number of the selected controller is used.
Minimal:
vm1:
type: CCI.Supervisor.Resource
properties:
context: ${resource.namespace.id}
manifest:
apiVersion: vmoperator.vmware.com/v1alpha5
kind: VirtualMachine
metadata:
name: web-01
labels: {app: web}
spec:
className: best-effort-small
imageName: ubuntu-24.04-server-cloudimg-amd64
storageClass: vsan-default-storage-policy
wait:
conditions:
- type: VirtualMachineGuestNetworkConfigSynced
status: "True"
Recipes
A Linux user with an SSH key and a password, inline cloud-init. The password is not a string here:
passwdandhashed_passwdreference a key in a Secret, and a plain string fails withcannot restore struct from: string. The hash can come from Util.PasswordEntry:bootstrap: cloudInit: cloudConfig: users: - name: ops sudo: ALL=(ALL) NOPASSWD:ALL lock_passwd: false hashed_passwd: name: web-pw # a Secret in the namespace key: ops-passwd # holding ${resource.pw.sha512crypt} ssh_authorized_keys: - ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOkJfr8Q3cNq ops@example runcmd: - [systemctl, enable, --now, ssh]We logged in through a load balancer as
opswith that key;sudoneeded no password and the shadow entry held the$6$hash.Windows, or a long first-boot script: keep the whole cloud-config in a Secret and point
rawCloudConfigat it. Our jump hosts run cloudbase-init this way:bootstrap: cloudInit: rawCloudConfig: name: jump-bootstrap # the Secret key: user-data # the key inside itA static address on a VPC subnet. With cloud-init the DNS servers go on the interface:
network: hostName: dc01 interfaces: - name: eth0 network: {apiVersion: crd.nsx.vmware.com/v1alpha1, kind: Subnet, name: sn-mgmt} addresses: ["172.30.0.34/27"] gateway4: 172.30.0.33 nameservers: [172.30.0.34] bootstrap: cloudInit: rawCloudConfig: {name: dc-bootstrap, key: user-data}An address on a subnet without choosing it: name the subnet and leave
addressesout. VM Operator takes one from the subnet and configures the guest; ours got172.30.0.2.network: interfaces: - name: eth0 network: {apiVersion: crd.nsx.vmware.com/v1alpha1, kind: Subnet, name: sn-app}An extra data disk: a Persistent Volume Claim in the same blueprint, then the VM below. It arrived in the guest as
sdb, 5 GiB, beside the image’s 10 GiBsda:volumes: - name: data persistentVolumeClaim: claimName: web-01-dataAn ISO in the CD-ROM, for an installer (our nested hosts boot the ESXi installer this way).
guestIDbecomes mandatory:guestID: vmkernel9Guest hardware: cdrom: - name: cdrom0 image: {kind: VirtualMachineImage, name: vmi-e400a813bbd5d52a5} connected: true allowGuestControl: trueA bigger boot disk than the image’s:
advanced.bootDiskCapacity: 80Gi. The guest still has to grow its partition.Keep VMs apart. Affinity rules only work for members of a Virtual Machine Group; on a VM without
groupNamethe Supervisor refuses them (spec.groupName: Required value: when setting affinity). Our two web VMs with this rule landed on different hosts:groupName: web affinity: vmAntiAffinity: preferredDuringSchedulingPreferredDuringExecution: - labelSelector: matchLabels: {app: web} topologyKey: kubernetes.io/hostname
Status worth reading: status.network.primaryIP4 (after the wait above),
status.powerState, status.nodeName (the ESXi host), status.zone,
status.instanceUUID, status.biosUUID, status.hardwareVersion, and
status.volumes[] with attached per disk.
Gotchas
- DNS settings depend on the bootstrap provider:
spec.network.nameserversworks only with LinuxPrep and Sysprep, the per-interfacenameserversonly with CloudInit and Sysprep, and a VM with no bootstrap can have neither. The Supervisor says which:nameservers is available only with the following bootstrap providers: .... promoteDisksModedefaults toOnline: after a fast deploy from a linked clone, VM Operator copies the disks into full disks while the VM runs. For a large image that is real I/O;Disabledkeeps the linked clone and deploys faster. Our Windows jump host was ready in 15.1 minutes withDisabledagainst 17.6 with the default. VMs with snapshots cannot promote online.- The first deployment of a new image into a VPC can fail with an NSX
503638error while the image is still being cached; a retry succeeds. - Changing
classNameresizes the VM; changingmanifestin a new blueprint version recreates it.
Virtual Machine Group
CCI.Supervisor.Resource with apiVersion: vmoperator.vmware.com/v1alpha5,
kind: VirtualMachineGroup. A set of VMs placed and powered as one: a boot
order with delays between steps, and one power state for all of them.
spec field | Notes |
|---|---|
bootOrder[] | Steps, in order. Each has members[] (kind: VirtualMachine default or VirtualMachineGroup; name) and powerOnDelay before the step. |
powerState | PoweredOn (default), PoweredOff, Suspended, applied to every member. |
powerOffMode, suspendMode | TrySoft (default), Soft, Hard. |
groupName | A parent group, to nest groups. |
nextForcePowerStateSyncTime | now pushes the group’s power state to every member again. |
Every field the platform accepts (10)
Field Type Req. Values Description spec.bootOrderarray of object e.g. [{members: [{name: web-01, kind: VirtualMachine}], powerOnDelay: 30s}]BootOrder describes the boot sequence for this group members. Each boot order contains a set of members that will be powered on simultaneously, with an optional delay before powering on. spec.bootOrder[].membersarray of object e.g. [{name: web-01, kind: VirtualMachine}]Members describes the names of VirtualMachine or VirtualMachineGroup objects that are members of this boot order group. spec.bootOrder[].members[].kindstring VirtualMachine, VirtualMachineGroup; default VirtualMachineKind is the kind of member of this group, which can be either VirtualMachine or VirtualMachineGroup. If omitted, it defaults to VirtualMachine. spec.bootOrder[].members[].namestring yes e.g. web-01Name is the name of member of this group. spec.bootOrder[].powerOnDelaystring e.g. 30sPowerOnDelay is the amount of time to wait before powering on all the members of this boot order group. spec.groupNamestring e.g. <parent group>GroupName describes the name of the group that this group belongs to. spec.nextForcePowerStateSyncTimestring e.g. nowNextForcePowerStateSyncTime may be used to force sync the power state of the group to all of its members, by setting the value of this field to “now” (case-insensitive). spec.powerOffModestring Hard, Soft, TrySoftPowerOffMode describes the desired behavior when powering off a VM Group. Refer to the VirtualMachine.PowerOffMode field for more details. spec.powerStatestring PoweredOff, PoweredOn, SuspendedPowerState describes the desired power state of a VirtualMachineGroup. spec.suspendModestring Hard, Soft, TrySoftSuspendMode describes the desired behavior when suspending a VM Group. Refer to the VirtualMachine.SuspendMode field for more details.
Recipe, one VM before the next, thirty seconds apart:
appGroup:
type: CCI.Supervisor.Resource
properties:
context: ${resource.namespace.id}
manifest:
apiVersion: vmoperator.vmware.com/v1alpha5
kind: VirtualMachineGroup
metadata: {name: app}
spec:
bootOrder:
- members: [{name: web-01}]
- members: [{name: web-02}]
powerOnDelay: 30s
Each member names the group in spec.groupName: app and depends on the group
resource (dependsOn: [appGroup]), because the group is referenced only by
name.
Status worth reading: status.members[] (each member’s power state and
placement), status.conditions.
Gotchas
- A member of a later step stays off until every member of the earlier steps
is on. When our first test’s
web-01failed to create,web-02sat powered off for good. - A VM in a group doesn’t place itself; the group places its members.
Virtual Machine Service
CCI.Supervisor.Resource with apiVersion: vmoperator.vmware.com/v1alpha5,
kind: VirtualMachineService. A Kubernetes-style service in front of VMs,
selected by label. With type: LoadBalancer, the VPC’s load balancer gives
it an external address. That’s how a VM on a private subnet is reached from
outside.
spec field | Notes |
|---|---|
type | Required. LoadBalancer or ClusterIP. The API lists ExternalName too; the VM Operator documentation says it isn’t supported. |
selector | Labels of the VMs behind it. |
ports[] | name, port, targetPort, protocol (TCP, UDP, SCTP). |
loadBalancerSourceRanges[] | Source CIDRs allowed to reach a LoadBalancer service. |
loadBalancerIP, clusterIp, externalName | A requested address, a fixed cluster IP, a DNS name. |
Every field the platform accepts (11)
Field Type Req. Values Description spec.clusterIpstring e.g. 10.96.0.20ClusterIP is the IP address of the service and is usually assigned randomly by the master. spec.externalNamestring e.g. web.example.comExternalName is the external reference that kubedns or equivalent will return as a CNAME record for this service. No proxying will be involved. spec.loadBalancerIPstring e.g. 192.168.144.20LoadBalancer will get created with the IP specified in this field. spec.loadBalancerSourceRangesarray of string e.g. [10.0.0.0/8]LoadBalancerSourceRanges is an array of IP addresses in the format of CIDRs, for example: 103.21.244.0/22 and 10.0.0.0/24. spec.portsarray of object e.g. [{name: rdp, port: 3389}]Ports specifies a list of VirtualMachineServicePort to expose with this VirtualMachineService. Each of these ports will be an accessible network entry point to access this service by. spec.ports[].namestring yes e.g. rdpName describes the name to be used to identify this VirtualMachineServicePort. spec.ports[].portinteger yes e.g. 3389Port describes the external port that will be exposed by the service. spec.ports[].protocolstring yes e.g. TCPProtocol describes the Layer 4 transport protocol for this port. Supports “TCP”, “UDP”, and “SCTP”. spec.ports[].targetPortinteger yes e.g. 3389TargetPort describes the internal port open on a VirtualMachine that should be mapped to the external Port. spec.selectorobject e.g. {app: web}Selector specifies a map of key-value pairs, also known as a Label Selector, that is used to match this VirtualMachineService with the set of VirtualMachines that should back this VirtualMachineService. spec.typestring yes e.g. LoadBalancerType specifies a desired VirtualMachineServiceType for this VirtualMachineService. Supported types are ClusterIP, LoadBalancer, ExternalName.
Recipe, RDP to a jump host, the only way into our labs:
jumpAccess:
type: CCI.Supervisor.Resource
properties:
context: ${resource.namespace.id}
manifest:
apiVersion: vmoperator.vmware.com/v1alpha5
kind: VirtualMachineService
metadata: {name: jump-access}
spec:
type: LoadBalancer
selector: {app: jump}
ports:
- {name: rdp, port: 3389, targetPort: 3389, protocol: TCP}
loadBalancerSourceRanges: [10.0.0.0/8]
Status worth reading: status.loadBalancer.ingress[0].ip, the external
address.
Gotchas
LoadBalancerneeds the VPC’s load balancer. VCF Automation waits for the address by itself, so in a VPC without one the request stays in progress until it times out. A VPC made by a blueprint never has one; see VPC.- A service with several VMs behind it spreads connections across them: our SSH sessions alternated between the two web VMs.
- The palette writes
v1alpha3; we usev1alpha5, the Supervisor’s stored version. Both are served.
Subnet
CCI.Supervisor.Resource with apiVersion: crd.nsx.vmware.com/v1alpha1,
kind: Subnet. A subnet of the namespace’s VPC: a layer-2 segment with its
own address range, for VMs that need a network of their own.
spec field | Notes |
|---|---|
accessMode | Private (default): routed inside the VPC only. PrivateTGW: reachable from other VPCs through the transit gateway. Public: from the external network. |
ipv4SubnetSize | Addresses in the subnet, default 64. |
ipAddresses[] | Specific CIDRs instead of a size. |
subnetDHCPConfig.mode | DHCPDeactivated (default), DHCPServer, DHCPRelay; dhcpServerAdditionalConfig.reservedIPRanges keeps ranges out of the pool. |
advancedConfig | staticIPAllocation.enabled, connectivityState (Connected default, Disconnected), gatewayAddresses, dhcpServerAddresses. |
vpcName | The VPC, when it isn’t the namespace’s own. |
vlanConnectionName | A subnet backed by a distributed VLAN connection; not in the designer’s form. |
Every field the platform accepts (15)
Field Type Req. Values Description spec.accessModestring Private, Public, PrivateTGW, L2OnlyAccess mode of Subnet, accessible only from within VPC or from outside VPC. spec.advancedConfigobject e.g. {dhcpServerAddresses: [10.200.0.2/28], gatewayAddresses: [10.200.0.1/28]}VPC Subnet advanced configuration. spec.advancedConfig.connectivityStatestring Connected, Disconnected; default ConnectedConnectivity status of the Subnet from other Subnets of the VPC. The default value is “Connected”. spec.advancedConfig.dhcpServerAddressesarray of string e.g. [10.200.0.2/28]DHCPServerAddresses specifies custom DHCP server IP addresses for the Subnet. spec.advancedConfig.gatewayAddressesarray of string e.g. [10.200.0.1/28]GatewayAddresses specifies custom gateway IP addresses for the Subnet. spec.advancedConfig.staticIPAllocationobject e.g. {enabled: true}Static IP allocation for VPC Subnet Ports. spec.advancedConfig.staticIPAllocation.enabledboolean e.g. trueActivate or deactivate static IP allocation for VPC Subnet Ports. If the DHCP mode is DHCPDeactivated or not set, its default value is true. spec.ipAddressesarray of string e.g. [10.200.0.0/28]Subnet CIDRS. spec.ipv4SubnetSizeinteger e.g. 32Size of Subnet based upon estimated workload count. spec.subnetDHCPConfigobject e.g. {dhcpServerAdditionalConfig: {reservedIPRanges: [10.200.0.10-10.200.0.15]}, ...}DHCP configuration for Subnet. spec.subnetDHCPConfig.dhcpServerAdditionalConfigobject e.g. {reservedIPRanges: [10.200.0.10-10.200.0.15]}Additional DHCP server config for a VPC Subnet. spec.subnetDHCPConfig.dhcpServerAdditionalConfig.reservedIPRangesarray of string e.g. [10.200.0.10-10.200.0.15]Reserved IP ranges. Supported formats include: [“192.168.1.1”, “192.168.1.3-192.168.1.100”] spec.subnetDHCPConfig.modestring DHCPServer, DHCPRelay, DHCPDeactivatedDHCP Mode. DHCPDeactivated will be used if it is not defined. It cannot switch from DHCPDeactivated to DHCPServer or DHCPRelay. spec.vlanConnectionNamestring e.g. <distributed VLAN connection>Distributed VLAN Connection name. spec.vpcNamestring e.g. ${resource.vpc.name}VPC name of the Subnet.
Minimal, our lab’s management subnet:
snMgmt:
type: CCI.Supervisor.Resource
properties:
context: ${resource.namespace.id}
manifest:
apiVersion: crd.nsx.vmware.com/v1alpha1
kind: Subnet
metadata: {name: sn-mgmt}
spec: {accessMode: Private, ipv4SubnetSize: 32}
A VM joins it by name, in an interface:
network: {apiVersion: crd.nsx.vmware.com/v1alpha1, kind: Subnet, name: sn-mgmt}.
Status worth reading: status.networkAddresses, status.gatewayAddresses,
status.conditions (Realized).
Gotchas
- DHCP is off by default. VMs still get addresses: VM Operator takes one from the subnet and hands it to the guest through the bootstrap provider.
- Subnets are NSX objects of the VPC. After a deployment is deleted they can outlive it for a few minutes; wait until the VPC lists none before reusing the addresses.
Persistent Volume Claim
CCI.Supervisor.Resource with apiVersion: v1,
kind: PersistentVolumeClaim. A disk from a storage class, for a VM’s
volumes or a pod.
spec field | Notes |
|---|---|
storageClassName | A storage class the namespace has. |
resources.requests.storage | The size: 100Gi. |
accessModes[] | ReadWriteOnce for a VM disk; ReadWriteMany where the storage supports it. |
volumeMode | Filesystem or Block. |
dataSource, dataSourceRef | Restore from a snapshot or clone another claim. |
Every field the platform accepts (23)
Field Type Req. Values Description spec.accessModesarray of string e.g. [ReadWriteOnce]accessModes contains the desired access modes the volume should have. spec.dataSourceobject e.g. {apiGroup: snapshot.storage.k8s.io, kind: <kind>}TypedLocalObjectReference contains enough information to let you locate the typed referenced object inside the same namespace. spec.dataSource.apiGroupstring e.g. snapshot.storage.k8s.ioAPIGroup is the group for the resource being referenced. If APIGroup is not specified, the specified Kind must be in the core API group. spec.dataSource.kindstring yes e.g. <kind>Kind is the type of resource being referenced spec.dataSource.namestring yes e.g. <name>Name is the name of resource being referenced spec.dataSourceRefobject e.g. {apiGroup: snapshot.storage.k8s.io, namespace: ns-source}TypedObjectReference contains enough information to let you locate the typed referenced object spec.dataSourceRef.apiGroupstring e.g. snapshot.storage.k8s.ioAPIGroup is the group for the resource being referenced. If APIGroup is not specified, the specified Kind must be in the core API group. spec.dataSourceRef.kindstring yes e.g. <kind>Kind is the type of resource being referenced spec.dataSourceRef.namestring yes e.g. <name>Name is the name of resource being referenced spec.dataSourceRef.namespacestring e.g. ns-sourceNamespace is the namespace of resource being referenced Note that when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant object is required in the referent namespace to … spec.resourcesobject e.g. {limits: {storage: 20Gi}, requests: {storage: 20Gi}}VolumeResourceRequirements describes the storage resource requirements for a volume. spec.resources.limitsobject e.g. {storage: 20Gi}Limits describes the maximum amount of compute resources allowed. spec.resources.requestsobject e.g. {storage: 20Gi}Requests describes the minimum amount of compute resources required. spec.selectorobject e.g. {matchExpressions: [{key: app, operator: In}], matchLabels: {tier: fast}}A label selector is a label query over a set of resources. The result of matchLabels and matchExpressions are ANDed. spec.selector.matchExpressionsarray of object e.g. [{key: app, operator: In}]matchExpressions is a list of label selector requirements. The requirements are ANDed. spec.selector.matchExpressions[].keystring yes e.g. appkey is the label key that the selector applies to. spec.selector.matchExpressions[].operatorstring yes e.g. Inoperator represents a key’s relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. spec.selector.matchExpressions[].valuesarray of string e.g. [fast]values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. spec.selector.matchLabelsobject e.g. {tier: fast}matchLabels is a map of {key,value} pairs. spec.storageClassNamestring e.g. vsan-default-storage-policystorageClassName is the name of the StorageClass required by the claim. spec.volumeAttributesClassNamestring e.g. <volume attributes class>volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim. spec.volumeModestring Block, FilesystemvolumeMode defines what type of volume is required by the claim. Value of Filesystem is implied when not included in claim spec. spec.volumeNamestring e.g. <existing PersistentVolume>volumeName is the binding reference to the PersistentVolume backing this claim.
dataDisk:
type: CCI.Supervisor.Resource
properties:
context: ${resource.namespace.id}
manifest:
apiVersion: v1
kind: PersistentVolumeClaim
metadata: {name: web-01-data}
spec:
accessModes: [ReadWriteOnce]
storageClassName: vsan-default-storage-policy
resources:
requests:
storage: 5Gi
Status worth reading: status.phase (Bound), status.capacity.storage.
Gotchas
- The designer’s form calls the field
accessMode; the Supervisor refuses that spelling (unknown field "spec.accessMode"). - A
-latebindingstorage class (WaitForFirstConsumer) puts no constraint on where the VM lands; our nested hosts’ vSAN capacity disks use one.
Secret
CCI.Supervisor.Resource with apiVersion: v1, kind: Secret. Key/value
data in the namespace. In a blueprint it mostly carries a VM’s cloud-init or
Sysprep data, or a password a VM’s cloudConfig references.
| Field | Notes |
|---|---|
stringData | Plain values; the Supervisor encodes them. The easy one in a blueprint. |
data | Base64-encoded values. |
type | Opaque for your own data; kubernetes.io/tls and the other standard types. |
immutable | true stops changes after creation. |
Every field the platform accepts (4)
Field Type Req. Values Description dataobject e.g. {password: <base64>}Data contains the secret data. Each key must consist of alphanumeric characters, ‘-’, ‘_’ or ‘.’. immutableboolean e.g. trueImmutable, if set to true, ensures that data stored in the Secret cannot be updated (only object metadata can be modified). stringDataobject e.g. {password: ${input.password}}stringData allows specifying non-binary secret data in string form. It is provided as a write-only input field for convenience. typestring e.g. OpaqueUsed to facilitate programmatic handling of secret data.
jumpConfig:
type: CCI.Supervisor.Resource
properties:
context: ${resource.namespace.id}
manifest:
apiVersion: v1
kind: Secret
metadata: {name: jump-bootstrap}
type: Opaque
stringData:
user-data: |
#cloud-config
users:
- name: student
passwd: ${input.jumpPassword}
Gotcha: an input marked encrypted: true stays hidden in the request,
but whatever a Secret holds can be read by anyone allowed to read Secrets in
the namespace.
Kubernetes Cluster
CCI.Supervisor.Resource with apiVersion: cluster.x-k8s.io/v1beta1,
kind: Cluster. A VKS cluster, described by a ClusterClass topology. The
designer’s schema stops at topology.variables. What the variables can be
comes from the ClusterClass: builtin-generic-v3.6.0 on our platform.
spec field | Notes |
|---|---|
clusterNetwork | Required. pods.cidrBlocks, services.cidrBlocks, serviceDomain. Without services VKS refuses the cluster: spec.ClusterNetwork.Services must be defined. |
topology.class | Required. The ClusterClass. |
topology.classNamespace | Where the ClusterClass lives; not in the designer’s form. See the gotchas. |
topology.version | Required. A Kubernetes release the Supervisor offers, for example v1.35.5+vmware.1-vkr.1. |
topology.controlPlane | replicas (1 or 3), metadata, machineHealthCheck, node drain and deletion timeouts. |
topology.workers.machineDeployments[] | class: node-pool (the only worker class), name, replicas, and variables.overrides[] per pool. |
topology.variables[] | name and value pairs, below. |
Every field the platform accepts (85)
Field Type Req. Values Description spec.availabilityGatesarray of object e.g. [{conditionType: <condition type>, polarity: Positive}]availabilityGates specifies additional conditions to include when evaluating Cluster Available condition. spec.availabilityGates[].conditionTypestring yes e.g. <condition type>conditionType refers to a condition with matching type in the Cluster’s condition list. If the conditions doesn’t exist, it will be treated as unknown. spec.availabilityGates[].polaritystring Positive, Negativepolarity of the conditionType specified in this availabilityGate. Valid values are Positive, Negative and omitted. When omitted, the default behaviour will be Positive. spec.clusterNetworkobject e.g. {pods: {cidrBlocks: [192.168.156.0/20]}, serviceDomain: cluster.local}clusterNetwork represents the cluster network configuration. spec.clusterNetwork.apiServerPortinteger e.g. 6443apiServerPort specifies the port the API Server should bind to. Defaults to 6443. spec.clusterNetwork.podsobject e.g. {cidrBlocks: [192.168.156.0/20]}pods is the network ranges from which Pod networks are allocated. spec.clusterNetwork.pods.cidrBlocksarray of string yes e.g. [192.168.156.0/20]cidrBlocks is a list of CIDR blocks. spec.clusterNetwork.serviceDomainstring e.g. cluster.localserviceDomain is the domain name for services. spec.clusterNetwork.servicesobject e.g. {cidrBlocks: [10.96.0.0/12]}services is the network ranges from which service VIPs are allocated. spec.clusterNetwork.services.cidrBlocksarray of string yes e.g. [10.96.0.0/12]cidrBlocks is a list of CIDR blocks. spec.controlPlaneEndpointobject e.g. {host: 192.168.144.40, port: 6443}controlPlaneEndpoint represents the endpoint used to communicate with the control plane. spec.controlPlaneEndpoint.hoststring e.g. 192.168.144.40host is the hostname on which the API server is serving. spec.controlPlaneEndpoint.portinteger e.g. 6443port is the port on which the API server is serving. spec.controlPlaneRefobject e.g. {kind: KubeadmControlPlane, name: lab-vks-cp}controlPlaneRef is an optional reference to a provider-specific resource that holds the details for provisioning the Control Plane for a Cluster. spec.controlPlaneRef.apiVersionstring e.g. controlplane.cluster.x-k8s.io/v1beta1API version of the referent. spec.controlPlaneRef.fieldPathstring e.g. (set by the platform)If referring to a piece of an object instead of an entire object, this string should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. spec.controlPlaneRef.kindstring e.g. KubeadmControlPlaneKind of the referent. spec.controlPlaneRef.namestring e.g. lab-vks-cpName of the referent. spec.controlPlaneRef.namespacestring e.g. ns-labNamespace of the referent. spec.controlPlaneRef.resourceVersionstring e.g. (set by the platform)Specific resourceVersion to which this reference is made, if any. spec.controlPlaneRef.uidstring e.g. (set by the platform)UID of the referent. spec.infrastructureRefobject e.g. {kind: VSphereCluster, name: lab-vks}infrastructureRef is a reference to a provider-specific resource that holds the details for provisioning infrastructure for a cluster in said provider. spec.infrastructureRef.apiVersionstring e.g. vmware.infrastructure.cluster.x-k8s.io/v1beta1API version of the referent. spec.infrastructureRef.fieldPathstring e.g. (set by the platform)If referring to a piece of an object instead of an entire object, this string should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. spec.infrastructureRef.kindstring e.g. VSphereClusterKind of the referent. spec.infrastructureRef.namestring e.g. lab-vksName of the referent. spec.infrastructureRef.namespacestring e.g. ns-labNamespace of the referent. spec.infrastructureRef.resourceVersionstring e.g. (set by the platform)Specific resourceVersion to which this reference is made, if any. spec.infrastructureRef.uidstring e.g. (set by the platform)UID of the referent. spec.pausedboolean e.g. truepaused can be used to prevent controllers from processing the Cluster and all its associated objects. spec.topologyobject e.g. {class: builtin-generic-v3.6.0, classNamespace: vmware-system-vks-public}topology encapsulates the topology for the cluster. spec.topology.classstring yes e.g. builtin-generic-v3.6.0class is the name of the ClusterClass object to create the topology. spec.topology.classNamespacestring e.g. vmware-system-vks-publicclassNamespace is the namespace of the ClusterClass that should be used for the topology. If classNamespace is empty or not set, it is defaulted to the namespace of the Cluster object. spec.topology.controlPlaneobject e.g. {replicas: 1, machineHealthCheck: {maxUnhealthy: 40%, nodeStartupTimeout: 10m}}controlPlane describes the cluster control plane. spec.topology.controlPlane.machineHealthCheckobject e.g. {maxUnhealthy: 40%, nodeStartupTimeout: 10m}machineHealthCheck allows to enable, disable and override the MachineHealthCheck configuration in the ClusterClass for this control plane. spec.topology.controlPlane.machineHealthCheck.enableboolean e.g. trueenable controls if a MachineHealthCheck should be created for the target machines. If false: No MachineHealthCheck will be created. spec.topology.controlPlane.machineHealthCheck.maxUnhealthyint or string e.g. 40%maxUnhealthy specifies the maximum number of unhealthy machines allowed. Any further remediation is only allowed if at most “maxUnhealthy” machines selected by “selector” are not healthy. spec.topology.controlPlane.machineHealthCheck.nodeStartupTimeoutstring e.g. 10mnodeStartupTimeout allows to set the maximum time for MachineHealthCheck to consider a Machine unhealthy if a corresponding Node isn’t associated through a Spec.ProviderID field.spec.topology.controlPlane.machineHealthCheck.remediationTemplateobject e.g. {apiVersion: <group>/<version>, kind: <remediation template kind>, name: <name>}remediationTemplate is a reference to a remediation template provided by an infrastructure provider. spec.topology.controlPlane.machineHealthCheck.unhealthyConditionsarray of object e.g. [{type: Ready, status: Unknown, timeout: 300s}]unhealthyConditions contains a list of the conditions that determine whether a node is considered unhealthy. The conditions are combined in a logical OR, i.e. spec.topology.controlPlane.machineHealthCheck.unhealthyRangestring e.g. '[1-3]'unhealthyRange specifies the range of unhealthy machines allowed. spec.topology.controlPlane.metadataobject e.g. {annotations: {owner: team-a}, labels: {app: web}}metadata is the metadata applied to the ControlPlane and the Machines of the ControlPlane if the ControlPlaneTemplate referenced by the ClusterClass is machine based. spec.topology.controlPlane.metadata.annotationsobject e.g. {owner: team-a}annotations is an unstructured key value map stored with a resource that may be set by external tools to store and retrieve arbitrary metadata. spec.topology.controlPlane.metadata.labelsobject e.g. {app: web}labels is a map of string keys and values that can be used to organize and categorize (scope and select) objects. May match selectors of replication controllers and services. spec.topology.controlPlane.nodeDeletionTimeoutstring e.g. 10mnodeDeletionTimeout defines how long the controller will attempt to delete the Node that the Machine hosts after the Machine is marked for deletion. spec.topology.controlPlane.nodeDrainTimeoutstring e.g. 10mnodeDrainTimeout is the total amount of time that the controller will spend on draining a node. The default value is 0, meaning that the node can be drained without any time limitations. spec.topology.controlPlane.nodeVolumeDetachTimeoutstring e.g. 10mnodeVolumeDetachTimeout is the total amount of time that the controller will spend on waiting for all volumes to be detached. spec.topology.controlPlane.readinessGatesarray of object e.g. [{conditionType: <condition type>, polarity: Positive}]readinessGates specifies additional conditions to include when evaluating Machine Ready condition. This field can be used e.g. spec.topology.controlPlane.readinessGates[].conditionTypestring yes e.g. <condition type>conditionType refers to a condition with matching type in the Machine’s condition list. If the conditions doesn’t exist, it will be treated as unknown. spec.topology.controlPlane.readinessGates[].polaritystring Positive, Negativepolarity of the conditionType specified in this readinessGate. Valid values are Positive, Negative and omitted. When omitted, the default behaviour will be Positive. spec.topology.controlPlane.replicasinteger e.g. 1replicas is the number of control plane nodes. spec.topology.controlPlane.variablesobject e.g. {overrides: [{name: vmClass, value: best-effort-medium}]}variables can be used to customize the ControlPlane through patches. spec.topology.controlPlane.variables.overridesarray of object e.g. [{name: vmClass, value: best-effort-medium}]overrides can be used to override Cluster level variables. spec.topology.rolloutAfterstring e.g. 2026-10-01T22:00:00ZrolloutAfter performs a rollout of the entire cluster one component at a time, control plane first and then machine deployments. spec.topology.variablesarray of object e.g. [{name: vmClass, value: best-effort-small}]variables can be used to customize the Cluster through patches. They must comply to the corresponding VariableClasses defined in the ClusterClass. spec.topology.variables[].definitionFromstring e.g. <patch name>definitionFrom specifies where the definition of this Variable is from. Deprecated: This field is deprecated, must not be set anymore and is going to be removed in the next apiVersion. spec.topology.variables[].namestring yes e.g. vmClassname of the variable. spec.topology.variables[].valueany yes e.g. best-effort-smallvalue of the variable. Note: the value will be validated against the schema of the corresponding ClusterClassVariable from the ClusterClass. spec.topology.versionstring yes e.g. v1.35.5+vmware.1-vkr.1version is the Kubernetes version of the cluster. spec.topology.workersobject e.g. {machineDeployments: [{name: np-1, class: node-pool}], machinePools: [{name: mp-1, ...}]}workers encapsulates the different constructs that form the worker nodes for the cluster. spec.topology.workers.machineDeploymentsarray of object e.g. [{name: np-1, class: node-pool}]machineDeployments is a list of machine deployments in the cluster. spec.topology.workers.machineDeployments[].classstring yes e.g. node-poolclass is the name of the MachineDeploymentClass used to create the set of worker nodes. spec.topology.workers.machineDeployments[].failureDomainstring e.g. domain-c9failureDomain is the failure domain the machines will be created in. Must match a key in the FailureDomains map stored on the cluster object. spec.topology.workers.machineDeployments[].machineHealthCheckobject e.g. {enable: true}machineHealthCheck allows to enable, disable and override the MachineHealthCheck configuration in the ClusterClass for this MachineDeployment. spec.topology.workers.machineDeployments[].metadataobject e.g. {labels: {pool: np-1}}metadata is the metadata applied to the MachineDeployment and the machines of the MachineDeployment. At runtime this metadata is merged with the corresponding metadata from the ClusterClass. spec.topology.workers.machineDeployments[].minReadySecondsinteger e.g. 10minReadySeconds is the minimum number of seconds for which a newly created machine should be ready. Defaults to 0 (machine will be considered available as soon as it is ready) spec.topology.workers.machineDeployments[].namestring yes e.g. np-1name is the unique identifier for this MachineDeploymentTopology. The value is used with other unique identifiers to create a MachineDeployment’s Name (e.g. spec.topology.workers.machineDeployments[].nodeDeletionTimeoutstring e.g. 10mnodeDeletionTimeout defines how long the controller will attempt to delete the Node that the Machine hosts after the Machine is marked for deletion. spec.topology.workers.machineDeployments[].nodeDrainTimeoutstring e.g. 10mnodeDrainTimeout is the total amount of time that the controller will spend on draining a node. The default value is 0, meaning that the node can be drained without any time limitations. spec.topology.workers.machineDeployments[].nodeVolumeDetachTimeoutstring e.g. 10mnodeVolumeDetachTimeout is the total amount of time that the controller will spend on waiting for all volumes to be detached. spec.topology.workers.machineDeployments[].readinessGatesarray of object e.g. [{conditionType: <condition type>}]readinessGates specifies additional conditions to include when evaluating Machine Ready condition. This field can be used e.g. spec.topology.workers.machineDeployments[].replicasinteger e.g. 1replicas is the number of worker nodes belonging to this set. spec.topology.workers.machineDeployments[].strategyobject e.g. {type: RollingUpdate, rollingUpdate: {maxSurge: 1}}strategy is the deployment strategy to use to replace existing machines with new ones. spec.topology.workers.machineDeployments[].variablesobject e.g. {overrides: [{name: vmClass, value: best-effort-large}]}variables can be used to customize the MachineDeployment through patches. spec.topology.workers.machinePoolsarray of object e.g. [{name: mp-1, class: <machine pool class>}]machinePools is a list of machine pools in the cluster. spec.topology.workers.machinePools[].classstring yes e.g. <machine pool class>class is the name of the MachinePoolClass used to create the pool of worker nodes. spec.topology.workers.machinePools[].failureDomainsarray of string e.g. [domain-c9]failureDomains is the list of failure domains the machine pool will be created in. Must match a key in the FailureDomains map stored on the cluster object. spec.topology.workers.machinePools[].metadataobject e.g. {labels: {pool: mp-1}}metadata is the metadata applied to the MachinePool. At runtime this metadata is merged with the corresponding metadata from the ClusterClass. spec.topology.workers.machinePools[].minReadySecondsinteger e.g. 10minReadySeconds is the minimum number of seconds for which a newly created machine pool should be ready. Defaults to 0 (machine will be considered available as soon as it is ready) spec.topology.workers.machinePools[].namestring yes e.g. mp-1name is the unique identifier for this MachinePoolTopology. The value is used with other unique identifiers to create a MachinePool’s Name (e.g. spec.topology.workers.machinePools[].nodeDeletionTimeoutstring e.g. 10mnodeDeletionTimeout defines how long the controller will attempt to delete the Node that the MachinePool hosts after the MachinePool is marked for deletion. spec.topology.workers.machinePools[].nodeDrainTimeoutstring e.g. 10mnodeDrainTimeout is the total amount of time that the controller will spend on draining a node. The default value is 0, meaning that the node can be drained without any time limitations. spec.topology.workers.machinePools[].nodeVolumeDetachTimeoutstring e.g. 10mnodeVolumeDetachTimeout is the total amount of time that the controller will spend on waiting for all volumes to be detached. spec.topology.workers.machinePools[].replicasinteger e.g. 2replicas is the number of nodes belonging to this pool. spec.topology.workers.machinePools[].variablesobject e.g. {overrides: [{name: vmClass, value: best-effort-large}]}variables can be used to customize the MachinePool through patches.
The ClusterClass’s variables (builtin-generic-v3.6.0); vmClass and
storageClass are required:
| Variable | What it sets |
|---|---|
vmClass | The VM class for the nodes. |
storageClass | The storage class for node disks. |
volumes | Extra node disks: name, capacity, mountPath, storageClass. |
node | labels, taints and firewall for the nodes. |
osConfiguration | ntp.servers, trust.additionalTrustedCAs, systemProxy (http, https, noProxy), user (an administrator and its SSH key), sshd, fips, grub, directoryJoin, ubuntuPro, tuned, securityContext. |
kubernetes | endpointFQDNs, certificateRotation (on by default), and API server, kubelet, controller-manager and etcd settings. |
networks | The nodes’ interfaces: one primary and optional secondary networks. |
resourceConfiguration | systemReserved CPU and memory for the kubelet. |
vsphereOptions | persistentVolumes: which storage classes the cluster’s PVCs may use. |
bootstrapAddons | The CNI, through cniRef. |
Every field the platform accepts (147)
Field Type Req. Values Description bootstrapAddonsobject e.g. {cniRef: {name: <CNI package config>, namespace: <its namespace>}}BootstrapAddons defines Addons to be installed on Cluster during bootstrapping. Only supported with Kubernetes 1.35 and above. bootstrapAddons.cniRefobject yes e.g. {name: <CNI package config>, namespace: <its namespace>}CNI Addon to instantiate for Cluster. Used to select CNI rather than ClusterBootstrap spec.CNI field. Compatible Addon/AddonRelease must exist. bootstrapAddons.cniRef.namestring yes e.g. <CNI package config>Name of the Addon being referenced. bootstrapAddons.cniRef.namespacestring e.g. <its namespace>Namespace of the addon being referenced. If not specified, will use the default public namespace defined by the addon manager. kubeAPIServerFQDNsarray of string e.g. [api.lab.example.com]Deprecated: This variable is deprecated. Use kubernetes.endpointFQDNs instead. This variable will be removed in a future release. kubernetesobject e.g. {apiServerConfiguration: {logs: {flushFrequency: 5s, verbosity: 2}, ...}}Kubernetes configures cluster-wide settings for the Kubernetes cluster, typically applied to the control plane. Supported scopes: cluster, controlPlane, workers kubernetes.apiServerConfigurationobject e.g. {logs: {flushFrequency: 5s, verbosity: 2}, maxMutatingRequestsInFlight: 200}APIServerConfiguration contains configuration options for the Kubernetes API server. kubernetes.apiServerConfiguration.logsobject e.g. {flushFrequency: 5s, verbosity: 2}Logging configures the logging options for the API server, including log levels, formats, and output destinations. Refer to the Kubernetes component-base logs options for more information. kubernetes.apiServerConfiguration.logs.flushFrequencystring e.g. 5sFlushFrequency is the maximum time between log flushes. If specified as a string, it’s parsed as a duration (e.g., “1s”). kubernetes.apiServerConfiguration.logs.formatstring text, jsonFormat specifies the structure of log messages. Supported values are “text” (default) and “json”. Corresponds to –logging-format flag. kubernetes.apiServerConfiguration.logs.verbosityinteger e.g. 2Verbosity is the threshold that determines which log messages are logged. Default is zero which logs only the most important messages. kubernetes.apiServerConfiguration.maxMutatingRequestsInFlightinteger e.g. 200MaxMutatingRequestsInFlight is the maximum number of parallel mutating requests. Every further request has to wait. kubernetes.apiServerConfiguration.maxRequestsInFlightinteger e.g. 400MaxRequestsInFlight is the maximum number of parallel non-long-running requests. Every further request has to wait. kubernetes.apiServerConfiguration.profilingboolean e.g. trueProfiling enables profiling via web interface host:port/debug/pprof/ Default: false kubernetes.apiServerConfiguration.requestTimeoutstring e.g. 60sRequestTimeout is the duration after which all non-long-running requests will be timed out. Corresponds to the –request-timeout flag. kubernetes.certificateRotationobject e.g. {enabled: true, renewalDaysBeforeExpiry: 90}CertificateRotation configures options for the automatic rotation of control plane certificates which have a default validity of 12 months. kubernetes.certificateRotation.enabledboolean default trueEnabled controls enablement of auto certificate rotation kubernetes.certificateRotation.renewalDaysBeforeExpiryinteger default 90RenewalDaysBeforeExpiry states the number of days before certificate expiry to initiate the renewal of certificates. kubernetes.endpointFQDNsarray of string e.g. [api.lab.example.com]EndpointFQDNs Configure FQDN aliases for the control plane endpoint for example to allow users to connect to the cluster using https://k8s.prod.example.com/ kubernetes.etcdConfigurationobject e.g. {maximumDBSizeGiB: 8}EtcdConfiguration contains configuration options for the etcd database used by Kubernetes. These settings control etcd behavior including database size limits and performance tuning. kubernetes.etcdConfiguration.maximumDBSizeGiBinteger yes e.g. 8MaximumDBSizeGiB specifies the maximum size of the etcd database in GiB. This value is used to set –quota-backend-bytes for etcd. kubernetes.kubeControllerManagerConfigurationobject e.g. {terminatedPodGCThreshold: 1000}KubeControllerManagerConfiguration contains configuration options for the kube-controller-manager. Supported scopes: cluster, controlPlane kubernetes.kubeControllerManagerConfiguration.terminatedPodGCThresholdinteger e.g. 1000TerminatedPodGCThreshold is the number of terminated pods that can exist before the terminated pod garbage collector starts deleting terminated pods. kubernetes.kubeletConfigurationobject e.g. {allowedUnsafeSysctls: [net.core.somaxconn], eventBurst: 100}KubeletConfiguration contains configuration options for the kubelet running on worker nodes. kubernetes.kubeletConfiguration.allowedUnsafeSysctlsarray of string e.g. [net.core.somaxconn]AllowedUnsafeSysctls is a comma separated allowlist of unsafe sysctls or sysctl patterns (ending in *). All safe sysctls are enabled by default.kubernetes.kubeletConfiguration.containerLogMaxFilesinteger e.g. 5ContainerLogMaxFiles is the maximum number of container log files that can be present for a container. Default: 5 kubernetes.kubeletConfiguration.containerLogMaxSizeMiBinteger e.g. 10ContainerLogMaxSize defines the maximum size of the container log file before it is rotated in MiB. kubernetes.kubeletConfiguration.eventBurstinteger e.g. 100EventBurst is the maximum size of a burst of event creations, temporarily allows event creations to burst to this number, while still not exceeding eventRecordQPS. kubernetes.kubeletConfiguration.eventRecordQPSinteger e.g. 50EventRecordQPS is the maximum event creations per second. If 0, there is no limit enforced. Corresponds to –event-qps kubelet flag. kubernetes.kubeletConfiguration.healthzBindAddressstring e.g. 127.0.0.1HealthzBindAddress is the IP address for the healthz server to serve on. Default: “127.0.0.1” kubernetes.kubeletConfiguration.imageGCHighThresholdPercentinteger e.g. 85ImageGCHighThresholdPercent is the percent of disk usage after which image garbage collection is always run. The percent is calculated as this field value out of 100. kubernetes.kubeletConfiguration.imageGCLowThresholdPercentinteger e.g. 80ImageGCLowThresholdPercent is the percent of disk usage before which image garbage collection is never run. Lowest disk usage to garbage collect to. kubernetes.kubeletConfiguration.imageMaximumGCAgestring e.g. 168hImageMaximumGCAge is the maximum age an image can be unused before it is garbage collected. kubernetes.kubeletConfiguration.imageMinimumGCAgestring e.g. 2mImageMinimumGCAge is the minimum age for an unused image before it is garbage collected. Default: “2m” kubernetes.kubeletConfiguration.imagePullCredentialsVerificationPolicystring NeverVerify, NeverVerifyPreloadedImages, NeverVerifyAllowlistedImages, AlwaysVerifyImagePullCredentialsVerificationPolicy determines how credentials should be verified when pod requests an image that is already present on the node. kubernetes.kubeletConfiguration.loggingobject e.g. {flushFrequency: 5s, verbosity: 2}Logging specifies the logging configuration options for the kubelet. This controls log levels, formats, and output destinations for kubelet logs. kubernetes.kubeletConfiguration.logging.flushFrequencystring e.g. 5sFlushFrequency is the maximum time between log flushes. If specified as a string, it’s parsed as a duration (e.g., “1s”). kubernetes.kubeletConfiguration.logging.formatstring text, jsonFormat specifies the structure of log messages. Supported values are “text” (default) and “json”. Corresponds to –logging-format flag. kubernetes.kubeletConfiguration.logging.verbosityinteger e.g. 2Verbosity is the threshold that determines which log messages are logged. Default is zero which logs only the most important messages. kubernetes.kubeletConfiguration.maxParallelImagePullsinteger e.g. 5MaxParallelImagePulls sets the maximum number of image pulls in parallel. This field is only used when SerializeImagePulls is false. kubernetes.kubeletConfiguration.maxPodsinteger e.g. 110MaxPods is the number of pods that can run on this Kubelet. Default: 110 NOTE: By default, the maximum allowed value is 250. kubernetes.kubeletConfiguration.podPidsLimitinteger e.g. 4096PodPidsLimit is the maximum number of PIDs in any pod. Use Kubelet default (-1) when omitted. Default: nil kubernetes.kubeletConfiguration.preloadedImagesVerificationAllowlistarray of string e.g. [registry.example.local/*]PreloadedImagesVerificationAllowlist specifies a list of images that are exempted from credential reverification for the “NeverVerifyAllowlistedImages” imagePullCredentialsVerificationPolicy.kubernetes.kubeletConfiguration.registryBurstinteger e.g. 10RegistryBurst is the maximum size of bursty pulls, temporarily allows pulls to burst to this number, while still not exceeding registryPullQPS. kubernetes.kubeletConfiguration.registryPullQPSinteger e.g. 5RegistryPullQPS is the limit of registry pulls per second. Set to 0 for no limit. Default: 5 kubernetes.kubeletConfiguration.serializeImagePullsboolean e.g. trueSerializeImagePulls when enabled, tells the Kubelet to pull images one at a time. Default: true kubernetes.kubeletConfiguration.streamingConnectionIdleTimeoutstring e.g. 4hStreamingConnectionIdleTimeout is the maximum time a streaming connection can be idle before the connection is automatically closed. kubernetes.securityobject e.g. {podSecurityStandard: {auditVersion: latest, enforceVersion: latest}, ...}Security configures Kubernetes specific security settings. kubernetes.security.podSecurityStandardobject e.g. {auditVersion: latest, enforceVersion: latest}PodSecurityStandard configures the PodSecurityStandard settings for the cluster. kubernetes.security.podSecurityStandard.auditstring ``, privileged, baseline, restrictedAudit sets the level for the audit PodSecurityConfiguration mode. Policy violations trigger an audit annotation, but are otherwise allowed One of “”, privileged, baseline, restricted. kubernetes.security.podSecurityStandard.auditVersionstring e.g. latestAuditVersion can be used to pin the policy to the version that shipped with a given Kubernetes minor version (e.g. v1.31) when in audit mode. kubernetes.security.podSecurityStandard.deactivatedboolean default falseDeactivated disables the patches for Pod Security Standard via AdmissionConfiguration. kubernetes.security.podSecurityStandard.enforcestring ``, privileged, baseline, restrictedEnforce sets the level for the enforce PodSecurityConfiguration mode. Policy violations cause the pod to be rejected. kubernetes.security.podSecurityStandard.enforceVersionstring e.g. latestEnforceVersion can be used to pin the policy to the version that shipped with a given Kubernetes minor version (e.g. kubernetes.security.podSecurityStandard.exemptionsobject e.g. {namespaces: [monitoring]}Exemptions can be statically configured based on (requesting) user, RuntimeClass, or namespace. A request meeting exemption criteria is ignored by the admission plugin. kubernetes.security.podSecurityStandard.warnstring ``, privileged, baseline, restrictedWarn sets the level for the warn PodSecurityConfiguration mode. Policy violations trigger a user-facing warning, but are otherwise allowed. kubernetes.security.podSecurityStandard.warnVersionstring e.g. latestWarnVersion can be used to pin the policy to the version that shipped with a given Kubernetes minor version (e.g. v1.31) when in warn mode. kubernetes.security.resourceQuotaConfigurationobject e.g. {enabled: false}ResourceQuotaConfiguration configures the ResourceQuota admission control settings for the cluster. kubernetes.security.resourceQuotaConfiguration.enabledboolean default falseEnabled enables the patches for ResourceQuotaConfiguration via AdmissionConfiguration. networksobject e.g. {interfaces: {primary: {network: {apiVersion: crd.nsx.vmware.com/v1alpha1, ...}}}}Networks defines the network configuration for the cluster networks.interfacesobject e.g. {primary: {network: {apiVersion: crd.nsx.vmware.com/v1alpha1, kind: SubnetSet, ...}}}Interfaces describes one primary (eth0) and zero or more secondary interfaces attached to Node virtual machine. networks.interfaces.primaryobject e.g. {network: {apiVersion: crd.nsx.vmware.com/v1alpha1, kind: SubnetSet, ...}}Primary is the primary network interface which is used to connect the Kubernetes primary network for Load balancer, Service discovery, Pod traffic and management traffic etc. networks.interfaces.primary.mtuinteger e.g. 1500MTU is the Maximum Transmission Unit size in bytes. networks.interfaces.primary.networkobject yes e.g. {apiVersion: crd.nsx.vmware.com/v1alpha1, kind: SubnetSet, name: <subnet set>}Network is the name of the network resource to which this interface is connected. networks.interfaces.primary.routesarray of object e.g. [{to: 172.16.0.0/16, via: 10.244.0.1}]Routes is a list of optional, static routes. networks.interfaces.secondaryarray of object e.g. [{name: eth1, network: {apiVersion: crd.nsx.vmware.com/v1alpha1, kind: Subnet, ...}}]Secondary network is supported with network provider NSX-VPC and vsphere-network. networks.interfaces.secondary[].mtuinteger e.g. 1500MTU is the Maximum Transmission Unit size in bytes. networks.interfaces.secondary[].namestring yes e.g. eth1Name describes the unique name of this network interface, used to distinguish it from other network interfaces attached to node Virtual Machine. networks.interfaces.secondary[].networkobject yes e.g. {apiVersion: crd.nsx.vmware.com/v1alpha1, kind: Subnet, name: storage-net}Network is the name of the network resource to which this interface is connected. networks.interfaces.secondary[].routesarray of object e.g. [{to: 10.50.0.0/16, via: 10.250.0.1}]Routes is a list of optional, static routes. nodeobject e.g. {firewall: {inboundRules: [{fromPort: 30000, protocol: TCP}]}, labels: {workload: web}}Node configures Kubernetes node specific settings. Supported scopes: cluster, controlPlane, workers node.firewallobject e.g. {inboundRules: [{fromPort: 30000, protocol: TCP}]}Firewall specifies the firewall configuration that should be created on the node to allow specific kinds of traffic. node.firewall.inboundRulesarray of object yes e.g. [{fromPort: 30000, protocol: TCP}]InboundRules is a list of firewall rules that will be configured on each node to allow or deny specific kinds of traffic. node.firewall.inboundRules[].fromPortinteger e.g. 30000FromPort is the low end (inclusive) of the port range that this rule applies to. node.firewall.inboundRules[].protocolint or string yes e.g. TCPProtocol is the type of traffic that this rule applies to. Allowed protocols include “tcp”, “udp”, “icmp”, or an any valid IANA protocol number. node.firewall.inboundRules[].sourcestring e.g. 10.0.0.0/8Source is the CIDR range of the originating traffic that this rule applies to. If unset, the rule will apply to any source network. node.firewall.inboundRules[].toPortinteger e.g. 32767ToPort is the high end (inclusive) of the port range that this rule applies to. node.labelsobject e.g. {workload: web}Labels is a list of user defined name-value pairs node.taintsarray of object e.g. [{key: dedicated, value: gpu}]Taints specifies the taints the Node API object should be registered with. If this field is unset, i.e. nil, it will be defaulted with a control-plane taint for control-plane nodes. node.taints[].effectstring yes NoSchedule, PreferNoSchedule, NoExecuteEffect of the taint on pods that do not tolerate the taint. Valid effects are NoSchedule, PreferNoSchedule and NoExecute. node.taints[].keystring yes e.g. dedicatedKey is the taint key to be applied to a node. node.taints[].valuestring yes e.g. gpuValue is the taint value corresponding to the taint key. osConfigurationobject e.g. {ntp: {servers: [172.30.0.34]}, ...}OSConfiguration configures the system settings of nodes that are independent of Kubernetes. Supported scopes: cluster, controlPlane, workers osConfiguration.directoryJoinobject e.g. {credentialSecretRef: <Secret with the join account>, domain: example.local}DirectoryJoin configures the node to join a Windows Active Directory. Only supported on Windows at present. osConfiguration.directoryJoin.credentialSecretRefstring yes e.g. <Secret with the join account>CredentialSecretRef is the name of the secret containing Active Directory join credentials. osConfiguration.directoryJoin.domainstring yes e.g. example.localDomain is the FQDN of the Active Directory Kerberos domain to join. osConfiguration.directoryJoin.gmsaControlSecurityGroupDNstring e.g. CN=gmsa-k8s,OU=Groups,DC=example,DC=localGMSAControlSecurityGroupDN is an optional Windows Active Directory security group that has permissions to access the password of the Group Managed Service Accounts. osConfiguration.directoryJoin.organizationalUnitDNstring e.g. OU=K8s,DC=example,DC=localOrganizationalUnitDN is an optional organizational unit where the node will be added to in Active Directory. The value will be validated according to https://tools.ietf.org/html/rfc4514 osConfiguration.fipsobject e.g. {enabled: false}FIPS configures FIPS related settings for the Kubernetes cluster to run in FIPS mode. Supported scopes: cluster osConfiguration.fips.enabledboolean default falseEnable specifies whether FIPS settings are enabled and enforced on the node osConfiguration.grubobject e.g. {password: {secretRef: {name: <Secret>, key: password}, user: root}}GRUB configures GRUB Boot Loader. osConfiguration.grub.passwordobject e.g. {secretRef: {name: <Secret>, key: password}, user: root}Password configures the password protection for GRUB Boot Loader (Only applicable on Linux). osConfiguration.grub.password.enabledboolean default falseEnabled defines if the GRUB Boot Loader must be protected with a password osConfiguration.grub.password.secretRefobject e.g. {name: <Secret>, key: password}SecretRef is the name of the secret containing the password to protect GRUB Key is the data.key field within the secret containing the password value. osConfiguration.grub.password.userstring e.g. rootUser specifies the username to use for GRUB password protection. osConfiguration.ntpobject e.g. {servers: [172.30.0.34]}NTP sets the time servers that will be used by nodes in the cluster. By default, NTP servers are inherited from vCenter. osConfiguration.ntp.serversarray of string yes e.g. [172.30.0.34]NTP sets the time servers that will be used by nodes in this cluster. By default, NTP servers are inherited from vCenter. osConfiguration.securityContextobject e.g. {appArmor: {profiles: [{name: <AppArmor profile>}]}}SecurityContext holds security configurations that will be applied to node. osConfiguration.securityContext.appArmorobject e.g. {profiles: [{name: <AppArmor profile>}]}AppArmor configures the appArmor profiles of the node. Supported scopes: cluster, controlPlane, workers Only supported on Ubuntu and Photon nodes. osConfiguration.securityContext.appArmor.profilesarray of object yes e.g. [{name: <AppArmor profile>}]Profiles is a list of appArmor profiles to be added to the node. osConfiguration.sshdobject e.g. {banner: Authorised use only}SSHD configures the sshd config of the node. osConfiguration.sshd.bannerstring e.g. Authorised use onlyBanner specifies the login message used for sending a legal warning message before authentication osConfiguration.systemProxyobject e.g. {http: http://proxy.example.local:3128, https: http://proxy.example.local:3128}SystemProxy configures parameters that reference a proxy server for outbound cluster connections. osConfiguration.systemProxy.httpstring yes e.g. http://proxy.example.local:3128HTTP is the proxy server to be used for all http connections. This should be a hostname or dotted numerical IP address. osConfiguration.systemProxy.httpsstring yes e.g. http://proxy.example.local:3128HTTPS configures the proxy server to be used for all https connections. This should be a hostname or dotted numerical IP address. osConfiguration.systemProxy.noProxyarray of string yes e.g. [.example.local, 10.0.0.0/8]NoProxy configures the list of hostnames and CIDR ranges that should be reached without the configured proxy servers. osConfiguration.trustobject e.g. {additionalTrustedCAs: [{caCert: {secretRef: {name: corp-ca}}}]}Trust configures system-wide certificate trust for nodes osConfiguration.trust.additionalTrustedCAsarray of object yes e.g. [{caCert: {secretRef: {name: corp-ca}}}]AdditionalTrustedCAs is a list of additional CAs to be added to the system trust store of nodes. osConfiguration.trust.additionalTrustedCAs[].caCertobject yes e.g. {secretRef: {name: corp-ca, key: ca.crt}}SecretContent configures a reference to or content of secret data. osConfiguration.tunedobject e.g. {active: [<tuned profile>], profiles: {<profile name>: <TunedProfile reference>}}TuneD injects TuneD profiles and activate specified profile on Linux nodes. Only supported on Linux. osConfiguration.tuned.activearray of string yes e.g. [<tuned profile>]Active is a list of tuned profile name will be activated on node. osConfiguration.tuned.profilesobject e.g. {<profile name>: <TunedProfile reference>}Profiles is a map of tuned profiles will be injected on node. Key is the desired tuned profile name, value is the TunedProfile CR reference which contains the profile content. osConfiguration.ubuntuProobject e.g. {services: [usg], settings: [{key: <setting>, value: <value>}]}UbuntuPro configures the Ubuntu Pro subscription of the node. Only supported on Ubuntu. osConfiguration.ubuntuPro.servicesarray of string e.g. [usg]Services specifies the Ubuntu Pro services to be enabled. osConfiguration.ubuntuPro.settingsarray of object e.g. [{key: <setting>, value: <value>}]Settings specifies the Ubuntu Pro client (ubuntu-advantage-tools) settings to be configured. osConfiguration.ubuntuPro.settings[].keystring yes e.g. <setting>osConfiguration.ubuntuPro.settings[].valuestring yes e.g. <value>osConfiguration.ubuntuPro.tokenSecretRefstring yes e.g. <Secret with the Pro token>TokenSecretRef is the name of the secret containing a valid Ubuntu Pro Subscription token. The secret must have a key token with the content of a valid token. osConfiguration.userobject e.g. {passwordSecret: {key: password, name: <Secret>}, ...}User is an administrative user that will be created on all nodes. If not set, this is defaulted to “vmware-system-user”. osConfiguration.user.passwordobject e.g. {renewalDaysBeforeExpiry: 30}Password configures the password policy such as password max age and renewal settings. osConfiguration.user.password.renewalDaysBeforeExpiryinteger e.g. 30RenewalDaysBeforeExpiry configures the days to renew the password before it gets expired. osConfiguration.user.passwordSecretobject e.g. {key: password, name: <Secret>}Key is the data.key field within the secret containing the password value. If not specified, the secret will be automatically generated as -ssh-password. osConfiguration.user.passwordSecret.keystring yes e.g. passwordKey is the data.key field within the secret containing the password value. For Linux, this must be the hashed value that should be inserted into /etc/shadow. osConfiguration.user.passwordSecret.namestring yes e.g. <Secret>Name is the name of the secret containing the password for the administrative account. osConfiguration.user.requirePasswordOnSudoboolean e.g. trueRequirePasswordOnSudo configures whether password re-authentication is required on sudo. osConfiguration.user.sshAuthorizedKeystring e.g. ssh-ed25519 AAAA... ops@adminThe string of the SSH public key that is to be used for the administrative account. The public key must be of any FIPS-140 approved algorithm. osConfiguration.user.userstring yes e.g. vmware-system-userName is the name of the user to be created. By default, this is vmware-system-user. resourceConfigurationobject e.g. {systemReserved: {cpu: 500m, memory: 1Gi}}ResourceConfiguration configures kubelet resource options. Currently, only CPU and memory reservations are supported. resourceConfiguration.systemReservedobject e.g. {cpu: 500m, memory: 1Gi}SystemReserved defines the system reserved CPU and memory reservations. resourceConfiguration.systemReserved.automaticboolean default trueAutomatic controls the automatic calculation of system reserved resources. resourceConfiguration.systemReserved.cpuint or string e.g. 500mCPU describes the number of CPU cores reserved for system processes. resourceConfiguration.systemReserved.memoryint or string e.g. 1GiMemory describes the memory resources reserved for system processes. storageClassstring yes e.g. vsan-default-storage-policyStorageClass sets the StorageClass that will be used to create node root volumes. vmClassstring yes e.g. best-effort-smallVMClass sets the VMClass that will be used to create nodes. Supported scopes: cluster, controlPlane, workers volumesarray of object e.g. [{name: containerd, capacity: 50Gi}]Volumes configures additional disks to be attached to node virtual machines. Supported scopes: cluster, controlPlane, workers volumes[].capacitystring yes e.g. 50GiCapacity defines the storage capacity of the volume. volumes[].mountPathstring yes e.g. /var/lib/containerdMountPath defines the mount path for the volume. volumes[].namestring yes e.g. containerdName defines the name of the volume. volumes[].storageClassstring e.g. vsan-default-storage-policyStorageClass defines the Storage class to use for the volume. vsphereOptionsobject e.g. {persistentVolumes: {availableStorageClasses: [vsan-default-storage-policy], ...}}VSphereOptions configures vSphere specific options related to nodes Supported scopes: cluster, controlPlane, workers vsphereOptions.persistentVolumesobject e.g. {availableStorageClasses: [vsan-default-storage-policy], ...}PersistentVolumes configures what is available for PVCs to be used in the cluster. vsphereOptions.persistentVolumes.availableStorageClassesarray of string e.g. [vsan-default-storage-policy]AvailableStorageClasses lists the storage classes that can be used in the cluster. vsphereOptions.persistentVolumes.availableVolumeSnapshotClassesarray of string e.g. [volumesnapshotclass-delete]AvailableVolumeSnapshotClasses lists the volume snapshot classes that can be used in the cluster. vsphereOptions.persistentVolumes.customizableStorageClassAnnotationsarray of string e.g. [<annotation>]CustomizableStorageClassAnnotations is a list of annotation keys set on the storage classes within the cluster which can be customized by the user. vsphereOptions.persistentVolumes.customizableStorageClassLabelsarray of string e.g. [<label>]CustomizableStorageClassLabels is a list of label keys set on the storage classes within the cluster which can be customized by the user. vsphereOptions.persistentVolumes.defaultStorageClassstring e.g. vsan-default-storage-policyDefaultStorageClass sets the default storage class inside the cluster. vsphereOptions.persistentVolumes.defaultVolumeSnapshotClassstring e.g. volumesnapshotclass-deleteDefaultVolumeSnapshotClass sets the default volume snapshot class inside the cluster.
Recipe, one control plane node and one worker, as we deployed it (ready in four minutes):
k8s:
type: CCI.Supervisor.Resource
properties:
context: ${resource.namespace.id}
manifest:
apiVersion: cluster.x-k8s.io/v1beta1
kind: Cluster
metadata: {name: dev-01}
spec:
clusterNetwork:
pods: {cidrBlocks: [192.168.156.0/20]}
services: {cidrBlocks: [10.96.0.0/12]}
serviceDomain: cluster.local
topology:
class: builtin-generic-v3.6.0
classNamespace: vmware-system-vks-public
version: v1.35.5+vmware.1-vkr.1
controlPlane:
replicas: 1
workers:
machineDeployments:
- class: node-pool
name: np-1
replicas: 1
variables:
- name: vmClass
value: best-effort-small
- name: storageClass
value: vsan-default-storage-policy
- name: osConfiguration
value:
ntp:
servers: [172.30.0.34]
wait:
conditions:
- type: Ready
status: "True"
The same cluster in v1beta2, the version the Supervisor recommends; the
class becomes a reference with its namespace:
apiVersion: cluster.x-k8s.io/v1beta2
kind: Cluster
metadata: {name: dev-01}
spec:
clusterNetwork:
pods: {cidrBlocks: [192.168.156.0/20]}
services: {cidrBlocks: [10.96.0.0/12]}
serviceDomain: cluster.local
topology:
classRef:
name: builtin-generic-v3.6.0
namespace: vmware-system-vks-public
version: v1.35.5+vmware.1-vkr.1
controlPlane: {replicas: 1}
workers:
machineDeployments:
- {class: node-pool, name: np-1, replicas: 1}
variables:
- {name: vmClass, value: best-effort-small}
- {name: storageClass, value: vsan-default-storage-policy}
Status worth reading: status.phase, status.conditions; the kubeconfig
is in the namespace as the Secret <cluster>-kubeconfig (ours:
dev-01-kubeconfig).
Gotchas
- Every namespace gets copies of a few ClusterClasses, on f06
builtin-generic-v3.1.0tov3.3.0; Broadcom’s ClusterClass matrix marksv3.3.0deprecated for VKS 3.6 and 3.7, and Broadcom’s own 9.1 sample still uses it. The newer classes live only invmware-system-vks-public: name that namespace (classNamespace, orclassRef.namespaceinv1beta2) to use them. - The palette’s
v1beta1works, with a deprecation warning. - Nodes run Photon OS unless the cluster carries the annotation
run.tanzu.vmware.com/resolve-os-image: os-name=ubuntu. topology.versionmust be a release the Supervisor lists as ready and compatible; on f06 those werev1.32.xtov1.35.5.- VKS needs the VPC’s load balancer for the cluster’s API endpoint, so the namespace must use a VPC that has one.
Util.PasswordEntry
type: Util.PasswordEntry. Not in the palette, but one of the five types: it
generates a password, or takes one you give it, and hashes it at request
time.
| Property | Notes |
|---|---|
length | Generate a password of this length. Default 14. |
password | A password to use instead, when length is not set. |
generatedPassword | Computed: the generated password. |
sha512crypt | Computed: the password’s SHA-512 crypt hash ($6$...). |
Every field the platform accepts (3)
Field Type Req. Values Description countinteger default 1The number of resource instances to be created. lengthinteger default 14Length of the password to be auto generated passwordstring e.g. ${input.adminPassword}Password value received as an input when length is not specified
pw:
type: Util.PasswordEntry
properties:
length: 20
VCF Automation stores both computed values as encrypted secrets
(((secret:v1:...))), so the deployment doesn’t show them. Where the hash is
used decides how to write it:
In a raw cloud-config held in a Secret, it is a string:
hashed_passwd: ${resource.pw.sha512crypt}.In a VM’s inline
cloudConfigit must be a Secret reference, so put it in a Secret first:webPw: type: CCI.Supervisor.Resource properties: context: ${resource.ns.id} manifest: apiVersion: v1 kind: Secret metadata: {name: web-pw} type: Opaque stringData: ops-passwd: ${resource.pw.sha512crypt}
Complete, tested blueprints
The five blueprints we deployed to test this guide, as they ran:
| File | What it builds | Result |
|---|---|---|
test1-vpc.yaml | A VPC, its attachment, an external IP allocation, a group, a gateway firewall policy referencing the group, a namespace in the new VPC, a generated password, two counted Secrets holding its hash | Created in 2 min 15 s; every VPC object Realized |
test1b-nat.yaml | A DNAT rule on that VPC | Created; NSX realized it without the port |
test3-workload.yaml | In an existing VPC with a load balancer: a namespace, a subnet, a PVC, a VM group with a boot order, two Ubuntu VMs (cloud-init user with key and hashed password, data disk, subnet, anti-affinity), a LoadBalancer service | Created in 2 min; SSH through the load balancer as the cloud-init user |
test4-vks.yaml | A VKS cluster, one control plane node and one worker, builtin-generic-v3.6.0 | Ready in 4 min |
test5-ipwait.yaml | One VM whose output is its IP | Output 172.30.0.2 |
Downloads
vcfa-91-blueprint-reference.zip: the five test blueprints; the five base types as VCF Automation’s API returns them; the fifteen palette schemas from the designer and the palette map; and the field tables of this guide as Markdown.
Why this matters outside the lab
Self-service on VCF Automation All Apps is only as good as its blueprints. And a blueprint is only as good as its author’s knowledge of the fields, which are mostly documented somewhere else, or nowhere.
The cost of not knowing shows up late. The designer saves the blueprint, the validator passes it, and the request fails ten minutes in. Or worse, it succeeds, with a NAT rule that forwards every port or a firewall rule that allows any service.
Knowing what the platform actually enforces turns that into a five-second dry run. It also turns a catalog item from a demo into something a team can depend on.
Rules learned
- The palette is five resource types. Learn
CCI.Supervisor.ResourceandCCI.VPC.Configurationand you can write every item by hand, including kinds the palette doesn’t show. - VCF Automation’s validation checks a resource’s own properties, never the manifest or the VPC spec inside. Dry-run manifests against the Supervisor; test VPC objects by deploying them.
- Where the designer’s form and the platform disagree, the platform wins:
accessModes,labelSelector, VM affinity terms endingPreferredDuringExecution. - Outputs are computed once. Wait for what they read: a VM’s address needs
the condition
VirtualMachineGuestNetworkConfigSynced. - A blueprint VPC has no load balancer and can’t get one, so LoadBalancer services and VKS need a VPC made in the UI.
- Name firewall services (
":HTTPS") instead of port sets, give every rule afrom, and treat a NAT rule as mapping the whole address. - Inline cloud-init passwords are Secret references;
count.indexneedsallocatePerInstance: true.
Broadcom documentation
- Managing Blueprints in VCF Automation: blueprints, the designer, inputs, versions, property groups and custom forms.
- Sample Blueprints in VCF Automation: Broadcom’s samples: VMs,
countwithallocatePerInstance, a VM with a VKS cluster, a VPC with a namespace, a VM group with affinity. - Specifying formatVersion in Blueprints: what
formatVersion: 2adds, including outputs and__deploymentOverview. - Creating bindings and dependencies between resources:
dependsOnand property bindings, and how each orders the build. - Input Property Groups and Constant Property Groups:
${input.<group>.<property>}and${propgroup.<group>.<property>}. - Managing Secrets in VCF Automation:
${secret.<name>}, organization and project secrets. - VCF Automation blueprint designs that prepare for day 2 changes: re-applying a blueprint versus day-2 actions, and bindings in day 2.
- Create a Namespace Class in VCF Automation: what a namespace class sets, and so what a blueprint namespace must add.
- Create a Virtual Private Cloud in VCF Automation: a VPC’s connectivity profile, private CIDRs and load balancing, and that VKS needs load balancing.
- Create a NAT Rule for a VPC in VCF Automation: the NAT actions, external addresses and priorities behind
VPCNATRule. - Secure North-South boundaries for Transit Gateways and VPCs (vDefend 9.1): VPC gateway firewall policies, rules realized on the edges, and the activation flag in the security profile.
- Deploying and Managing Virtual Machines in vSphere Supervisor: VM classes, images, storage classes and zones, with a pointer to the VM Operator API.
- Using the Versioned ClusterClass: the ClusterClass matrix per VKS release and
vmware-system-vks-public. - v1beta1/v1beta2 Example: Default Cluster: the minimum cluster and the CIDR rules.
- ClusterClass Variable Reference: every variable of the builtin-generic classes, and where each can be overridden.
- VM Status Information Missing in VCF Automation 9.0.x Deployments (KB 435137): where the designer’s default VM
waitcomes from.
The VM Operator API itself is documented upstream, outside Broadcom, and Broadcom’s VM Service pages link there: v1alpha5 reference.
Lab environment; opinions my own. Every snippet was validated, dry-run or deployed on a live VCF 9.1 environment; the field tables come from the platform’s own schemas.