In a previous article I described how to run an EBS boot AMI with a larger root disk size than the default. That’s fine if you know the size you want before running the instance, but what if you have an EC2 instance already running and you need to increase the size of its root disk without running a different instance?
As long as you are ok with a little down time on the EC2 instance (few minutes), it is possible to change out the root EBS volume with a larger copy, without needing to start a new instance.
Let’s walk through the steps on a sample Ubuntu 9.10 Karmic EBS boot instance. I tested this with ami-6743ae0e but check Alestic.com for the latest AMI ids.
On the instance we check the initial size of the root file system (15 GB):
$ df -h /
Filesystem Size Used Avail Use% Mounted on
/dev/sda1 15G 675M 14G 5% /
The following commands are all run on a system other than the one we are resizing. Pick a new size (in GB) that is larger than the current size:
instanceid=<YOURINSTANCEID>
size=20
Get the root EBS volume id and availability zone for this instance:
oldvolumeid=$(ec2-describe-instances $instanceid |
egrep "^BLOCKDEVICE./dev/sda1" | cut -f3)
zone=$(ec2-describe-instances $instanceid | egrep ^INSTANCE | cut -f12)
echo "instance $instanceid in $zone with original volume $oldvolumeid"
Stop (not terminate!) the instance:
ec2-stop-instances $instanceid
Detach the original volume from the instance:
while ! ec2-detach-volume $oldvolumeid; do sleep 1; done
Create a snapshot of the original volume:
snapshotid=$(ec2-create-snapshot $oldvolumeid | cut -f2)
while ec2-describe-snapshots $snapshotid | grep -q pending; do sleep 1; done
echo "snapshot: $snapshotid"
Create a new volume from the snapshot, specifying a larger size:
newvolumeid=$(ec2-create-volume --availability-zone $zone --size $size --snapshot $snapshotid |
cut -f2)
echo "new volume: $newvolumeid"
Attach the new volume to the instance:
ec2-attach-volume --instance $instanceid --device /dev/sda1 $newvolumeid
while ! ec2-describe-volumes $newvolumeid | grep -q attached; do sleep 1; done
Start the instance and find its new public IP address/hostname. (If you were using an elastic IP address, re-assign it to the instance.)
ec2-start-instances $instanceid
while ! ec2-describe-instances $instanceid | grep -q running; do sleep 1; done
ec2-describe-instances $instanceid
Connect to the instance with ssh (not shown) and resize the root file system to fill the new EBS volume. This step is done automatically at boot time on modern Ubuntu AMIs:
# ext3 root file system (most common)
sudo resize2fs /dev/sda1
#(OR)
sudo resize2fs /dev/xvda1
# XFS root file system (less common):
sudo apt-get update && sudo apt-get install -y xfsprogs
sudo xfs_growfs /
Show that the root file system is the new, larger size (20 GB):
$ df -h /
Filesystem Size Used Avail Use% Mounted on
/dev/sda1 20G 679M 19G 4% /
Delete the old EBS volume and snapshot if you no longer need them, though I recommend you at least keep the snapshot for a while just in case:
ec2-delete-volume $oldvolumeid
ec2-delete-snapshot $snapshotid
Note: Since you manually created the new volume and attached it to the instance yourself, it will not be deleted automatically when the instance is terminated. You can modify the instance attributes to change the delete-on-termination flag for the volume if you wish.
[Update 2011-11-21: Note that the resize2fs step is done automatically on modern Ubuntu AMIs.]
[Update 2011-11-21: Modern Ubuntu AMIs now call it /dev/xvda1 instead of /dev/sda1]