Last modified September 4, 2025

'kubectl gs template cluster' command reference

This command helps with creating a Cluster API (CAPI) cluster by producing a manifest based on user input. This manifest can then optionally be modified and finally be applied to the platform API to create a cluster.

The generated manifest includes:

  • App - describes the Giant Swarm App which defines the helm release which in turn creates the actual cluster resources. The resource name is identical with the cluster name.
  • ConfigMap - describes the configuration for the above cluster chart. Please see Creating a workload cluster for which cluster chart is used, depending on the cloud provider. The resource name is the cluster name plus the -userconfig suffix.

Syntax and flags

The command to execute is kubectl gs template cluster.

It supports the following flags:

  • --provider - The infrastructure provider (one of: aws, azure, capa, vsphere).

  • --name - Unique name of the cluster. If not provided, a random alphanumeric name will be generated.

  • --organization - Name of the organization that will own the cluster. Determines the namespace where resources will be created. Can be retrieved with kubectl get releases for your installation.

  • --description (optional) - User-friendly description of the cluster’s purpose.

  • --control-plane-az (optional) - Availability zone(s) of the control plane instance(s).

  • --output (optional) - The name of the file to write the output to instead of stdout.

  • --oidc-issuer-url (optional - CAPI) - This is the issuer URL for configuring OpenID connect in the cluster API.

  • --oidc-ca-file (optional - CAPI) - This is the CA file path in case is not used a trusted Certificate Authority for OIDC endpoint.

  • --oidc-client-id (optional - CAPI) - This is the client ID that is configured in the OIDC endpoint.

  • --oidc-username-claim (optional - CAPI) - This is the claim used to map the username identity of the user.

  • --oidc-groups-claim (optional - CAPI) - This is the claim used to map the group identity of the user.

    TODO: move the following content to the flag it belongs to.

    On AWS, it must be configured with AZ of the installation region. E.g. for region eu-central-1, a valid value is eu-central-1a.

    On Azure, it can be any of the 3 zones: 1, 2, 3.

    Use the flag once with a single value to create a cluster with one control plane node (on both Azure and AWS). For high-availability control planes, specify three distinct availability zones instead (AWS only). This can be done by separating AZ names with comma or using the flag three times with a single AZ name.

Flags specific to AWS

  • --aws-cluster-role-identity-name (optional) - Refers to the IAM role used to create all AWS cloud resources when creating the cluster. The role can be in another AWS account in order to create all resources in that account (default: default).
  • --az-usage-limit (optional) - Maximum number of availability zones (AZ) that should be used in a region. If a region has more than this number of AZs then this number of AZs will be picked randomly when creating subnets (default: 3).
  • --bastion-instance-type (optional) - Instance type used for the bastion machine (default: t3.small).
  • --bastion-replicas (optional) - Number of bastion instances to run.
  • --control-plane-instance-type (optional) - Instance type used for Control plane nodes (default: r6i.xlarge).
  • --cluster-catalog (optional) - Name of the Giant Swarm app catalog that holds the cluster’s app release.
  • --cluster-version (optional) - Version of cluster-vsphere helm chart to use. If not provided, the latest version will be used.
  • --default-apps-catalog (optional) - Name of the Giant Swarm app catalog that holds the default-apps’ app release.
  • --default-apps-version (optional) - Version of default-apps-vsphere helm chart to use. If not provided, the latest version will be used.
  • --machine-pool-azs (optional) - Availability zones for the machine pool.
  • --machine-pool-custom-node-labels (optional) - Labels to add to the nodes in the machine pool.
  • --machine-pool-instance-type (optional) - Instance type to use for the machine pool.
  • --machine-pool-max-size (optional) - Maximum size of the machine pool.
  • --machine-pool-min-size (optional) - Minimum size of the machine pool.
  • --machine-pool-name (optional) - Name of the machine pool.
  • --machine-pool-root-volume-size-gb (optional) - Size in GB of the root volume of the machines in the machine pool.
  • --name - must only contain alphanumeric characters, start with a letter, and be no longer than 20 characters in length.
  • --region - AWS region where cluster will be created.
  • --vpc-cidr (optional) - IPv4 address range to assign to this cluster’s VPC, in CIDR notation.

Flags specific to Azure

  • --azure-subscription-id - Azure subscription ID to use.
  • --bastion-instance-type (optional) - Instance type used for the bastion machine (default: Standard_D2s_v5).
  • --cluster-catalog (optional) - Name of the Giant Swarm app catalog that holds the cluster’s app release.
  • --cluster-version (optional) - Version of cluster-vsphere helm chart to use. If not provided, the latest version will be used.
  • --control-plane-instance-type (optional) - Instance type used for Control plane nodes (default: Standard_D4s_v3).
  • --default-apps-catalog (optional) - Name of the Giant Swarm app catalog that holds the default-apps’ app release.
  • --default-apps-version (optional) - Version of default-apps-vsphere helm chart to use. If not provided, the latest version will be used.
  • --name - must only contain alphanumeric characters, start with a letter, and be no longer than 20 characters in length.
  • --region - Azure region where cluster will be created.

Note: The zones where the worker and control-plane nodes are deployed must be in the same region specified in the --region flag.

Flags specific to vSphere

  • --cluster-catalog (optional) - Name of the Giant Swarm app catalog that holds the cluster’s app release.
  • --cluster-version (optional) - Version of cluster-vsphere helm chart to use. If not provided, the latest version will be used.
  • --default-apps-catalog (optional) - Name of the Giant Swarm app catalog that holds the default-apps’ app release.
  • --default-apps-version (optional) - Version of default-apps-vsphere helm chart to use. If not provided, the latest version will be used.
  • --kubernetes-version (optional) - Cluster’s Kubernetes version (default: 1.24.11).
  • --vsphere-control-plane-disk-gib (optional) - Disk size in GiB for individual control plane nodes (default: 50).
  • --vsphere-control-plane-ip (optional) - Control plane IP, leave empty for auto allocation.
  • --vsphere-control-plane-ip-pool (optional) - Name of GlobalInClusterIpPool CR from which to take an IP for the control plane (default: wc-cp-ips).
  • --vsphere-control-plane-memory-mib (optional) - Memory size in MiB for individual control plane nodes (default: 8096).
  • --vsphere-control-plane-num-cpus (optional) - Number of CPUs for individual control plane nodes (default: 4).
  • --vsphere-control-plane-replicas (optional) - Number of control plane replicas in odd number (default: 3).
  • --vsphere-credentials-secret-name (optional) - Name of the kubernetes secret that should be associated to the cluster app. It should exist in the organization’s namespace and should contain the credentials for vsphere.
  • --vsphere-image-template (optional) - Name of the vSphere template to deploy the VMs from (default: ubuntu-2004-kube-${kubernetes-version}).
  • --vsphere-network-name - Portgroup name in vCenter to connect the new VMs to.
  • --vsphere-resource-pool (optional) - Name of the vSphere resource pool to deploy the VMs to (default: cluster)
  • --vsphere-service-lb-pool (optional) - Name of GlobalInClusterIpPool CR from which the IP for Service LB (kubevip) is taken (default “svc-lb-ips”)
  • --vsphere-service-load-balancer-cidr (optional) - CIDR for Service LB within workload cluster.
  • --vsphere-worker-disk-gib (optional) - Disk size in GiB for individual worker nodes (default: 50).
  • --vsphere-worker-memory-mib (optional) - Memory size in MiB for individual worker nodes (default: 14144).
  • --vsphere-worker-num-cpus (optional) - Number of CPUs for individual worker nodes (default: 6).
  • --vsphere-worker-replicas (optional) - Number of worker replicas (default: 3).

Examples

Example command for an AWS CAPI cluster:

kubectl gs template cluster \
  --provider capa \
  --release 31.1.1 \
  --control-plane-az eu-central-1a \
  --description "Development Cluster" \
  --name dev01 \
  --organization acme

Example command for an Azure CAPI cluster:

kubectl gs template cluster \
  --provider capz \
  --region germanywestcentral \
  --azure-subscription-id xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx \
  --description "Development Cluster" \
  --name dev01 \
  --organization acme
kubectl gs template cluster \
  --provider vsphere \
  --name demo1 \
  --organization multi-project \
  --vsphere-service-load-balancer-cidr 10.10.222.238/30 \
  --vsphere-network-name demo1 \
  --vsphere-worker-memory-mib 4096 \
  --vsphere-worker-num-cpus 4 \
  --vsphere-worker-replicas 3 \
  --vsphere-control-plane-num-cpus 8 \
  --vsphere-control-plane-memory-mib 12000 \

Output

The above example command would generate the following output:

---
apiVersion: v1
data:
  values: |
    global:
      connectivity:
        availabilityZoneUsageLimit: 3
        network: {}
        topology: {}
      controlPlane: {}
      metadata:
        description: Development Cluster
        name: dev01
        organization: acme
        preventDeletion: false
      nodePools:
        nodepool0:
          availabilityZones:
          - eu-central-1a
          instanceType: m5.xlarge
          maxSize: 10
          minSize: 3
          rootVolumeSizeGB: 8
      providerSpecific: {}
      release:
        version: 31.1.1    
kind: ConfigMap
metadata:
  creationTimestamp: null
  labels:
    giantswarm.io/cluster: dev01
  name: dev01-userconfig
  namespace: org-acme
---
apiVersion: application.giantswarm.io/v1alpha1
kind: App
metadata:
  labels:
    app-operator.giantswarm.io/version: 0.0.0
  name: dev01
  namespace: org-acme
spec:
  catalog: cluster
  config:
    configMap:
      name: ""
      namespace: ""
    secret:
      name: ""
      namespace: ""
  kubeConfig:
    context:
      name: ""
    inCluster: true
    secret:
      name: ""
      namespace: ""
  name: cluster-aws
  namespace: org-acme
  userConfig:
    configMap:
      name: dev01-userconfig
      namespace: org-acme
  version: ""
---
apiVersion: v1
data:
  values: |
    connectivity:
      bastion:
        enabled: true
    controlPlane:
      replicas: 3
    metadata:
      description: Development Cluster
      name: dev01
      organization: acme
    providerSpecific:
      location: germanywestcentral
      subscriptionId: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx    
kind: ConfigMap
metadata:
  labels:
    giantswarm.io/cluster: dev01
  name: dev01-userconfig
  namespace: org-acme
---
apiVersion: application.giantswarm.io/v1alpha1
kind: App
metadata:
  labels:
    app-operator.giantswarm.io/version: 0.0.0
  name: dev01
  namespace: org-acme
spec:
  catalog: cluster
  config:
    configMap:
      name: ""
      namespace: ""
    secret:
      name: ""
      namespace: ""
  kubeConfig:
    context:
      name: ""
    inCluster: true
    secret:
      name: ""
      namespace: ""
  name: cluster-azure
  namespace: org-acme
  userConfig:
    configMap:
      name: dev01-userconfig
      namespace: org-acme
  version: 0.0.29
---
apiVersion: v1
data:
  values: |
    clusterName: dev01
    organization: acme    
kind: ConfigMap
metadata:
  labels:
    giantswarm.io/cluster: dev01
  name: dev01-default-apps-userconfig
  namespace: org-acme
---
apiVersion: application.giantswarm.io/v1alpha1
kind: App
metadata:
  labels:
    app-operator.giantswarm.io/version: 0.0.0
    giantswarm.io/cluster: dev01
    giantswarm.io/managed-by: cluster
  name: dev01-default-apps
  namespace: org-acme
spec:
  catalog: cluster
  config:
    configMap:
      name: dev01-cluster-values
      namespace: org-acme
  kubeConfig:
    inCluster: true
  name: default-apps-azure
  namespace: org-acme
  userConfig:
    configMap:
      name: dev01-default-apps-userconfig
      namespace: org-acme
  version: 0.4.0
---
apiVersion: v1
data:
  values: |
    global:
      connectivity:
        baseDomain: test.gigantic.io
        network:
          controlPlaneEndpoint:
            host: ""
            ipPoolName: wc-cp-ips
            port: 6443
          loadBalancers:
            cidrBlocks:
            - 10.10.222.238/30
            ipPoolName: svc-lb-ips
      controlPlane:
        image:
          repository: gsoci.azurecr.io/giantswarm
        machineTemplate:
          cloneMode: linkedClone
          diskGiB: 50
          memoryMiB: 12000
          network:
            devices:
            - dhcp4: true
              networkName: demo1
          numCPUs: 8
          resourcePool: '*/Resources'
          template: flatcar-stable-3602.2.1-kube-v1.24.12-gs
        replicas: 3
      metadata:
        organization: multi-project
      nodeClasses:
        default:
          cloneMode: linkedClone
          diskGiB: 50
          memoryMiB: 4096
          network:
            devices:
            - dhcp4: true
              networkName: demo1
          numCPUs: 4
          resourcePool: '*/Resources'
          template: flatcar-stable-3602.2.1-kube-v1.24.12-gs
      nodePools:
        worker:
          class: default
          replicas: 3    
kind: ConfigMap
metadata:
  creationTimestamp: null
  labels:
    giantswarm.io/cluster: demo1
  name: demo1-userconfig
  namespace: org-multi-project
---
apiVersion: application.giantswarm.io/v1alpha1
kind: App
metadata:
  labels:
    app-operator.giantswarm.io/version: 0.0.0
  name: demo1
  namespace: org-multi-project
spec:
  catalog: cluster
  config:
    configMap:
      name: ""
      namespace: ""
    secret:
      name: ""
      namespace: ""
  extraConfigs:
  - kind: secret
    name: container-registries-configuration
    namespace: default
    priority: 25
  kubeConfig:
    context:
      name: ""
    inCluster: true
    secret:
      name: ""
      namespace: ""
  name: cluster-vsphere
  namespace: org-multi-project
  userConfig:
    configMap:
      name: demo1-userconfig
      namespace: org-multi-project
    secret:
      name: vsphere-credentials
      namespace: org-multi-project
  version: 0.53.1
---
apiVersion: v1
data:
  values: |
    clusterName: demo1
    organization: multi-project    
kind: ConfigMap
metadata:
  creationTimestamp: null
  labels:
    giantswarm.io/cluster: demo1
  name: demo1-default-apps-userconfig
  namespace: org-multi-project
---
apiVersion: application.giantswarm.io/v1alpha1
kind: App
metadata:
  labels:
    app-operator.giantswarm.io/version: 0.0.0
    giantswarm.io/cluster: demo1
    giantswarm.io/managed-by: cluster
  name: demo1-default-apps
  namespace: org-multi-project
spec:
  catalog: cluster
  config:
    configMap:
      name: demo1-cluster-values
      namespace: org-multi-project
    secret:
      name: ""
      namespace: ""
  kubeConfig:
    context:
      name: ""
    inCluster: true
    secret:
      name: ""
      namespace: ""
  name: default-apps-vsphere
  namespace: org-multi-project
  userConfig:
    configMap:
      name: demo1-default-apps-userconfig
      namespace: org-multi-project
  version: 0.14.0