Immutable infrastructure is a paradigm where servers are never modified after deployment. Instead of patching existing systems, you replace them entirely with new instances built from a common image. This approach eliminates configuration drift and improves reliability.
Benefits of Immutable Infrastructure
- Consistency: Every deployment is identical
- Reliability: No configuration drift over time
- Rollback: Easy to revert to previous versions
- Security: Reduced attack surface, no manual changes
- Auditability: Complete history in version control
Building Immutable AMIs with Packer
# packer.pkr.hcl
packer {
required_plugins {
amazon = {
version = ">= 1.0.0"
source = "github.com/hashicorp/amazon"
}
}
}
source "amazon-ebs" "app" {
ami_name = "app-{{timestamp}}"
instance_type = "t3.medium"
region = "us-east-1"
source_ami_filter {
filters = {
name = "amzn2-ami-hvm-*-x86_64-gp2"
root-device-type = "ebs"
virtualization-type = "hvm"
}
owners = ["amazon"]
most_recent = true
}
ssh_username = "ec2-user"
tags = {
Name = "app-server"
Environment = "production"
BuildTime = "{{timestamp}}"
}
}
build {
sources = ["source.amazon-ebs.app"]
provisioner "shell" {
scripts = [
"scripts/install-dependencies.sh",
"scripts/configure-app.sh",
"scripts/harden-os.sh"
]
}
provisioner "file" {
source = "configs/"
destination = "/etc/app/"
}
post-processor "manifest" {
output = "manifest.json"
}
}Blue-Green Deployment
# Terraform - Blue-Green with ASG
resource "aws_autoscaling_group" "blue" {
name = "app-blue"
desired_capacity = var.blue_active ? var.desired_capacity : 0
max_size = var.max_size
min_size = var.blue_active ? var.min_size : 0
target_group_arns = [aws_lb_target_group.app.arn]
vpc_zone_identifier = var.subnet_ids
launch_template {
id = aws_launch_template.blue.id
version = "$Latest"
}
instance_refresh {
strategy = "Rolling"
preferences {
min_healthy_percentage = 90
}
}
}
resource "aws_autoscaling_group" "green" {
name = "app-green"
desired_capacity = var.blue_active ? 0 : var.desired_capacity
max_size = var.max_size
min_size = var.blue_active ? 0 : var.min_size
target_group_arns = [aws_lb_target_group.app.arn]
vpc_zone_identifier = var.subnet_ids
launch_template {
id = aws_launch_template.green.id
version = "$Latest"
}
}Drift Detection with AWS Config
# Terraform - Drift detection rule
resource "aws_config_config_rule" "ec2_managed_instance" {
name = "ec2-managedinstance-inventory-blacklisted"
source {
owner = "AWS"
source_identifier = "EC2_MANAGEDINSTANCE_INVENTORY_BLACKLISTED"
}
input_parameters = jsonencode({
inventoryNames = "AWS:Application"
})
}
# CloudWatch alarm for drift
resource "aws_cloudwatch_metric_alarm" "config_drift" {
alarm_name = "config-drift-detected"
comparison_operator = "GreaterThanThreshold"
evaluation_periods = 1
metric_name = "NonCompliantResourceCount"
namespace = "AWS/Config"
period = 300
statistic = "Average"
threshold = 0
alarm_actions = [aws_sns_topic.alerts.arn]
}Container-Based Immutability
# Dockerfile with immutable best practices
FROM python:3.11-slim AS builder
WORKDIR /app
COPY requirements.txt .
RUN pip install --user --no-cache-dir -r requirements.txt
FROM python:3.11-slim
WORKDIR /app
# Create non-root user
RUN useradd -r -s /bin/false appuser
# Copy dependencies
COPY --from=builder /root/.local /home/appuser/.local
COPY --chown=appuser:appuser . .
# Make filesystem read-only where possible
RUN chmod -R 555 /app
USER appuser
ENV PATH=/home/appuser/.local/bin:$PATH
CMD ["python", "app.py"]CI/CD Pipeline
# GitHub Actions - Immutable deployment
name: Deploy
on:
push:
branches: [main]
jobs:
build-ami:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build AMI
run: packer build packer.pkr.hcl
- name: Update Terraform
run: |
AMI_ID=$(jq -r '.builds[0].artifact_id' manifest.json | cut -d: -f2)
sed -i "s/ami-[a-z0-9]*/\$AMI_ID/" terraform/variables.tf
- name: Deploy
run: |
cd terraform
terraform apply -auto-approveConclusion
Immutable infrastructure eliminates configuration drift and improves system reliability. By combining tools like Packer for image building, Terraform for deployment, and AWS Config for drift detection, teams can achieve truly immutable deployments.

