Skip to main content
Crusoe Support Help Center home page
Crusoe

How-To Export CMK Kubeconfig Using Terraform

Apeksha Khilari
Apeksha Khilari
Updated

Last Updated: Dec 23, 2025

Introduction

The Crusoe Managed Kubernetes (CMK) cluster can be provisioned using Terraform, with the added capability to export the Kubeconfig as a Yaml file. This guide provides step-by-step instructions for setting up a CMK cluster with an Infiniband (IB)-enabled GPU nodepool and exporting the Kubeconfig, all through Terraform. This Kubeconfig file can then be used to access the newly created CMK cluster.

Prerequisites

  • Terraform 
  • Crusoe Quota to spin up desired GPU resources
  • Crusoe authentication credentials

Step-by-Step Instructions

The following example demonstrates how to create a CMK cluster with a H100 GPU nodepool and export it to a file named kubeconfig.yaml in the current directory.

Note: Please run the mentioned comments in code to find out the latest CMK/nodepool version.

  1. Copy the following text in a file named main.tf
     

    
    #############################################
    # Provider config
    #############################################
    
    terraform {
      required_providers {
        crusoe = {
          source = "crusoecloud/crusoe"
        }
      }
    }
    
    ##################################################
    # Local config
    ##################################################
    locals {
      project_id            = "<project-id>"
      my_ssh_public_key     = file("<path to ssh public key>")
      control_plane_version = "1.33.4-cmk.2"
      worker_version        = "1.33.4-cmk.2"
      location              = "<crusoe location>" # See `crusoe locations list` for location options
      add_ons = [
        # "cluster_autoscaler",
        # "nvidia_gpu_operator",
        # "nvidia_network_operator",
        # "crusoe_csi",
      ]
      worker_count    = 1
      worker_type     = "h100-80gb-sxm-ib.8x"  # use any IB supported SKU 
      kubeconfig_path = "./kubeconfig.yaml"
      ib_network_id   = "<IB network id>"
      subnet_id       = "<Subnet id>"
    }
    
    ####################################################
    # CMK Cluster creation
    
    resource "crusoe_kubernetes_cluster" "my_cluster" {
      name       = "my-cluster"
      project_id = local.project_id 
      # Set the desired CMK control plane version
      # See `crusoe kubernetes versions list` for available versions
      version    = local.control_plane_version
      # See `crusoe locations list` for location options
      location   = local.location
    
      # Optional: Set cluster/service CIDRs and node CIDR mask size
      # cluster_cidr = "192.168.1.0/24"
      # node_cidr_mask_size = "27"
      # service_cluster_ip_range = "192.168.2.0/24"
    
      # Optional: Add additional add-ons
      # See `crusoe kubernetes clusters create --help` for available add-ons
      # add_ons = local.add_ons
    
      # Optional: Configure OIDC authentication for Kubernetes
      # Replace with your own identity provider values
      # oidc_issuer_url      = "https://auth.example.com/oauth2/aussah0123456bd97"
      # oidc_client_id       = "0123456789abcdef"
      # oidc_username_claim  = "sub"      # typically "sub" or "email"
      # oidc_groups_claim    = "groups"   # claim used to identify user groups
      # oidc_username_prefix = ""         # prefix prepended to username claim
    }
    
    ######
    # IB Partition creation
    
    resource "crusoe_ib_partition" "my_partition" {
      name          = "my-ib-partition"
      project_id    = local.project_id
    
      # Available IB network IDs can be listed with the CLI by running
      # `crusoe networking ib-network list`
      ib_network_id = local.ib_network_id
    }
    
    ######
    # Nodepool creation
    
    resource "crusoe_kubernetes_node_pool" "my_nodepool" {
      name           = "my-nodepool"
      cluster_id     = crusoe_kubernetes_cluster.my_cluster.id
      instance_count = local.worker_count
    
      # Optional: Set the desired CMK worker node version
      # If not specified, the default is the latest stable version compatible with the cluster
      # List available node pool versions with "crusoe kubernetes versions list"
      version = local.worker_version
      type    = local.worker_type
      # Optional: Add your SSH public key to the created nodes to allow SSH access
      ssh_key = local.my_ssh_public_key
    
      # Optional: Set ib_partition_id when using IB supported GPU types, such as - A100-SXM,H200s,H100s etc. 
      # See `crusoe networking ib-partitions list` for all in partitions created in your projects 
      ib_partition_id = crusoe_ib_partition.my_partition.id
      # See `crusoe networking vpc-subnets list` for all available vpc subnets 
      subnet_id = local.subnet_id
    
      # Optional: Kubernetes Node objects will be labeled with the following key:value pairs
      # requested_node_labels = {
      #   "labelkey" = "labelvalue"
      # }
    
      # Optional: Use local ephemeral NVMe disks for containerd storage
      # ephemeral_storage_for_containerd = true
    
      lifecycle {
        ignore_changes = [
          ssh_key,
        ]
      }
    }
    
    ######
    # Kubeconfig 
    
    resource "crusoe_kubeconfig" "my_cluster_kubeconfig" {
      cluster_id = crusoe_kubernetes_cluster.my_cluster.id
      # Optional: Specify authentication type for kubeconfig.
      # Supported values: "admin_cert" (default), "oidc"
      # auth_type  = "oidc"
    }
    
    # Optional: Output the kubeconfig YAML to a file
    resource "local_file" "kubeconfig_file" {
      content  = crusoe_kubeconfig.my_cluster_kubeconfig.kubeconfig_yaml
      filename = local.kubeconfig_path
    }
    
    #############################################
    # Outputs
    #############################################
    output "cluster" {
      value = crusoe_kubernetes_cluster.my_cluster
    }
    
    output "nodepool" {
      value = crusoe_kubernetes_node_pool.my_nodepool
    }
    
    
  2. Once all the placeholders above are updated, run the following commands to apply the code:

    $ terraform plan
    $ terraform apply    
  3. Export Kubeconfig file to access the cluster

    $ export KUBECONFIG=<path to kubeconfig file>
  4. Run a `kubectl` command to verify the cluster is accessible

    $ kubectl get nodes
      NAME                                        STATUS   ROLES    AGE    VERSION
      np-8fa7d1df-1.us-east1-a.compute.internal   Ready       103s   v1.33.4

Additional Information

 

Related to

Was this article helpful?

0 out of 0 found this helpful

Still need help?

Our support team is ready to assist you with any questions.

Have more questions? Submit a request

Recently Viewed

Comments

0 comments

Article is closed for comments.