Skip to content

clusterctl Variables

clusterctl replaces shell-style ${NAME} and ${NAME:=default} references in the CAPTF templates with environment variables. A variable with no default and no value makes clusterctl generate fail, so a missing name never deploys something you did not ask for.

The provider ships three templates:

Template Flavor What it creates
cluster-template.yaml Default (no --flavor) A Cluster, TerraformCluster, control plane, MachineDeployment and MachineHealthChecks
cluster-template-clusterclass.yaml clusterclass A Cluster that references the noop ClusterClass through spec.topology
identity.yaml None. Applied by an admin A TerraformClusterIdentity and its credentials Secret

Both cluster flavors read the same variables, so the first table covers them. The identity template reads two. See Templates and ClusterClass for what each flavor creates and Quick Start for a full walkthrough.

Cluster flavors: default and clusterclass

Both templates read every variable below. Variables marked as set by a clusterctl generate cluster option need no export.

Identity and module images

Variable Required Default Sets
TERRAFORM_IDENTITY_NAME Yes None The TerraformClusterIdentity the cluster uses, and by default its machines. Default flavor: TerraformCluster.spec.identityRef.name and spec.defaults.identityRef.name. clusterclass flavor: the identityName topology variable
TERRAFORM_CLUSTER_IMAGE Yes None The cluster module image: TerraformCluster.spec.source.image, or the clusterImage topology variable
TERRAFORM_MACHINE_IMAGE Yes None The machine module image for control-plane and worker machines: spec.template.spec.source.image of both TerraformMachineTemplates, or the machineImage topology variable

Cluster shape

Variable Required Default Sets
CLUSTER_NAME Yes None The name of every object. Set by the name you pass to clusterctl generate cluster
KUBERNETES_VERSION Yes None The version of the KubeadmControlPlane and MachineDeployment, or of the topology. Set by --kubernetes-version
CONTROL_PLANE_MACHINE_COUNT Yes None Control-plane replicas. Set by --control-plane-machine-count. An odd number of at least 3 keeps a rollout with maxSurge: 0 available
WORKER_MACHINE_COUNT Yes None MachineDeployment replicas. Set by --worker-machine-count
POD_CIDR No 192.168.0.0/16 Cluster.spec.clusterNetwork.pods
SERVICE_CIDR No 10.128.0.0/12 Cluster.spec.clusterNetwork.services

Health check timeouts

Each timeout is in seconds. They tune the two MachineHealthChecks: one for the control plane and one for workers. In the clusterclass flavor they set the same fields on the Cluster topology.

Variable Required Default Sets
TERRAFORM_NODE_STARTUP_TIMEOUT No 1200 Worker nodeStartupTimeoutSeconds
TERRAFORM_UNHEALTHY_TIMEOUT No 1800 Worker: seconds of InfrastructureReady=False before remediation
TERRAFORM_CP_NODE_STARTUP_TIMEOUT No 1800 Control-plane nodeStartupTimeoutSeconds. Longer than the worker value because kubeadm init or join plus kube-vip does more work than a worker join
TERRAFORM_CP_UNHEALTHY_TIMEOUT No 3600 Control-plane unhealthy timeout. Longer because replacing a control-plane machine costs more

The unhealthy timeout must exceed one apply plus one drift interval

The unhealthy window starts when an apply starts, so set TERRAFORM_UNHEALTHY_TIMEOUT above your longest apply time plus one drift interval (30 minutes by default). Below that, Cluster API can replace a machine whose apply is still running.

Identity template

identity.yaml is not a flavor. An admin applies it once per set of credentials, with clusterctl generate yaml:

Variable Required Default Sets
TERRAFORM_IDENTITY_NAME Yes None The name of the TerraformClusterIdentity and of its credentials Secret
NAMESPACE Yes None The namespace allowed to use the identity (spec.allowedNamespaces.list)

The generated Secret holds placeholder keys. Replace them with the environment variables your module’s providers read. See Identities and Credentials.

export TERRAFORM_IDENTITY_NAME=<identity-name> NAMESPACE=<namespace>
clusterctl generate yaml --from templates/identity.yaml | kubectl apply -f -

Replace <identity-name> with the name clusters reference, and <namespace> with the namespace they live in.

Generate a cluster

Export the required variables that no option sets, then generate. This example uses the default flavor and overrides two optional values:

export TERRAFORM_IDENTITY_NAME=<identity-name> \
  TERRAFORM_CLUSTER_IMAGE=<cluster-module-image> \
  TERRAFORM_MACHINE_IMAGE=<machine-module-image> \
  POD_CIDR=<pod-cidr> \
  TERRAFORM_UNHEALTHY_TIMEOUT=<seconds>

clusterctl generate cluster <cluster-name> --infrastructure terraform \
  --target-namespace <namespace> \
  --kubernetes-version <version> \
  --control-plane-machine-count 3 --worker-machine-count 2 \
  | kubectl apply -f -

Placeholders:

  • <identity-name>: an existing TerraformClusterIdentity that allows <namespace>.
  • <cluster-module-image> and <machine-module-image>: the module images, for example a tag you built for the cluster and machine roles.
  • <pod-cidr> and <seconds>: optional. Leave them out to use the defaults in the tables above.
  • <cluster-name>, <namespace> and <version>: the name, the target namespace and the Kubernetes version, such as v1.36.3.

--infrastructure terraform needs the provider registered with clusterctl. To render a template file directly instead, replace it with --from templates/cluster-template.yaml.

To use the clusterclass flavor, apply the class to the namespace once, enable the ClusterTopology feature gate when you register the provider, and add --flavor clusterclass:

kubectl apply -n <namespace> -f templates/clusterclass-noop.yaml
clusterctl generate cluster <cluster-name> --infrastructure terraform \
  --flavor clusterclass --target-namespace <namespace> \
  --kubernetes-version <version> \
  --control-plane-machine-count 3 --worker-machine-count 2 \
  | kubectl apply -f -

clusterclass-noop.yaml has no clusterctl variables and no namespace, so apply it to every namespace that generates clusters from it.

ClusterClass topology variables

The noop ClusterClass declares three topology variables. The clusterclass flavor fills them from the clusterctl variables above, in Cluster.spec.topology.variables. To change one later, edit the value on the Cluster; you do not edit the class or its templates.

Variable Required Type Filled from Description
identityName Yes string TERRAFORM_IDENTITY_NAME Name of the TerraformClusterIdentity the cluster and, by default, its machines use
clusterImage Yes string TERRAFORM_CLUSTER_IMAGE Source image of the cluster module (TerraformCluster.spec.source.image)
machineImage Yes string TERRAFORM_MACHINE_IMAGE Source image of the machine module, for control-plane and worker machines. Changing it rolls the machines out
spec:
  topology:
    classRef:
      name: noop
    variables:
    - name: identityName
      value: <identity-name>
    - name: clusterImage
      value: <cluster-module-image>
    - name: machineImage
      value: <machine-module-image>

A *Template kind is immutable once created, so the topology controller rolls a new machineImage out by creating a new TerraformMachineTemplate. See Template immutability and rolling out a change and The noop ClusterClass.