Project 2: Provision with Terraform & Deploy to Kubernetes
Infrastructure as code creates the cluster; Kubernetes runs your app at scale.
Your image is published β but where does it run? In Project 2 you provision infrastructure as code with Terraform (reproducible, version-controlled), then deploy your app to Kubernetes with the resilience features that make it production-worthy: health checks, resource limits, and autoscaling.
π― Learning Objectives
- Provision a Kubernetes cluster with Terraform
- Understand remote state and why it matters
- Write Kubernetes manifests with health checks and resource limits
- Expose the app and enable autoscaling
Step 1 β Provision Infrastructure with Terraform
Rather than clicking around a cloud console, you declare the cluster in code. A minimal example provisioning a managed cluster:
# main.tf
terraform {
backend "s3" { # remote state (see below)
bucket = "my-tf-state"
key = "prod/cluster.tfstate"
region = "us-east-1"
}
}
module "cluster" {
source = "terraform-aws-modules/eks/aws"
cluster_name = "portfolio-cluster"
cluster_version = "1.30"
# ... vpc, node groups, etc.
}
output "cluster_endpoint" {
value = module.cluster.cluster_endpoint
}The workflow is always the same three commands:
terraform init # download providers, connect backend
terraform plan # preview what will change (review this!)
terraform apply # create the infrastructureβ Always read the plan
terraform plan shows exactly what will be created, changed, or destroyed. Never apply in production without reading it β a careless change can destroy and recreate a database. The plan is your safety review.
Step 2 β Use Remote State
Notice the backend "s3" block. Terraform tracks reality in a state file. Keeping it on your laptop is a disaster waiting to happen β lost laptop, no teamwork, conflicting changes. Remote state (S3, GCS, Terraform Cloud) fixes this:
- Shared β the whole team works from one source of truth
- Locked β prevents two people applying at once and corrupting state
- Durable & versioned β survives your machine and can be rolled back
π‘ State is sensitive
The state file can contain secrets (passwords, keys) in plaintext. Store it in an encrypted, access-controlled backend β never commit it to Git.
Step 3 β Deploy to Kubernetes
With the cluster up, deploy your Project 1 image. A production-worthy Deployment includes probes and resource limits β not just the bare minimum:
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
spec:
replicas: 3
selector:
matchLabels: { app: myapp }
template:
metadata:
labels: { app: myapp }
spec:
containers:
- name: myapp
image: ghcr.io/you/myapp:a1b2c3d # deploy by SHA, not latest
ports:
- containerPort: 3000
livenessProbe: # restart if hung
httpGet: { path: /health, port: 3000 }
initialDelaySeconds: 5
readinessProbe: # don't send traffic until ready
httpGet: { path: /health, port: 3000 }
resources:
requests: { cpu: "100m", memory: "128Mi" }
limits: { cpu: "500m", memory: "256Mi" }Expose it with a Service so traffic can reach the pods:
apiVersion: v1
kind: Service
metadata:
name: myapp
spec:
type: LoadBalancer
selector: { app: myapp }
ports:
- port: 80
targetPort: 3000Step 4 β Autoscale
Let Kubernetes add and remove pods based on load with a HorizontalPodAutoscaler:
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: myapp
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: myapp
minReplicas: 3
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target: { type: Utilization, averageUtilization: 70 }Now the app scales out past 3 pods when CPU crosses 70%, and back in when load drops β capacity that follows demand, defined declaratively.
π§ͺ Hands-on Lab
Explain the Probes
Your app occasionally hangs (still βrunningβ but not responding), and during startup it briefly returns errors before itβs ready. Which probe addresses each problem, and what would happen without them?
π§ Knowledge Check
Why should Terraform state be stored in a remote backend rather than locally?
What is the difference between a liveness and a readiness probe?
πΌ Interview Preparation
Walk through how you'd deploy a containerised app to production on Kubernetes.
Summary
Project 2 is complete: Terraform provisions your cluster reproducibly with remote state, and your app runs on Kubernetes with probes, resource limits, a Service, and autoscaling. The final project adds the operational layer β observability and GitOps β to make the whole system truly production-grade.