Creating Kubernetes Resources with Terraform: Namespaces, Deployments, Services and More
This tutorial demonstrates how to use Terraform to define and provision common Kubernetes resources such as namespaces, deployments, services, ConfigMaps, Secrets, and PersistentVolumeClaims, providing step‑by‑step commands, code examples, and verification procedures for a fully automated workflow.
Using Terraform to create Kubernetes (k8s) resources treats infrastructure as code, enabling automation, version control, and repeatability. This guide walks through creating common resources: namespaces, deployments, and services.
Why Terraform is a good tool for configuring Kubernetes clusters:
Terraform allows users to maintain Kubernetes cluster definitions in code.
It uses the same declarative syntax for lower‑level infrastructure configuration.
Variables let you modify the Kubernetes cluster.
You can preview changes to the cluster before applying them.
Terraform can configure Kubernetes and deploy applications with the same configuration language.
One command creates, updates, and deletes pods and resources without manually invoking the API.
Terraform understands resource relationships and supports modular infrastructure code.
It shortens product delivery time by helping with disaster‑recovery and release issues.
Prerequisites:
A running Kubernetes cluster.
Terraform and kubectl installed and configured.
Now, let’s start creating resources.
Step 1: Set up Terraform configuration
Create a Terraform project directory:
mkdir terraform-k8s && cd terraform-k8sCreate a provider.tf file to define the Kubernetes provider:
terraform {
required_providers {
kubernetes = {
source = "hashicorp/kubernetes"
}
}
}
provider "kubernetes" {
config_path = "~/.kube/config"
}Note: Ensure the config_path points to your kubeconfig file.
Step 2: Define Kubernetes resources
Create a namespace.tf file to define a Kubernetes namespace:
resource "kubernetes_namespace" "demo" {
metadata {
name = "demo-namespace"
}
}Create a deployment.tf file for deploying an application:
resource "kubernetes_deployment" "demo" {
metadata {
name = "demo-deployment"
namespace = kubernetes_namespace.example.metadata[0].name
}
spec {
replicas = 3
selector {
match_labels = {
app = "demo"
}
}
template {
metadata {
labels = {
app = "demo"
}
}
spec {
container {
image = "nginx:latest"
name = "demo-deployment"
}
}
}
}
}Create a service.tf file to expose the deployment:
resource "kubernetes_service" "demo" {
metadata {
name = "demo-service"
namespace = kubernetes_namespace.example.metadata[0].name
}
spec {
selector = {
app = "example"
}
port {
port = 80
target_port = 80
}
type = "LoadBalancer"
}
}Create a configmap.tf file to define a ConfigMap:
resource "kubernetes_config_map" "demo" {
metadata {
name = "demo-config"
namespace = kubernetes_namespace.example.metadata[0].name
}
data = {
"config.json" = jsonencode({
"key" = "value"
})
}
}Create a secret.tf file to define a Kubernetes Secret (note: using native secrets is preferred over external secret stores):
resource "kubernetes_secret" "demo" {
metadata {
name = "demo-secret"
namespace = kubernetes_namespace.example.metadata[0].name
}
data = {
"password" = base64encode("supersecret")
}
}Note: Using native Kubernetes secrets instead of external secret stores or CSI drivers is recommended.
Create a pvc.tf file to define a PersistentVolumeClaim:
resource "kubernetes_persistent_volume_claim" "demo" {
metadata {
name = "demo-pvc"
namespace = kubernetes_namespace.example.metadata[0].name
}
spec {
access_modes = ["ReadWriteOnce"]
resources {
requests = {
storage = "10Gi"
}
}
}
}Modify the deployment to mount the ConfigMap and Secret:
resource "kubernetes_deployment" "demo" {
metadata {
name = "demo-deployment"
namespace = kubernetes_namespace.example.metadata[0].name
}
spec {
replicas = 3
selector {
match_labels = {
app = "demo"
}
}
template {
metadata {
labels = {
app = "demo"
}
}
spec {
container {
image = "nginx:latest"
name = "demo"
volume_mount {
mount_path = "/etc/config"
name = "config"
}
volume_mount {
mount_path = "/etc/secret"
name = "secret"
read_only = true
}
}
volume {
name = "config"
config_map {
name = kubernetes_config_map.example.metadata[0].name
}
}
volume {
name = "secret"
secret {
secret_name = kubernetes_secret.example.metadata[0].name
}
}
}
}
}
}Step 3: Initialize the working directory
Run terraform init in the project folder to download providers and initialize the backend.
Step 4: Create a Terraform plan
Run terraform plan to see the execution plan.
Step 5: Apply the Terraform configuration
Run terraform apply to create all required resources on the cluster.
Step 6: Verify the resources
After applying, verify that resources are correctly deployed:
kubectl get all --namespace=demo-namespaceYou have now learned how to use Terraform to create various Kubernetes resources. Feel free to adapt the configurations to your own needs.
<Book Recommendation>
2024 release covering enterprise‑level DevOps CI/CD practices!
<Training Camp Update>
The 8th session of the DevOps practical training camp started on May 18, 2024, focusing on microservice applications in a Kubernetes environment.
第⑧期DevOps实战营正式发布!
DevOps Cloud Academy
Exploring industry DevOps practices and technical expertise.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.