The Terraform Kubernetes provider manages Kubernetes resources directly. Errors typically stem from cluster connectivity, authentication, RBAC permissions, and API version mismatches.

Understanding Kubernetes Provider Errors

Common errors include: `` Error: Kubernetes cluster unreachable: connection refused Error: Forbidden: unauthorized to create resource Error: Resource version mismatch: object has been modified Error: API version "extensions/v1beta1" not found

Issue 1: Cluster Connectivity Failures

Cannot connect to Kubernetes API server.

Error Example: `` Error: Kubernetes cluster unreachable: Get "https://CLUSTER_ENDPOINT/version": dial tcp: connection refused

Solution:

Configure proper authentication for different cluster types:

For EKS clusters: ```hcl data "aws_eks_cluster" "cluster" { name = var.cluster_name }

data "aws_eks_cluster_auth" "cluster" { name = var.cluster_name }

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

# Or using exec method (recommended for newer EKS) provider "kubernetes" { host = data.aws_eks_cluster.cluster.endpoint cluster_ca_certificate = base64decode(data.aws_eks_cluster.cluster.certificate_authority[0].data)

exec { api_version = "client.authentication.k8s.io/v1beta1" command = "aws" args = ["eks", "get-token", "--cluster-name", var.cluster_name] } } ```

For GKE clusters: ```hcl data "google_client_config" "default" {}

data "google_container_cluster" "cluster" { name = var.cluster_name location = var.cluster_location }

provider "kubernetes" { host = "https://${data.google_container_cluster.cluster.endpoint}" cluster_ca_certificate = base64decode(data.google_container_cluster.cluster.master_auth[0].cluster_ca_certificate) token = data.google_client_config.default.access_token } ```

For Azure AKS clusters: ```hcl data "azurerm_kubernetes_cluster" "cluster" { name = var.cluster_name resource_group_name = var.resource_group }

provider "kubernetes" { host = data.azurerm_kubernetes_cluster.cluster.kube_config[0].host client_certificate = base64decode(data.azurerm_kubernetes_cluster.cluster.kube_config[0].client_certificate) client_key = base64decode(data.azurerm_kubernetes_cluster.cluster.kube_config[0].client_key) cluster_ca_certificate = base64decode(data.azurerm_kubernetes_cluster.cluster.kube_config[0].cluster_ca_certificate) } ```

Using kubeconfig: ``hcl provider "kubernetes" { config_path = "~/.kube/config" config_context = "my-cluster-context" }

Issue 2: RBAC Permission Denied

Insufficient permissions to manage Kubernetes resources.

Error Example: `` Error: Forbidden: User "terraform" cannot create resource "deployments" in API group "apps" in namespace "production"

Solution:

Create proper RBAC configuration: ```hcl resource "kubernetes_service_account" "terraform" { metadata { name = "terraform-deployer" namespace = "kube-system" } }

resource "kubernetes_cluster_role" "terraform" { metadata { name = "terraform-deployer" }

rule { api_groups = ["", "apps", "batch", "extensions", "networking.k8s.io"] resources = ["*"] verbs = ["create", "delete", "get", "list", "update", "watch", "patch"] }

rule { api_groups = ["rbac.authorization.k8s.io"] resources = ["roles", "rolebindings", "clusterroles", "clusterrolebindings"] verbs = ["create", "delete", "get", "list", "update", "watch", "patch"] } }

resource "kubernetes_cluster_role_binding" "terraform" { metadata { name = "terraform-deployer-binding" }

role_ref { api_group = "rbac.authorization.k8s.io" kind = "ClusterRole" name = kubernetes_cluster_role.terraform.metadata[0].name }

subject { kind = "ServiceAccount" name = kubernetes_service_account.terraform.metadata[0].name namespace = "kube-system" } } ```

Namespace-specific permissions: ```hcl resource "kubernetes_role" "terraform_namespace" { metadata { name = "terraform-deployer" namespace = var.namespace }

rule { api_groups = ["", "apps"] resources = ["deployments", "services", "configmaps", "secrets"] verbs = ["*"] } }

resource "kubernetes_role_binding" "terraform_namespace" { metadata { name = "terraform-deployer" namespace = var.namespace }

role_ref { api_group = "rbac.authorization.k8s.io" kind = "Role" name = kubernetes_role.terraform_namespace.metadata[0].name }

subject { kind = "User" name = "terraform-user" api_group = "rbac.authorization.k8s.io" } } ```

Issue 3: Resource Version Mismatch

Resource has been modified outside Terraform.

Error Example: `` Error: Resource version mismatch: object has been modified Expected version: 12345, Current version: 12346

Solution:

Re-import the resource: ``bash terraform import kubernetes_deployment.app production/my-app

Or refresh state: ``bash terraform refresh -target=kubernetes_deployment.app

Prevent drift by ignoring certain fields: ```hcl resource "kubernetes_deployment" "app" { metadata { name = "my-app" namespace = "production" }

spec { # ... configuration ... }

lifecycle { # Ignore changes made by Kubernetes autoscaling ignore_changes = [ spec[0].replicas ]

# Prevent accidental deletion prevent_destroy = true } } ```

Issue 4: API Version Deprecation

Using deprecated API versions.

Error Example: `` Error: API version "extensions/v1beta1" is deprecated Use "apps/v1" instead

Solution:

Update to current API versions: ```hcl # Old (deprecated) # resource "kubernetes_deployment" "app" { # metadata { name = "my-app" } # spec { # replicas = 3 # } # }

# New (correct API version) resource "kubernetes_deployment" "app" { metadata { name = "my-app" namespace = "default"

annotations = { "kubectl.kubernetes.io/last-applied-configuration" = jsonencode({}) } }

spec { replicas = 3

selector { match_labels = { app = "my-app" } }

template { metadata { labels = { app = "my-app" } }

spec { container { name = "app" image = "nginx:latest"

port { container_port = 80 } } } } } } ```

Common API version updates: - Deployments: extensions/v1beta1 -> apps/v1 - DaemonSets: extensions/v1beta1 -> apps/v1 - StatefulSets: apps/v1beta1 -> apps/v1 - Ingress: extensions/v1beta1 -> networking.k8s.io/v1 - NetworkPolicy: extensions/v1beta1 -> networking.k8s.io/v1

Issue 5: Namespace Does Not Exist

Target namespace not found.

Error Example: `` Error: namespaces "production" not found

Solution:

Create namespace before other resources: ```hcl resource "kubernetes_namespace" "production" { metadata { name = "production"

labels = { environment = "production" managed-by = "terraform" } } }

resource "kubernetes_deployment" "app" { metadata { name = "my-app" namespace = kubernetes_namespace.production.metadata[0].name }

spec { replicas = 3 }

depends_on = [kubernetes_namespace.production] } ```

Issue 6: Invalid YAML or Configuration

Resource configuration has syntax errors.

Error Example: `` Error: Invalid configuration: port number must be between 1 and 65535 Error: YAML parse error: line 25: unexpected character

Solution:

Validate configuration: ```hcl resource "kubernetes_service" "app" { metadata { name = "my-app-service" namespace = "default" }

spec { selector = { app = "my-app" }

port { name = "http" port = 80 # Valid: 1-65535 target_port = 8080 # Valid: 1-65535 or string protocol = "TCP" # TCP, UDP, or SCTP }

type = "LoadBalancer" # ClusterIP, NodePort, LoadBalancer, or ExternalName } } ```

Use kubectl_manifest for complex YAML: ```hcl resource "kubectl_manifest" "custom_resource" { yaml_body = <<-YAML apiVersion: custom.example.com/v1 kind: CustomResource metadata: name: my-custom-resource namespace: production spec: replicas: 3 config: key: value YAML

depends_on = [kubernetes_namespace.production] } ```

Issue 7: Secret Encoding Issues

Secret data not properly base64 encoded.

Error Example: `` Error: Invalid secret data: value must be base64 encoded

Solution:

Encode secret values: ```hcl resource "kubernetes_secret" "app_secrets" { metadata { name = "app-secrets" namespace = "production" }

data = { username = base64encode("admin") password = base64encode(var.db_password) api_key = base64encode(var.api_key) }

type = "Opaque" }

# Or use sensitive values resource "kubernetes_secret" "sensitive" { metadata { name = "sensitive-secrets" namespace = "production" }

data = { # Terraform handles encoding secret_value = base64encode(sensitive_value) } } ```

Issue 8: Timeout Waiting for Resource

Resource creation takes too long.

Error Example: `` Error: timed out waiting for resource "kubernetes_deployment.app" to be ready

Solution:

Configure timeouts and wait conditions: ```hcl resource "kubernetes_deployment" "app" { metadata { name = "my-app" namespace = "production" }

spec { replicas = 3

# ... rest of configuration ...

# Wait for deployment to be ready wait_for_rollout = true }

timeouts { create = "10m" update = "10m" delete = "5m" } } ```

Check deployment status: ``bash kubectl rollout status deployment/my-app -n production kubectl get pods -l app=my-app -n production kubectl describe deployment my-app -n production

Issue 9: Provider Version Conflicts

Provider version incompatible with cluster version.

Error Example: `` Error: Provider does not support Kubernetes version 1.24

Solution:

Update provider version: ```hcl terraform { required_providers { kubernetes = { source = "hashicorp/kubernetes" version = "~> 2.20" # Compatible with Kubernetes 1.24+ } } }

provider "kubernetes" { # Configuration ... } ```

Check compatibility matrix: - Kubernetes provider 2.0+ supports Kubernetes 1.19+ - Kubernetes provider 2.20+ supports Kubernetes 1.24+ - Use latest provider for newest Kubernetes versions

Verification Steps

Test cluster connectivity: ```bash kubectl cluster-info kubectl get nodes kubectl version

# Test with terraform terraform plan -target=kubernetes_namespace.test ```

Verify RBAC permissions: ``bash kubectl auth can-i create deployments --as=terraform-user kubectl auth can-i '*' '*' --all-namespaces

Prevention Best Practices

  1. 1.Configure authentication before deploying resources
  2. 2.Create namespaces before namespace-scoped resources
  3. 3.Use current API versions (apps/v1, networking.k8s.io/v1)
  4. 4.Encode secret values with base64encode()
  5. 5.Add depends_on for resource dependencies
  6. 6.Use ignore_changes for fields managed by Kubernetes
  7. 7.Configure appropriate timeouts for slow resources
  8. 8.Keep provider version updated for Kubernetes compatibility