Standardizing Multi‑Cloud Cluster Provisioning with Gardener’s ClusterClass and ClusterTemplate
Discover how Gardener’s ClusterClass and ClusterTemplate let you declaratively provision consistent Kubernetes clusters across clouds, with a step‑by‑step guide, YAML examples, and recovery tips.
14 Aug 2025, 10:30 UTC

Problem & Takeaway
When you create a new workload cluster on each cloud provider, you often end up with subtle configuration drift: different node sizes, network CIDRs, or storage classes. Gardener’s ClusterClass and ClusterTemplate resources let you define a single source of truth that every cluster must follow, eliminating manual errors and speeding up onboarding.
Desired Outcome
Provision a new workload cluster on AWS that automatically adopts the same networking, node sizing, and storage settings defined in a shared ClusterClass, using a ClusterTemplate that references that class.
Prerequisites
- Control Plane cluster running Gardener (v1.53 or later). You must have
kubectlconfigured to talk to it. - Cloud provider credentials (AWS access key, secret key, region) stored in a Gardener
Secretnamedaws-credsin the same namespace as the control‑plane. - Basic IAM permissions: ability to create VPCs, subnets, security groups, and EKS clusters.
Focused Procedure
Create a ClusterClass
This defines the desired infrastructure for all clusters that bind to it.
apiVersion: cluster.x-k8s.io/v1beta1 kind: ClusterClass metadata: name: aws-standard spec: controlPlane: machineTemplate: infrastructureRef: apiVersion: infrastructure.gardener.cloud/v1beta1 kind: AWSMachineTemplate name: aws-controlplane-template workers: machineTemplate: infrastructureRef: apiVersion: infrastructure.gardener.cloud/v1beta1 kind: AWSMachineTemplate name: aws-worker-template machineDeployments: - name: md-0 replicas: 3 class: aws-worker-class maxSurge: 1 maxUnavailable: 0Create the referenced MachineTemplates
These are Gardener‑specific CRDs that map to the underlying cloud resources.
apiVersion: infrastructure.gardener.cloud/v1beta1 kind: AWSMachineTemplate metadata: name: aws-controlplane-template spec: providerSpec: valueFrom: secret: name: aws-creds key: value nodeImage: ami-0c55b159cbfafe1f0 instanceType: m5.large sshKey: my-ssh-keyCreate a ClusterTemplate that references the ClusterClass
The template is what end users apply to create clusters.
apiVersion: gardener.cloud/v1beta1 kind: ClusterTemplate metadata: name: aws-standard-template spec: className: aws-standard namespace: gardener-system secretTemplateName: aws-creds region: us-east-1 infrastructure: provider: awsProvision a new cluster
Apply a
ClusterCR that references the template.apiVersion: gardener.cloud/v1beta1 kind: Cluster metadata: name: prod-app-cluster spec: templateName: aws-standard-template namespace: gardener-system secretName: aws-creds region: us-east-1 infrastructure: provider: awsRun:
kubectl apply -f cluster-prod.yaml
Expected Checks
- Cluster status –
kubectl get clusters -o wideshould showReady: Trueonce provisioning finishes. - Control plane node health –
kubectl -n gardener-system get nodes -l control-plane=true -o wideshould list nodes withReadystatus. - Check Gardener logs for reconciliation events:
kubectl logs -n gardener-system -l app=gardener -c gardener-controller-managerand grep forCluster prod-app-cluster.
Recovery & Rollback Options
- If the cluster never reaches
Ready, inspect theClusterstatus conditions:kubectl describe cluster prod-app-cluster. Common causes are missing IAM roles or insufficient VPC quota. - To delete the cluster cleanly, run:
kubectl delete cluster prod-app-cluster. Gardener will tear down the underlying EKS cluster and VPC resources. - To patch the ClusterClass (e.g., change instance type), edit the CRD:
kubectl edit clusterclass aws-standard. Existing clusters will reconcile to the new spec automatically.
Limitations & Practical Checks
- Provisioning is only as good as the underlying provider quotas – ensure you have enough VPC CIDR blocks and instance limits.
- Network peering between the control‑plane VPC and the workload cluster VPC must be configured by Gardener; verify connectivity with
kubectl exec -it ... -- ping -c 3 10.0.0.1from a pod. - Gardener’s reconciliation loop can trigger repeated attempts if the provider rejects a resource; check the event log for
ReconciliationFailedevents.
Conclusion
By centralizing cluster configuration in a ClusterClass and exposing it through a ClusterTemplate, you reduce drift, speed up onboarding, and make self‑healing automatic. The declarative approach also simplifies auditing and compliance, as every cluster is created from the same source of truth.