TerraformPilot

DevOps

Fix Terraform Error - Helm Provider - Kubernetes Cluster Unreachable

Fix 'Kubernetes cluster unreachable' errors with the Helm Terraform provider. Handle kubeconfig, EKS/GKE/AKS authentication, and provider dependency ordering.

LLuca Berton2 min read

Quick Answer

#

The Helm provider can't connect to your Kubernetes cluster. Either the kubeconfig is wrong, the cluster doesn't exist yet, or the authentication token has expired. Configure the Helm provider to use cluster outputs directly, not a static kubeconfig file.

The Error

#
Error: Kubernetes cluster unreachable: Get 
"https://EKS_ENDPOINT/api/v1/namespaces": dial tcp: 
lookup EKS_ENDPOINT: no such host
Error: Kubernetes cluster unreachable: the server has asked 
for the client to provide credentials

What Causes This

#

1. Cluster Not Created Yet

#

Terraform tries to configure the Helm provider at plan time, but the cluster doesn't exist yet.

2. Wrong Kubeconfig

#

Pointing to the wrong cluster, context, or expired credentials.

3. EKS Auth Token Expired

#

AWS auth tokens for EKS expire every 15 minutes.

How to Fix It

#

Solution 1: Configure Helm Provider with Cluster Outputs (EKS)

#
data "aws_eks_cluster" "main" {
  name = aws_eks_cluster.main.name
}
 
data "aws_eks_cluster_auth" "main" {
  name = aws_eks_cluster.main.name
}
 
provider "helm" {
  kubernetes {
    host                   = data.aws_eks_cluster.main.endpoint
    cluster_ca_certificate = base64decode(data.aws_eks_cluster.main.certificate_authority[0].data)
    token                  = data.aws_eks_cluster_auth.main.token
  }
}

Solution 2: GKE Configuration

#
data "google_client_config" "default" {}
 
data "google_container_cluster" "main" {
  name     = google_container_cluster.main.name
  location = google_container_cluster.main.location
}
 
provider "helm" {
  kubernetes {
    host                   = "https://${data.google_container_cluster.main.endpoint}"
    token                  = data.google_client_config.default.access_token
    cluster_ca_certificate = base64decode(data.google_container_cluster.main.master_auth[0].cluster_ca_certificate)
  }
}

Solution 3: AKS Configuration

#
provider "helm" {
  kubernetes {
    host                   = azurerm_kubernetes_cluster.main.kube_config[0].host
    client_certificate     = base64decode(azurerm_kubernetes_cluster.main.kube_config[0].client_certificate)
    client_key             = base64decode(azurerm_kubernetes_cluster.main.kube_config[0].client_key)
    cluster_ca_certificate = base64decode(azurerm_kubernetes_cluster.main.kube_config[0].cluster_ca_certificate)
  }
}

Solution 4: Separate Apply Stages

#

If the cluster and Helm releases are in the same config, use -target:

# Step 1: Create the cluster
terraform apply -target=aws_eks_cluster.main -target=aws_eks_node_group.main
 
# Step 2: Deploy Helm charts
terraform apply

Or better — split into separate Terraform configs:

infrastructure/
├── cluster/      # EKS/GKE/AKS cluster
│   └── main.tf
└── workloads/    # Helm releases
    └── main.tf   # Uses remote state from cluster/

Common Issues

#
SymptomFix
"no such host"Cluster not created yet — use -target or split configs
"provide credentials"Auth token expired — use data source (refreshes on each run)
"connection refused"Cluster endpoint is private — run from within VPC
"certificate signed by unknown authority"Missing cluster_ca_certificate in provider config

Troubleshooting Checklist

#
  1. ✅ Does the cluster exist? (Check cloud console)
  2. ✅ Is the provider using cluster outputs (not static kubeconfig)?
  3. ✅ Can you reach the cluster endpoint from where Terraform runs?
  4. ✅ Is the auth token fresh (data source, not hardcoded)?
#

Conclusion

#

Always configure the Helm provider using cluster output data sources (not static kubeconfig files) — tokens refresh automatically on each run. Split cluster creation from workload deployment into separate configs, or use -target to create the cluster first.

#Terraform#Troubleshooting#DevOps#Error Fix#Kubernetes

Share this article