Skip to main content

Bootstrap Config Reference

Field reference for butleradm bootstrap configuration files.

The config is a plain YAML file passed to butleradm bootstrap <provider> --config <path>. The CLI parses it into Go structs defined in butler-cli/internal/adm/bootstrap/orchestrator/config.go.


Top-Level Fields

FieldTypeRequiredDefaultDescription
providerstringYes--Infrastructure provider: harvester, nutanix, proxmox, aws, gcp, azure
clusterobjectYes--Cluster specification
networkobjectNoSee defaultsNetwork configuration
talosobjectNoSee defaultsTalos Linux configuration
addonsobjectNoSee defaultsAddon configuration
controlPlaneExposureobjectNoLoadBalancerHow tenant control planes are exposed (LoadBalancer, Ingress, or Gateway)
providerConfigobjectYes--Provider-specific settings (must match provider field)

cluster

FieldTypeRequiredDefaultDescription
cluster.namestringYes--Cluster name. Used for VM names, kubeconfig context, and resource naming.
cluster.topologystringNohaCluster topology: single-node or ha. Single-node forces controlPlane.replicas=1 and skips worker nodes.
cluster.controlPlaneobjectYes--Control plane node pool
cluster.workersobjectNo--Worker node pool. Ignored when topology is single-node.

Node Pool (controlPlane / workers)

FieldTypeRequiredDefaultDescription
replicasintYes--Number of nodes. Control plane must be 1 (single-node) or 3 (HA).
cpuintYes--vCPUs per node
memoryMBintYes--Memory per node in megabytes (e.g., 8192 = 8 GB)
diskGBintYes--Boot disk size in gigabytes
extraDisksarrayNo--Additional disks (for Longhorn storage)
extraDisks[].sizeGBintYes--Disk size in gigabytes
extraDisks[].storageClassstringNo--Optional storage class

network

FieldTypeRequiredDefaultDescription
network.podCIDRstringNo10.244.0.0/16Pod network CIDR
network.serviceCIDRstringNo10.96.0.0/12Service network CIDR
network.vipstringOn-prem only--Control plane VIP address. Used by kube-vip. Not applicable for cloud providers.
network.loadBalancerPoolobjectOn-prem only--MetalLB IP address range. Not applicable for cloud providers.
network.loadBalancerPool.startstringYes (if pool set)--First IP in the pool (inclusive)
network.loadBalancerPool.endstringYes (if pool set)--Last IP in the pool (inclusive)

On-Prem vs Cloud

  • On-prem (Harvester, Nutanix, Proxmox): Set vip and loadBalancerPool. kube-vip provides control plane HA, MetalLB provides LoadBalancer services.
  • Cloud (AWS, GCP, Azure): Do not set vip or loadBalancerPool. The provider creates a cloud load balancer for control plane HA. The CCM handles LoadBalancer services natively.

talos

FieldTypeRequiredDefaultDescription
talos.versionstringNov1.12.1Talos Linux version
talos.schematicstringNo--Talos Image Factory schematic ID. Determines which extensions are included in the image (e.g., iscsi-tools, qemu-guest-agent).

addons

FieldTypeRequiredDefaultDescription
addons.cni.typestringNociliumCNI plugin type
addons.storage.typestringNolonghornStorage provider type
addons.loadBalancer.typestringNometallbLoad balancer type (on-prem only)
addons.loadBalancer.addressPoolstringNo--Deprecated. Use network.loadBalancerPool instead. Legacy IP range string (e.g., 10.40.0.200-10.40.0.250).
addons.gitOps.typestringNo--GitOps controller type (e.g., flux). Not installed during bootstrap by default.
addons.capi.enabledboolNofalseInstall Cluster API
addons.capi.versionstringNo--CAPI version
addons.butlerController.enabledboolNofalseInstall Butler controller
addons.butlerController.versionstringNo--Butler controller version
addons.butlerController.imagestringNo--Butler controller container image
addons.console.enabledboolNofalseInstall Butler Console
addons.console.versionstringNolatestConsole chart/image version
addons.console.ingress.enabledboolNofalseCreate Ingress for console (on-prem)
addons.console.ingress.hoststringNobutler.<cluster>.localIngress hostname
addons.console.ingress.classNamestringNo--Ingress class (e.g., traefik)
addons.console.ingress.tlsboolNofalseEnable TLS on ingress
addons.console.ingress.tlsSecretNamestringNo--TLS secret name (auto-generated if TLS enabled)
addons.console.auth.adminPasswordstringNoadminInitial admin password
addons.console.auth.jwtSecretstringNo(random)JWT signing secret

controlPlaneExposure

Configures how tenant control planes are exposed after bootstrap. This is a platform-level setting written to ButlerConfig during addon installation (step 11.5). If omitted, defaults to LoadBalancer mode.

FieldTypeRequiredDefaultDescription
controlPlaneExposure.modestringNoLoadBalancerExposure mode: LoadBalancer, Ingress, or Gateway
controlPlaneExposure.hostnamestringIngress/Gateway--Wildcard domain for tenant API servers (e.g., *.k8s.platform.example.com)
controlPlaneExposure.ingressClassNamestringNo--Ingress class when mode is Ingress (e.g., haproxy, nginx)
controlPlaneExposure.controllerTypestringNo--Ingress controller type for TLS passthrough: haproxy, nginx, traefik, generic
controlPlaneExposure.gatewayRefstringGateway--Gateway resource reference when mode is Gateway (format: namespace/name)

Exposure Modes

LoadBalancer (default): Each tenant API server gets a dedicated LoadBalancer IP. Direct TCP access on port 6443. No SNI routing. Requires 1 IP per tenant from MetalLB (on-prem) or cloud LB. tcp-proxy is not required.

Ingress: Multiple tenants share a single IP via an Ingress controller with TLS passthrough. SNI-based routing using {cluster}.{namespace}.{hostname} hostnames. Requires an Ingress controller that supports TLS passthrough (HAProxy, NGINX, or Traefik). tcp-proxy is auto-enabled to rewrite in-cluster kubernetes.default.svc endpoints.

Gateway: Multiple tenants share a single IP via Gateway API TLSRoute. SNI-based routing like Ingress mode, but uses the Gateway API instead of Ingress resources. Requires a Gateway controller that supports TLSRoute. tcp-proxy is auto-enabled.

Examples

LoadBalancer mode (default, can be omitted entirely):

controlPlaneExposure:
mode: LoadBalancer

Ingress mode with HAProxy:

controlPlaneExposure:
mode: Ingress
hostname: "*.k8s.butlerlabs.dev"
ingressClassName: haproxy
controllerType: haproxy

Gateway mode:

controlPlaneExposure:
mode: Gateway
hostname: "*.k8s.butlerlabs.dev"
gatewayRef: "butler-system/tenant-gateway"

providerConfig

Only one provider block should be set, matching the top-level provider field.

providerConfig.harvester

FieldTypeRequiredDescription
kubeconfigPathstringYesPath to the Harvester kubeconfig file. Supports ~ expansion.
namespacestringYesHarvester namespace for VMs (e.g., default)
networkNamestringYesVM network in namespace/name format (e.g., default/vlan40-workloads)
imageNamestringYesTalos image in namespace/name format (e.g., default/talos-v1-12-1)

providerConfig.nutanix

FieldTypeRequiredDefaultDescription
endpointstringYes--Prism Central URL (e.g., https://prism.example.com)
portintNo9440Prism Central API port
insecureboolNofalseAllow insecure TLS (self-signed certs)
usernamestringYes--Prism Central username
passwordstringYes--Prism Central password
clusterUUIDstringYes--Target Nutanix cluster UUID
subnetUUIDstringYes--VM network subnet UUID
imageUUIDstringYes--Talos image UUID in Prism Central
storageContainerUUIDstringNo--Storage container for VM disks
hostAliasesarrayNo--/etc/hosts entries for the KIND node (e.g., ["10.0.0.1 prism.internal"]). Useful for corporate DNS/Zscaler.

providerConfig.proxmox

FieldTypeRequiredDefaultDescription
endpointstringYes--Proxmox API URL
insecureboolNofalseAllow insecure TLS
usernamestringYes--Proxmox username
passwordstringYes--Proxmox password
nodesarrayYes--List of Proxmox node names for VM placement
storagestringYes--Storage location for VM disks
templateIDintNo--VM template ID to clone
vmidStartintNo--Start of VM ID range
vmidEndintNo--End of VM ID range
hostAliasesarrayNo--/etc/hosts entries for KIND node

providerConfig.aws

FieldTypeRequiredDefaultDescription
accessKeyIDstringYes--IAM access key ID
secretAccessKeystringYes--IAM secret access key
regionstringYes--AWS region (e.g., us-east-1)
vpcIDstringNo--VPC ID
subnetIDstringNo--Subnet ID for VM placement
securityGroupIDstringNo--Security group ID
instanceTypestringNom5.xlargeEC2 instance type
amistringNo(per-region default)Custom AMI ID. If not set, uses built-in Talos AMI for the region.

providerConfig.gcp

FieldTypeRequiredDefaultDescription
serviceAccountKeyPathstringYes--Path to GCP service account key JSON file. Supports ~ expansion.
projectIDstringYes--GCP project ID
regionstringYes--GCP region (e.g., us-central1)
zonestringNo{region}-aGCP zone
networkstringYes--VPC network name
subnetworkstringNo--Subnet name
machineTypestringNo--GCE machine type (e.g., n2-standard-4)
imageProjectstringNo--GCP project containing the Talos image
imageFamilystringNo--Image family (e.g., talos-v1-12). Used if image is not set.
imagestringNo--Specific GCE image name. Takes precedence over imageFamily.

providerConfig.azure

FieldTypeRequiredDefaultDescription
clientIDstringYes--Service principal app ID
clientSecretstringYes--Service principal password
tenantIDstringYes--Azure AD tenant ID
subscriptionIDstringYes--Azure subscription ID
resourceGroupstringYes--Pre-existing resource group name
locationstringYes--Azure region (e.g., eastus)
vnetNamestringNo--Pre-existing VNet name
subnetNamestringNo--Subnet within the VNet
securityGroupNamestringNo--Pre-existing NSG name. Required for CCM to create LB NSG rules.
vmSizestringNo--Azure VM size (e.g., Standard_D4s_v3)
imageURNstringNo--Full ARM resource ID for the Talos image (managed image or gallery image version)

Defaults

When a field is omitted, these defaults are applied:

FieldDefault Value
cluster.topologyha
network.podCIDR10.244.0.0/16
network.serviceCIDR10.96.0.0/12
talos.versionv1.12.1
addons.cni.typecilium
addons.storage.typelonghorn
addons.loadBalancer.typemetallb
providerConfig.nutanix.port9440
providerConfig.gcp.zone{region}-a