Skip to main content
Terraform Basics
CHAPTER 13

Terraform and Kubernetes

Updated: May 15, 2026
30 min read

# CHAPTER 13

Terraform and Kubernetes

1. Introduction

As organizations scale, managing individual Docker containers becomes impossible. If a container crashes at 3:00 AM, who restarts it? If traffic spikes, who launches 50 more containers? Kubernetes (K8s) solves this by orchestrating massive clusters of containers automatically. But how do you orchestrate the orchestrator? In this chapter, we explore the powerful intersection of two DevOps titans. We will use Terraform to provision the underlying Kubernetes Cluster (the hardware), and then use the Terraform Kubernetes Provider to deploy applications (the software) *inside* that cluster.

2. Learning Objectives

By the end of this chapter, you will be able to:
  • Differentiate between provisioning a K8s Cluster vs. provisioning K8s Resources.
  • Configure the Terraform Kubernetes Provider.
  • Define Kubernetes Namespaces, Deployments, and Services using HCL.
  • Understand the integration between the AWS/GCP providers and the Kubernetes provider.
  • Evaluate the pros and cons of using Terraform versus Helm/YAML for K8s deployments.

3. Beginner-Friendly Explanation

Imagine a massive shipping port.
  • The AWS Provider (Building the Port): You use Terraform to pour the concrete, build the cranes, and hire the port manager. (Provisioning the EKS/GKE Kubernetes Cluster).
  • Kubernetes (The Manager): The port manager whose only job is to organize shipping containers.
  • The Kubernetes Provider (Giving Orders): You use Terraform to hand a clipboard to the port manager. The clipboard says: "I need exactly 5 containers of shoes unloaded, and if one breaks, instantly replace it." (Deploying Pods and Services).

4. Phase 1: Provisioning the Cluster (Hardware)

Before we can use Kubernetes, we must build it. Building a production-grade Amazon EKS (Elastic Kubernetes Service) cluster from raw resources requires 50+ lines of complex IAM and VPC code. Best Practice: Always use the official Terraform Registry module for cluster creation.
hcl
1234567891011121314151617181920
module "eks" {
  source  = "terraform-aws-modules/eks/aws"
  version = "~> 19.0"

  cluster_name    = "my-company-cluster"
  cluster_version = "1.27"

  vpc_id     = module.vpc.vpc_id
  subnet_ids = module.vpc.private_subnets

  eks_managed_node_groups = {
    # We define the worker nodes (the servers that actually run the containers)
    general_compute = {
      min_size     = 1
      max_size     = 3
      desired_size = 2
      instance_types = ["t3.large"]
    }
  }
}

5. Phase 2: Deploying to the Cluster (Software)

Once the cluster exists, we use a *second* provider (the kubernetes provider) to interact with it.
hcl
1234567891011
provider "kubernetes" {
  # We dynamically pull the authentication details from the AWS EKS module above!
  host                   = module.eks.cluster_endpoint
  cluster_ca_certificate = base64decode(module.eks.cluster_certificate_authority_data)
  
  exec {
    api_version = "client.authentication.k8s.io/v1beta1"
    command     = "aws"
    args        = ["eks", "get-token", "--cluster-name", module.eks.cluster_name]
  }
}

6. Mini Project: Deploy a K8s Application via Terraform

Instead of writing native Kubernetes YAML files (kubectl apply -f pod.yaml), we can translate that logic directly into HCL. Let's deploy an Nginx web server.

Step-by-Step Architecture Concept:

hcl
123456789101112131415161718192021222324252627282930313233
# 1. Create a Namespace (A logical partition in the cluster)
resource "kubernetes_namespace" "web_app" {
  metadata {
    name = "frontend"
  }
}

# 2. Create the Deployment (The containers)
resource "kubernetes_deployment" "nginx" {
  metadata {
    name      = "nginx-deployment"
    namespace = kubernetes_namespace.web_app.metadata[0].name
  }

  spec {
    replicas = 3 # Kubernetes will ensure exactly 3 containers are always running

    selector {
      match_labels = { app = "nginx" }
    }

    template {
      metadata { labels = { app = "nginx" } }
      spec {
        container {
          image = "nginx:1.21.6"
          name  = "nginx"
          port { container_port = 80 }
        }
      }
    }
  }
}

*When you run terraform apply, Terraform talks to the Kubernetes API, which then pulls the Docker image and spins up 3 highly available containers.*

7. Real-World Scenarios

A FinTech company used Terraform to build their AWS infrastructure, but developers were manually running kubectl apply from their laptops to deploy microservices. One day, a developer deployed a broken microservice that crashed the cluster. Because it was done manually, there was no git history of the change. The DevOps team spent hours diagnosing the issue. They changed their policy: all Kubernetes deployments were translated into Terraform HCL. The entire state of the cluster was now governed by the terraform.tfstate file, ensuring complete auditability and the ability to instantly rollback broken K8s configurations via code.

8. Best Practices

  • Terraform vs Helm/YAML: The industry is divided on this. While Terraform *can* deploy Kubernetes resources, many experts prefer to use Terraform ONLY to build the cluster (Phase 1), and use tools like Helm or ArgoCD to deploy the applications (Phase 2). Terraform's state file struggles with Kubernetes resources that auto-update themselves (like auto-scaling pods), causing Terraform to constantly think the state has drifted. Evaluate carefully if you want to use the kubernetes provider for application deployment.

9. Security Recommendations

  • Authentication Execution: In the provider configuration, we used an exec block to dynamically generate an AWS authentication token (aws eks get-token). This is vastly superior to hardcoding a static, long-lived Kubernetes .kube/config file in your CI/CD pipeline, ensuring that authentication is ephemeral and tightly coupled to AWS IAM roles.

10. Troubleshooting Tips

  • Provider Initialization Failures: If you write the code to create the EKS cluster and the code to deploy the Kubernetes Deployment in the *exact same* Terraform apply, Terraform will often crash. It tries to initialize the kubernetes provider before the EKS cluster actually exists. The best practice is to separate cluster creation and application deployment into two distinct Terraform projects (workspaces).

11. Exercises

  1. 1. Explain the architectural difference between the aws provider (creating an EKS cluster) and the kubernetes provider.
  1. 2. Why is using the exec block to dynamically generate an authentication token preferred over using a static kubeconfig file?

12. FAQs

Q: Can I use Terraform to manage an existing Kubernetes cluster that I created manually? A: Yes. As long as you can provide the cluster endpoint and certificate to the kubernetes provider, Terraform can connect to it and start managing namespaces and deployments, regardless of how the cluster was originally built.

13. Interview Questions

  • Q: Describe a unified deployment workflow using Terraform to provision both the underlying cloud Kubernetes infrastructure (e.g., GKE or EKS) and the application workloads. What are the synchronization challenges of defining both in the same state file?
  • Q: Contrast the operational philosophy of deploying Kubernetes workloads using Terraform's kubernetes_deployment resource versus utilizing native Kubernetes manifest files with a GitOps tool like ArgoCD.

14. Summary

In Chapter 13, we bridged the gap between cloud infrastructure and container orchestration. We demonstrated how Terraform leverages the modular power of the Terraform Registry to effortlessly provision complex, enterprise-grade Kubernetes clusters across major cloud providers. Furthermore, we utilized the kubernetes provider to translate native K8s YAML configurations into declarative HCL, bringing the deployment of highly available, replicated application pods under the strict governance and auditability of the Terraform state file.

15. Next Chapter Recommendation

Running terraform apply from your laptop is fine for testing, but in production, humans should never type commands. Robots should. Proceed to Chapter 14: CI/CD with Terraform.

Finish this Chapter

Save your progress on your learning path and prepare for coding interview challenges.

Discussion

Join the discussion

Log in or create a free account to participate.

Sort: ·