How to Resize an EBS Volume Without Downtime (Live File System Expansion)

Running out of disk space on a production EC2 instance is one of those operational emergencies that demands a zero-downtime solution. Resizing an EBS volume without downtime is fully supported on AWS — but the process has two distinct phases that engineers frequently conflate, leading to a volume that's larger on paper but still reports the same disk usage to the OS.

TL;DR: EBS Volume Resize Without Downtime

PhaseToolDowntime Required?What Changes
1. Modify VolumeAWS Console / CLI (modify-volume)NoEBS block device size increases
2. Extend Partitiongrowpart (if partitioned)NoPartition boundary expands to new size
3. Extend File Systemresize2fs / xfs_growfsNoOS-visible disk space increases

How EBS Volume Resizing Works

When you modify an EBS volume's size, AWS expands the underlying block device asynchronously. The volume transitions through states: modifying → optimizing → completed. The block device is available and writable throughout this process. However, the OS kernel, partition table, and file system are entirely unaware of the new size until you explicitly extend them. Think of it like extending a physical hard drive's platters — the drive is bigger, but the partition table still has a fence drawn at the old boundary, and the file system only manages space within that fence.

graph TD A["EC2 Instance Running"] --> B["AWS API: modify-volume"] B --> C["EBS Block Device Expands (modifying → completed)"] C --> D{"Partition Table Present?"} D -- "Yes (e.g. nvme0n1p1)" --> E["growpart Extend Partition"] D -- "No (raw device)" --> F["Skip growpart"] E --> G{"File System Type"} F --> G G -- "ext4" --> H["resize2fs /dev/nvme0n1p1"] G -- "XFS" --> I["xfs_growfs /mount/point"] H --> J["df -hT Shows New Size"] I --> J
  1. AWS EBS Layer: modify-volume expands the block device. The volume enters modifying state and becomes completed once the resize is done.
  2. Partition Layer: If the device has a partition table (e.g., /dev/xvda1 rather than raw /dev/xvda), growpart must extend the partition to consume the new space.
  3. File System Layer: resize2fs (ext4) or xfs_growfs (XFS) instructs the file system to expand into the now-available partition space. Both tools support online resize on a mounted file system.

Prerequisites: IAM Permissions for EBS Resize Without Downtime

The operator or automation role needs the following minimum permissions. Read/Describe actions require "Resource": "*" because they do not support resource-level restrictions in IAM. The mutating ec2:ModifyVolume action can be scoped to the specific volume ARN.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AllowModifySpecificVolume",
      "Effect": "Allow",
      "Action": "ec2:ModifyVolume",
      "Resource": "arn:aws:ec2:us-east-1:123456789012:volume/vol-0abcdef1234567890"
    },
    {
      "Sid": "AllowDescribeVolumes",
      "Effect": "Allow",
      "Action": [
        "ec2:DescribeVolumes",
        "ec2:DescribeVolumesModifications"
      ],
      "Resource": "*"
    }
  ]
}

Step 1: Identify the Volume and Current Disk State

Before touching anything, confirm which EBS volume backs the mount point you need to expand. A mismatch here means you resize the wrong volume — a silent failure that wastes time and leaves the problem unsolved.

On the EC2 instance, check current disk usage and device names:

# Check disk usage
df -hT

# List block devices and their mount points
lsblk

Note the device name (e.g., xvda, nvme0n1) and whether the mount point is on a raw device or a partition (e.g., nvme0n1p1). Then retrieve the EBS Volume ID from the instance metadata or the console:

aws ec2 describe-volumes \
  --filters Name=attachment.instance-id,Values=i-0abcdef1234567890 \
  --query 'Volumes[*].{VolumeId:VolumeId,Size:Size,Device:Attachments[0].Device,State:State}' \
  --output table

Step 2: Modify the EBS Volume Size

With the Volume ID confirmed, issue the resize. This is the AWS-side operation — it does not touch the instance OS at all. You can increase size but not decrease it; EBS volume size changes are one-directional.

aws ec2 modify-volume \
  --volume-id vol-0abcdef1234567890 \
  --size 100

Replace 100 with your target size in GiB. The command returns immediately; the actual resize happens asynchronously.

Poll the modification state until it reaches completed:

aws ec2 describe-volumes-modifications \
  --volume-ids vol-0abcdef1234567890 \
  --query 'VolumesModifications[*].{VolumeId:VolumeId,State:ModificationState,Progress:Progress}' \
  --output table

Do not proceed to the OS-level steps until ModificationState shows optimizing or completed. The block device size is reflected to the OS once the state leaves modifying.

Step 3: Extend the Partition (If Applicable) — EBS Resize Without Downtime

This is the step most runbooks skip, and it's the reason engineers see a larger block device in lsblk but no change in df. If your device has a partition (confirmed by lsblk showing a child device like nvme0n1p1), the partition boundary must be extended before the file system can see the new space.

On Amazon Linux 2 and most modern AMIs, growpart is available by default:

# Syntax: growpart  
growpart /dev/nvme0n1 1

If the root device is /dev/xvda with partition /dev/xvda1:

growpart /dev/xvda 1

A successful run outputs CHANGED: partition=1 start=... old: size=... end=... new: size=... end=.... If it outputs NOCHANGE, the partition already spans the full device — skip to Step 4.

Step 4: Extend the File System

The file system is the final layer. The correct tool depends on the file system type — using the wrong one fails silently or errors out without expanding anything. Check the type first:

df -hT

The Type column shows ext4, xfs, or another type. Then apply the appropriate command:

For ext4:

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

For XFS:

# xfs_growfs takes the mount point, not the device
xfs_growfs /
XFS requires the mount point as its argument, not the device path. Passing the device path to xfs_growfs will fail with an error. This trips up engineers who are used to resize2fs syntax.

Verify the expansion succeeded:

df -hT

The available space under the target mount point should now reflect the new volume size.

Experience Signal: The "Volume Shows Completed But df Hasn't Changed" Trap

A common incident pattern: an engineer runs modify-volume, waits for completed state, then checks df -h and sees no change. The immediate assumption is that the AWS API call failed or the change hasn't propagated. The actual cause is almost always a missed partition extension step.

The tell is in lsblk output. If the block device (nvme0n1) shows the new size but the partition (nvme0n1p1) still shows the old size, the partition table was never updated. df reports file system space, which is bounded by the partition, not the raw device. Running growpart followed by resize2fs or xfs_growfs resolves it immediately without any restart.

The misdiagnosis — assuming the AWS-side resize failed — leads engineers to re-run modify-volume, which returns an error because a modification is already in progress or completed. The real fix was always one layer below.

graph TD A["df shows old size after modify-volume"] --> B["Check lsblk"] B --> C{"Device shows new size?"} C -- "No" --> D["EBS modification not yet completed Wait for ModificationState: completed"] C -- "Yes" --> E{"Partition shows new size?"} E -- "No" --> F["Run growpart growpart /dev/nvme0n1 1"] F --> G{"File system type?"} E -- "Yes" --> G G -- "ext4" --> H["resize2fs /dev/nvme0n1p1"] G -- "XFS" --> I["xfs_growfs /"] H --> J["df -hT confirms new size"] I --> J
  1. lsblk shows new size on device, old size on partition: growpart was skipped. Run it now.
  2. lsblk shows new size on partition, df shows old size: File system extension was skipped. Run resize2fs or xfs_growfs.
  3. lsblk shows old size on device: The EBS modification has not completed yet. Wait for ModificationState: completed.

Full End-to-End CLI Walkthrough

🔽 Click to expand: Complete resize sequence (Amazon Linux 2, ext4, nvme device)
# --- On the EC2 instance ---
# 1. Confirm current state
df -hT
lsblk

# --- From your workstation or CI/CD pipeline ---
# 2. Resize the EBS volume to 100 GiB
aws ec2 modify-volume \
  --volume-id vol-0abcdef1234567890 \
  --size 100

# 3. Wait for modification to complete
aws ec2 describe-volumes-modifications \
  --volume-ids vol-0abcdef1234567890 \
  --query 'VolumesModifications[*].{State:ModificationState,Progress:Progress}' \
  --output table

# --- Back on the EC2 instance ---
# 4. Extend the partition (partition 1 on nvme0n1)
growpart /dev/nvme0n1 1

# 5. Extend the ext4 file system
resize2fs /dev/nvme0n1p1

# 6. Verify
df -hT

Wrap-Up: EBS Volume Resize Without Downtime — Next Steps

Resizing an EBS volume without downtime is a three-layer operation: AWS block device, OS partition table, and file system. Skipping any layer leaves the expansion incomplete. For recurring disk pressure, consider setting a CloudWatch alarm on disk_used_percent via the CloudWatch Agent to catch capacity issues before they become incidents.

For further reading, refer to the AWS documentation on extending a Linux file system after resizing a volume.

Glossary

TermDefinition
EBS VolumeA persistent block storage device that can be attached to an EC2 instance, independent of the instance lifecycle.
growpartA Linux utility that extends a partition to fill available space on a block device without unmounting.
resize2fsAn ext2/ext3/ext4 file system resize tool that supports online (live) expansion of mounted file systems.
xfs_growfsAn XFS utility that expands a mounted XFS file system to fill its underlying partition or volume.
ModificationStateThe EBS volume modification lifecycle state: modifyingoptimizingcompleted.

Related Posts

Comments

Popular posts from this blog

EC2 No Internet Access in Custom VPC: Fix Internet Gateway and Route Table

EC2 SSH Connection Timeout: Which Security Group Rules to Check

Difference Between IAM User and IAM Role: Which One Should Your EC2 Use?