Oracle Cloud Load Balancer with Terraform
Set up OCI Load Balancer with Terraform — backend sets, listeners, SSL certificates, and health checks. Step-by-step guide with code examples and best practi...
Cloud Computing
Mutable vs immutable infrastructure compared. Learn the differences, when to use each, and how tools like Terraform, Docker, and Ansible fit in.
When you deploy a server, can you change it later — or do you throw it away and build a new one? That's the core question behind mutable vs immutable infrastructure.
Mutable: You deploy a server and modify it over time (patches, config changes, updates). Immutable: You deploy a server and never change it. Need an update? Build a new one, replace the old one.
Most modern infrastructure leans immutable, but both approaches have their place. Here's when to use each.
| Mutable | Immutable | |
|---|---|---|
| Changes | Modify servers in place | Replace servers entirely |
| Config drift | Likely over time | Impossible by design |
| Rollback | Complex (undo changes) | Simple (deploy previous version) |
| Tools | Ansible, Chef, Puppet, SSH | Terraform, Docker, Packer, Kubernetes |
| Deploy speed | Fast (small changes) | Fast (swap instances) |
| State | Servers are unique | Servers are disposable |
| Scaling | Copy server + apply scripts | Launch from image |
| Best for | Legacy systems, stateful servers | Microservices, cloud-native apps |
In mutable infrastructure, servers are updated in place after deployment. You SSH in, apply patches, change configurations, restart services.
Day 1: Deploy Ubuntu 22.04 server
Day 30: apt update && apt upgrade (security patches)
Day 60: Change nginx config, restart nginx
Day 90: Install monitoring agent
Day 120: Update application to v2.0The server accumulates changes over time. Each server becomes unique based on its history.
Ansible is the most popular mutable infrastructure tool. It connects to existing servers and applies changes:
# ansible playbook — modify servers in place
- hosts: webservers
tasks:
- name: Update packages
apt:
upgrade: dist
update_cache: yes
- name: Install nginx
apt:
name: nginx
state: present
- name: Deploy app config
template:
src: nginx.conf.j2
dest: /etc/nginx/nginx.conf
notify: restart nginxThe biggest risk with mutable infrastructure is configuration drift — servers that should be identical gradually become different:
Server A: Ubuntu 22.04, nginx 1.22, Node 18, monitoring agent v2
Server B: Ubuntu 22.04, nginx 1.24, Node 20, monitoring agent v3
Server C: Ubuntu 22.04, nginx 1.22, Node 18, no monitoring agent (someone forgot)All three servers were supposed to be identical. Over months of manual patches and hotfixes, they diverged. Now a deployment that works on Server A fails on Server B. This is the "snowflake server" problem.
In immutable infrastructure, servers are never modified after deployment. Every change produces a new server image, and the old server is destroyed.
v1.0: Build image → Deploy 3 instances → Running
v1.1: Build NEW image → Deploy 3 NEW instances → Destroy old instances
v1.2: Build NEW image → Deploy 3 NEW instances → Destroy old instancesNo SSH, no patching, no config changes. If something needs to change, you build a new version from scratch.
Step 1: Build a machine image with Packer:
# packer template
source "amazon-ebs" "web" {
ami_name = "web-app-{{timestamp}}"
instance_type = "t3.micro"
region = "us-east-1"
source_ami = "ami-0c55b159cbfafe1f0"
}
build {
sources = ["source.amazon-ebs.web"]
provisioner "shell" {
inline = [
"sudo apt-get update",
"sudo apt-get install -y nginx nodejs",
"sudo systemctl enable nginx"
]
}
provisioner "file" {
source = "app/"
destination = "/var/www/app"
}
}Step 2: Deploy with Terraform:
# terraform — deploy the immutable image
resource "aws_instance" "web" {
count = 3
ami = "ami-NEW-VERSION" # New AMI from Packer
instance_type = "t3.micro"
tags = {
Name = "web-${count.index}"
Version = "1.1"
}
}Every deployment uses a fresh image. All servers are identical by construction.
Containers are the most common form of immutable infrastructure:
# Dockerfile — immutable by design
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --production
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]# kubernetes deployment — replace pods, never patch them
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app
spec:
replicas: 3
template:
spec:
containers:
- name: web
image: myapp:1.1 # New version = new image
ports:
- containerPort: 3000Most real-world architectures use both:
┌─────────────────────────────────────────────┐
│ IMMUTABLE (replace, never modify) │
│ • Web servers (Docker/AMI) │
│ • API servers │
│ • Worker processes │
│ • Lambda functions │
└─────────────────────────────────────────────┘
↕
┌─────────────────────────────────────────────┐
│ MUTABLE (update in place) │
│ • Databases (RDS, PostgreSQL) │
│ • File storage (S3, EFS) │
│ • Message queues (SQS, RabbitMQ) │
│ • Caches (Redis, ElastiCache) │
└─────────────────────────────────────────────┘Compute is immutable (easy to replace). Data is mutable (needs to persist). This is the standard pattern in modern cloud architecture.
| Tool | Approach | What It Does |
|---|---|---|
| Terraform | Immutable | Provisions infrastructure (VMs, networks, services) |
| Packer | Immutable | Builds machine images (AMIs, Docker images) |
| Docker | Immutable | Packages applications as container images |
| Kubernetes | Immutable | Orchestrates container deployments |
| Ansible | Mutable | Configures existing servers |
| Chef | Mutable | Configures existing servers |
| Puppet | Mutable | Configures existing servers |
Terraform + Packer + Docker = fully immutable infrastructure pipeline.
If you're currently using mutable infrastructure:
Learn by doing with interactive courses on CopyPasteLearn:
Immutable infrastructure is the modern standard for cloud-native applications: build an image, test it, deploy it, never modify it. Mutable infrastructure still works for stateful systems and legacy applications. Most production environments use both — immutable compute (containers, AMIs) with mutable data (databases, storage). Start immutable with Terraform and Docker, use Ansible for the things that genuinely need in-place changes.
Set up OCI Load Balancer with Terraform — backend sets, listeners, SSL certificates, and health checks. Step-by-step guide with code examples and best practi...
Configure OCI Object Storage buckets with Terraform — lifecycle policies, pre-authenticated requests, and replication. Step-by-step guide with code examples ...
Deploy Oracle Autonomous Database with Terraform — ATP and ADW instances, wallets, and private endpoints. Step-by-step guide with code examples and best prac...
Build Oracle Cloud Virtual Cloud Networks with Terraform — subnets, security lists, route tables, and gateways. Step-by-step guide with code examples and bes...