How to Resize an EBS Volume Without Downtime: A Step-by-Step Operational Guide

Your EC2 instance is running out of disk space mid-production — a classic operational emergency that doesn't require a maintenance window. AWS allows you to modify an EBS volume's size live and extend the file system while the instance keeps serving traffic.

TL;DR

PhaseActionDowntime?
1. Modify VolumeIncrease EBS size via Console or CLINone
2. Wait for OptimizationVolume enters optimizing stateNone
3. Extend PartitionRun growpart on the OS partitionNone
4. Resize File SystemRun resize2fs (ext4) or xfs_growfs (XFS)None

Architecture: What Actually Happens

Understanding the data flow prevents mistakes. The resize is a two-layer operation: the EBS block device layer (AWS-managed) and the OS file system layer (your responsibility). AWS expanding the volume does NOT automatically grow your file system — you must do that manually.

graph TD A[You: ModifyVolume API Call] --> B[AWS EBS Control Plane] B --> C{Volume State} C -->|modifying| D[Provisioning blocks...] D --> C C -->|optimizing| E[New size visible to OS] E --> F[OS: Block Device /dev/nvme0n1 shows 40G] F --> G[Partition table still shows 20G] G --> H[Run: growpart /dev/nvme0n1 1] H --> I[Partition now shows 40G] I --> J{File System Type?} J -->|ext4| K[Run: resize2fs /dev/nvme0n1p1] J -->|XFS| L[Run: xfs_growfs -d /] K --> M[df -hT shows 40G] L --> M
  1. AWS Control Plane: You submit a ModifyVolume API call. AWS provisions additional storage blocks on the EBS backend.
  2. Volume State Transition: The volume moves through modifyingoptimizingcompleted. The new size is available to the OS once it leaves modifying.
  3. OS Block Device: The kernel sees the larger block device (e.g., /dev/xvda or /dev/nvme0n1), but the partition table still reflects the old size.
  4. Partition Extension: growpart rewrites the partition table to claim the new unallocated space.
  5. File System Resize: resize2fs or xfs_growfs expands the file system metadata to fill the enlarged partition.
Analogy: Think of EBS as a physical hard drive and your file system as a bookshelf inside a room. AWS just knocked down a wall and gave you a bigger room — but your bookshelf still only occupies the original footprint. growpart extends the floor plan, and resize2fs/xfs_growfs moves the shelves to fill the new space.

Prerequisites & Constraints

  • EBS volume must be of type gp2, gp3, io1, io2, or st1/sc1 — all support live modification.
  • You can only increase EBS volume size, never decrease it.
  • After a modification, you must wait 6 hours before modifying the same volume again.
  • The EC2 instance must be running (not stopped) for a zero-downtime resize.
  • Requires IAM permission: ec2:ModifyVolume.

Step 1: Identify Your Volume

First, confirm the volume ID and current size from inside the instance and from AWS.

# On the EC2 instance — check current disk usage and device names
df -hT
lsblk

Sample output from lsblk:

NAME        MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
nvme0n1     259:0    0   20G  0 disk
└─nvme0n1p1 259:1    0   20G  0 part /

Note the device name (nvme0n1) and partition (nvme0n1p1). You'll need these in Step 3.

Step 2: Modify the EBS Volume (AWS Layer)

You can do this via the AWS Console or CLI. The CLI approach is reproducible and scriptable.

🔽 AWS CLI — Modify Volume Size
# Replace with your actual volume ID and desired size in GiB
VOLUME_ID="vol-0abc1234def567890"
NEW_SIZE=40  # in GiB

aws ec2 modify-volume \
  --volume-id "$VOLUME_ID" \
  --size $NEW_SIZE \
  --region us-east-1

Poll the modification state until it reaches optimizing or completed before proceeding:

aws ec2 describe-volumes-modifications \
  --volume-id vol-0abc1234def567890 \
  --region us-east-1 \
  --query 'VolumesModifications[*].{State:ModificationState,Size:TargetSize}' \
  --output table

Once the state is optimizing (not just modifying), the OS can see the new size. You do NOT need to wait for completed.

Step 3: Extend the Partition (OS Layer)

The OS kernel now sees a larger block device, but the partition table hasn't changed. Use growpart to fix this.

# Install growpart if not present (Amazon Linux 2 / RHEL / CentOS)
sudo yum install -y cloud-utils-growpart

# For Ubuntu/Debian
# sudo apt-get install -y cloud-guest-utils

# Extend partition 1 on nvme0n1
# Syntax: growpart  
sudo growpart /dev/nvme0n1 1

Verify the partition now reflects the new size:

lsblk

Expected output after growpart:

NAME        MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
nvme0n1     259:0    0   40G  0 disk
└─nvme0n1p1 259:1    0   40G  0 part /

Step 4: Resize the File System (OS Layer)

The correct command depends on your file system type. Check it first:

df -Th | grep -v tmpfs

For ext4 File Systems

# resize2fs works on a live, mounted ext4 file system
sudo resize2fs /dev/nvme0n1p1

For XFS File Systems (Amazon Linux 2 default)

# xfs_growfs operates on the MOUNT POINT, not the device
sudo xfs_growfs -d /

Critical distinction: resize2fs takes a device path. xfs_growfs takes a mount point. Mixing these up is a common mistake.

Step 5: Verify the Resize

df -hT

You should now see the full new size reflected under the mount point (e.g., /). No reboot required.

sequenceDiagram participant Ops as Operator participant CLI as AWS CLI participant EBS as EBS Service participant OS as EC2 Linux OS Ops->>CLI: modify-volume --size 40 CLI->>EBS: ModifyVolume API EBS-->>CLI: State: modifying EBS-->>CLI: State: optimizing Ops->>OS: growpart /dev/nvme0n1 1 OS-->>Ops: Partition extended to 40G Ops->>OS: xfs_growfs -d / OS-->>Ops: FS resized to 40G Ops->>OS: df -hT OS-->>Ops: / shows 40G available

IAM Policy: Least Privilege for Volume Modification

Grant only what's needed. The following policy allows modifying and describing volumes in a specific region without granting broader EC2 permissions.

🔽 IAM Policy JSON — Least Privilege EBS Modify
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AllowEBSModify",
      "Effect": "Allow",
      "Action": [
        "ec2:ModifyVolume",
        "ec2:DescribeVolumesModifications",
        "ec2:DescribeVolumes"
      ],
      "Resource": "*",
      "Condition": {
        "StringEquals": {
          "aws:RequestedRegion": "us-east-1"
        }
      }
    }
  ]
}

Note: ec2:ModifyVolume and ec2:DescribeVolumesModifications do not support resource-level restrictions on specific volume ARNs at the IAM policy level for all conditions — always verify current support in the IAM Actions Reference.

Common Pitfalls

MistakeConsequenceFix
Skipping growpartresize2fs sees no new space to claimAlways run growpart first if a partition exists
Using resize2fs on XFSCommand fails — wrong toolUse xfs_growfs with mount point
Proceeding while volume is in modifying stateOS may not see new size yetWait for optimizing state
No snapshot before resizeNo rollback path if something goes wrongAlways snapshot before modifying production volumes

Pre-Resize Snapshot (Recommended)

Before any volume modification on production, create a snapshot as a safety net:

aws ec2 create-snapshot \
  --volume-id vol-0abc1234def567890 \
  --description "Pre-resize snapshot $(date +%Y-%m-%d)" \
  --region us-east-1

Glossary

TermDefinition
EBS ModifyVolumeAWS API call that changes the size, type, or IOPS of an EBS volume without detaching it.
growpartLinux utility that extends a partition to fill available unallocated space on a block device.
resize2fsext2/ext3/ext4 file system resize utility; supports online (live) resizing for mounted volumes.
xfs_growfsXFS utility to expand a mounted XFS file system to fill its underlying partition.
Optimizing StateEBS volume modification state indicating the new size is available to the OS, though background optimization continues.

Next Steps

  • Set up a CloudWatch alarm on the disk_used_percent metric (via CloudWatch Agent) to alert before you hit capacity again.
  • Consider gp3 volumes over gp2 — they offer independent IOPS/throughput scaling and are generally more cost-effective. Always verify current pricing at the AWS EBS Pricing page.
  • Review the official AWS guide: Extend a Linux file system after resizing a volume.

Related Posts

Comments

Popular posts from this blog

EC2 No Internet Access in Custom VPC: Attaching an Internet Gateway and Fixing Route Tables

EC2 SSH Connection Timeout: The Exact Security Group Rules You Need to Fix It

IAM User vs. IAM Role: Why Your EC2 Instance Should Never Use a User