The Problem
Your EC2 instance is running low on disk space. The default root volume is typically 8 GB, which fills up fast with applications, logs, Docker images, or data.
You need to increase it — without destroying and recreating the instance.
Quick Answer
Add root_block_device to your aws_instance resource:
resource "aws_instance" "web" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t3.micro"
root_block_device {
volume_size = 50 # GB (default is 8)
volume_type = "gp3" # General Purpose SSD
encrypted = true
}
}
Run terraform apply. Terraform modifies the EBS volume in place — no instance replacement needed.
Complete Example
# variables.tf
variable "root_volume_size" {
description = "Root volume size in GB"
type = number
default = 50
}
variable "root_volume_type" {
description = "EBS volume type"
type = string
default = "gp3"
}
# main.tf
resource "aws_instance" "app" {
ami = data.aws_ami.ubuntu.id
instance_type = "t3.medium"
root_block_device {
volume_size = var.root_volume_size
volume_type = var.root_volume_type
encrypted = true
delete_on_termination = true
tags = {
Name = "app-root-volume"
}
}
tags = {
Name = "app-server"
}
}
data "aws_ami" "ubuntu" {
most_recent = true
owners = ["099720109477"]
filter {
name = "name"
values = ["ubuntu/images/hvm-ssd/ubuntu-jammy-22.04-amd64-server-*"]
}
}
output "root_volume_id" {
value = aws_instance.app.root_block_device[0].volume_id
}
Volume Types: gp2 vs gp3 vs io2
| Type | IOPS | Throughput | Cost | Best For |
|---|---|---|---|---|
| gp3 | 3,000 baseline (up to 16,000) | 125 MB/s (up to 1,000) | $0.08/GB/mo | Most workloads ✅ |
| gp2 | 3 per GB (up to 16,000) | 250 MB/s | $0.10/GB/mo | Legacy (gp3 is better) |
| io2 | Up to 64,000 | 1,000 MB/s | $0.125/GB/mo + IOPS | Databases, high IOPS |
| st1 | 500 | 500 MB/s | $0.045/GB/mo | Throughput-heavy (not for root) |
Always use gp3 unless you have specific IOPS requirements. It’s 20% cheaper than gp2 with better baseline performance.
root_block_device {
volume_size = 100
volume_type = "gp3"
iops = 6000 # Optional: increase from 3,000 baseline
throughput = 250 # Optional: increase from 125 MB/s baseline
}
What Happens During Resize
Growing the Volume (e.g., 8 GB → 50 GB)
- Terraform calls
ModifyVolumeAPI - AWS resizes the EBS volume in place
- Instance stays running — no reboot required for volume modification
- The OS filesystem needs to be extended (see below)
Terraform Plan Output
# aws_instance.app will be updated in-place
~ resource "aws_instance" "app" {
~ root_block_device {
~ volume_size = 8 -> 50
}
}
The key word is in-place — not replaced.
Filesystem Resize (After Terraform Apply)
The EBS volume is larger, but the OS filesystem still sees the old size. Extend it:
For ext4 (Ubuntu/Debian/Amazon Linux):
# Check current size
df -h /
# Grow the partition (if needed)
sudo growpart /dev/xvda 1
# Extend the filesystem
sudo resize2fs /dev/xvda1
For XFS (RHEL/CentOS/Amazon Linux 2023):
sudo growpart /dev/xvda 1
sudo xfs_growfs /
NVMe instances (t3, m5, c5, etc.) use /dev/nvme0n1p1:
sudo growpart /dev/nvme0n1 1
sudo resize2fs /dev/nvme0n1p1
Automate Filesystem Resize with User Data
resource "aws_instance" "app" {
ami = data.aws_ami.ubuntu.id
instance_type = "t3.medium"
root_block_device {
volume_size = 50
volume_type = "gp3"
encrypted = true
}
user_data = <<-EOF
#!/bin/bash
# Auto-extend filesystem on boot
growpart /dev/nvme0n1 1 || growpart /dev/xvda 1
resize2fs /dev/nvme0n1p1 || resize2fs /dev/xvda1 || xfs_growfs /
EOF
}
Adding Extra EBS Volumes
For data that should survive instance replacement, use separate EBS volumes:
resource "aws_ebs_volume" "data" {
availability_zone = aws_instance.app.availability_zone
size = 200
type = "gp3"
encrypted = true
tags = {
Name = "app-data-volume"
}
}
resource "aws_volume_attachment" "data" {
device_name = "/dev/xvdf"
volume_id = aws_ebs_volume.data.id
instance_id = aws_instance.app.id
}
Then on the instance:
# Format (first time only!)
sudo mkfs -t ext4 /dev/xvdf
# Mount
sudo mkdir -p /data
sudo mount /dev/xvdf /data
# Add to fstab for persistence
echo '/dev/xvdf /data ext4 defaults,nofail 0 2' | sudo tee -a /etc/fstab
Troubleshooting
“volume_size” forces instance replacement
If changing volume_size shows “must be replaced” instead of “updated in-place”, check:
- You’re not also changing the AMI
- You’re not changing
volume_typefrom the AMI default at the same time - Your Terraform AWS provider version is up to date
Volume modification is slow
EBS modifications can take 6+ hours for large volumes. Check status:
aws ec2 describe-volumes-modifications --volume-ids vol-12345678
Can’t shrink a volume
AWS does not support shrinking EBS volumes. You can only increase the size. To reduce, create a new smaller volume, copy data, and swap.
Filesystem shows old size after resize
You need to extend the filesystem (see commands above). The EBS volume is larger, but the filesystem needs to be told.
Cost Estimate
| Size | gp3 Monthly | gp2 Monthly |
|---|---|---|
| 8 GB (default) | $0.64 | $0.80 |
| 20 GB | $1.60 | $2.00 |
| 50 GB | $4.00 | $5.00 |
| 100 GB | $8.00 | $10.00 |
| 500 GB | $40.00 | $50.00 |
Prices for us-east-1. gp3 saves 20% over gp2 at every size.
Hands-On Courses
Learn by doing with interactive courses on CopyPasteLearn:
Conclusion
Add root_block_device { volume_size = 50 } to your aws_instance, use gp3 for the volume type, and run terraform apply. The resize happens in place with no instance replacement. Don’t forget to extend the filesystem afterward with growpart + resize2fs. For data volumes, use separate aws_ebs_volume resources so they survive instance rebuilds.




