Sling Academy
Home/DevOps/How to Use Terraform with Kubernetes for Infrastructure as Code

How to Use Terraform with Kubernetes for Infrastructure as Code

Last updated: January 30, 2024

Introduction

Infrastructure as Code (IaC) is a key DevOps practice that involves managing and provisioning infrastructure through machine-readable definition files, rather than through physical hardware configuration or interactive configuration tools. In this tutorial, we will explore how to use Terraform, an open-source IaC tool developed by HashiCorp, in conjunction with Kubernetes, the popular container-orchestration system. By the end of this tutorial, you’ll have a solid understanding of deploying Kubernetes resources using Terraform.

Prerequisites

  • A basic understanding of Kubernetes concepts such as pods, services, and deployments
  • Terraform installed on your local machine
  • Kubectl installed and configured
  • Access to a Kubernetes cluster

Setting Up Your Terraform Configuration

First, create a new directory for your Terraform configuration files:

mkdir terraform-k8s
 cd terraform-k8s

Next, create a file named provider.tf that will specify the Kubernetes provider for Terraform:

terraform {
 required_providers {
   kubernetes = {
     source = "hashicorp/kubernetes"
   }
 }
}

provider "kubernetes" {
 config_path    = "path/to/your/kubeconfig"
}

Replace path/to/your/kubeconfig with the actual path to your Kubernetes configuration file.

Defining Your First Resource

With the provider set up, you can now define your first Kubernetes resource. Create a file named main.tf and define a simple Pod:

resource "kubernetes_pod" "nginx" {
 metadata {
   name = "nginx-example"
   labels {
     app = "nginx"
   }
 }
 spec {
   container {
     image = "nginx:1.19"
     name  = "nginx"
   }
 }
}

Initialize Terraform and apply the configuration:

terraform init
terraform apply

You should see output indicating that Terraform has created the Pod:

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

Deploying More Complex Configurations

Let’s define a more complex scenario with a Deployment that has 3 replicas of the Nginx pod and a LoadBalancer Service to expose the application:

resource "kubernetes_deployment" "nginx-deployment" {
 metadata {
 name = "nginx-deployment"
 labels {
   app = "nginx"
 }
 }
 spec {
 replicas = 3
 selector {
   match_labels {
     app = "nginx"
   }
 }
 template {
   metadata {
     labels {
       app = "nginx"
     }
   }
 spec {
   container {
     image = "nginx:1.19"
     name  = "nginx"
   }
 }
 }
}

resource "kubernetes_service" "nginx" {
 metadata {
   name = "nginx-service"
 }
 spec {
   selector {
     app = "nginx"
   }
 type = "LoadBalancer"
 port {
   port        = 80
   target_port = 80
 }
}
}

Apply the updated configuration:

terraform apply

The output will show that Terraform created the Deployment and Service:

Apply complete! Resources: 2 added, 0 changed, 0 destroyed.

Using Modules for Reusability

Terraform modules encapsulate and reuse resource configurations. To use a module, create a directory named modules, then define a module for an Nginx deployment and service:

// modules/nginx/main.tf

resource "kubernetes_deployment" "nginx" { /* ... */ }
resource "kubernetes_service" "nginx" { /* ... */ }

In your main.tf, call the module:

module "nginx" {
 source = "./modules/nginx"
}

Initialize and apply the changes:

terraform init
terraform apply

Terraform will use the module to create your resources, following the DRY (Don’t Repeat Yourself) principle.

Managing State with Terraform

Terraform keeps track of your infrastructure’s state, allowing for incremental changes and management of resources. It’s important to keep the Terraform state file secure and backed up. For team environments, consider using remote state backends like AWS S3 or Terraform Cloud to store and lock your state file.

Advanced Use Cases

Provisioning a Kubernetes Cluster with Terraform

Beyond managing resources in an existing cluster, Terraform can also provision the Kubernetes cluster itself. For example, you can use Terraform to create a cluster on a cloud provider like AWS, GCP, or Azure, though this usage would require additional provider configurations and resources specific to these services. We won’t dive deep into this, but you should be aware of this powerful capability.

Terraform Workspaces for Environment Management

When working with multiple environments (e.g., staging, production), Terraform workspaces allow you to manage distinct sets of infrastructure resources under the same configuration. This is much cleaner and safer than copying configuration files for each environment.

Best Practices

  • Commit your plans: Before applying changes, run terraform plan and commit the outcome to version control, so your team can review changes.
  • Continuous Integration: Set up CI pipelines to test and apply Terraform configurations.
  • Use Variables: Parameterize configurations using variables for flexibility and environment-specific values.
  • Read the Documentation: The Terraform documentation is a comprehensive resource to understand how to use different features and best practices.

Conclusion

Terraform empowers developers and operators to manage Kubernetes resources declaratively and predicts outcomes through its planning process. With its modular design and ability to manage the entire cluster life cycle, it’s an essential tool for scalable and efficient Kubernetes infrastructure management.

Next Article: How to Set Up Cross-Cluster Communication in Kubernetes

Previous Article: How to Implement GitOps with Kubernetes Using ArgoCD

Series: Kubernetes Tutorials

DevOps

You May Also Like

  • How to reset Ubuntu to factory settings (4 approaches)
  • Making GET requests with cURL: A practical guide (with examples)
  • Git: What is .DS_Store and should you ignore it?
  • NGINX underscores_in_headers: Explained with examples
  • How to use Jenkins CI with private GitHub repositories
  • Terraform: Understanding State and State Files (with Examples)
  • SHA1, SHA256, and SHA512 in Terraform: A Practical Guide
  • CSRF Protection in Jenkins: An In-depth Guide (with examples)
  • Terraform: How to Merge 2 Maps
  • Terraform: How to extract filename/extension from a path
  • JSON encoding/decoding in Terraform: Explained with examples
  • Sorting Lists in Terraform: A Practical Guide
  • Terraform: How to trigger a Lambda function on resource creation
  • How to use Terraform templates
  • Understanding terraform_remote_state data source: Explained with examples
  • Jenkins Authorization: A Practical Guide (with examples)
  • Solving Jenkins Pipeline NotSerializableException: groovy.json.internal.LazyMap
  • Understanding Artifacts in Jenkins: A Practical Guide (with examples)
  • Using Jenkins with AWS EC2 and S3: A Practical Guide