Amazon Web Services (AWS) makes it very easy to expand EBS volumes. You just right-click on the volume, select modify, and enter the new, larger volume size. Done. To shrink Amazon EBS volumes, however, is a whole different matter – there is no way to do this directly using the AWS console.
And if you made the mistake of allocating too much disk space to your EBS volume when originally setting up your Amazon EC2 instance, you would generally get stuck with an over-sized volume for which you will incur unnecessary month-to-month disk space charges.
In this article, I describe a roundabout technique that I have often used to save some bucks in scenarios where I mistakenly over-allocated Amazon EBS when setting up EC2.
What we will basically be doing is this: We will create a new, smaller EBS volume and then copy over the contents of the old over-sized volume. Then we will delete the old, over-sized volume and work with the new, small volume going forward.
RELATED READING: Swap File For Ubuntu On Amazon EC2 – Why And How?
This process could get tricky though, since most of the work will be done via the EC2 command line (or terminal). But if you follow the below steps carefully, you shouldn’t lose any data and you shouldn’t encounter any issues with EBS drives refusing to boot up.
Steps To Shrink Amazon EBS Volumes
Step 1: IMPORTANT: Stop your Amazon EC2 instance and take a snapshot of the current volume – the over-sized one that you’re looking to shrink. This is an important step because it is the only way to go back to your “last known good” state should something go terribly wrong.
Step 2: Now you need to create a new, smaller EBS volume. The size of this volume should be the size you want to shrink to.
Exactly how you create this volume will depend on if the volume you are trying to shrink is a root volume or not.
For a non-root volume: Just create the EBS volume directly from the AWS console by clicking “Create Volume”. Generally, I would probably recommend going the root volume route EVEN IF the volume you are creating will not be used as a root volume.
For a root volume: Create a new Amazon EC2 instance with the same operating system as the one on your existing instance. The EC2 instance creation process will ask you to add storage. Enter the volume size that you want to shrink to. When done, detach the volume from the instance and terminate the instance. Going this route saves you the stress of formatting the volume, creating partitions, marking the root flag, etc. If you are attempting to resize a root volume and don’t go this route, you will quite possible end up with an unbootable EC2 instance.
Step 3: Create another new Amazon EC2 instance with the same operating system as your existing instance. A micro or small instance should do. We only need this temporarily to run some commands.
Step 4: Detach the old, over-sized volume from its instance and attach it to the instance you created in step #3 above.
Mount the old volume as /dev/sdf/ (it will become /dev/xvdf).
Step 5: Mount the new, smaller volume (created in step #2) as /dev/sdg (it will become /dev/xvdg).
Step 6: Power on the new EC2 instance and SSH into it.
Step 7: Run this command:
sudo e2fsck -f /dev/xvdf1
Where “1” is the partition number you wish to resize. For simplicity, I’ll assume that you are not working with multiple partitions. So, just go ahead and run the command as is.
NOTE: Make sure that the xvdf1 is not mounted. Otherwise, you may run into errors. If for some weird reason xvdf1 is mounted (happened to me once), you may need to detach and reattach all 3 volumes on the instance. Technically, the only mounted volume should be the root volume that came with our new temporary EC2 instance.
Step 8: If the last command runs without errors, go ahead and run this command:
sudo resize2fs -M -p /dev/xvdf1
Step 9: The last line from the resize2fs command above will tell you how many 4k blocks are on your file system. Now, you need to calculate the number of 16MB blocks you need.
Use this formula:
blockcount * 4 / (16 * 1024)
Where blockcount is from the last line of the resize2fs command.
Round up this number to give yourself a small buffer. Save this result. We will use it soon.
Step 10: If you don’t yet have a partition on your new volume (/dev/xvdg1), use fdisk to create one.
NOTE: This step would only apply if you created a non-root volume in step #2 above. If you created a root volume, you can completely ignore this step and move on.
Step 11: Now run this command:
sudo dd bs=16M if=/dev/xvdf1 of=/dev/xvdg1 count=SavedResultFromPreviousStep
This may take a while to complete depending on how much data you have. This step performs the actual copying of data from the old, over-sized drive to the new, smaller drive.
Step 12: When the copy finishes, run the following two commands:
sudo resize2fs -p /dev/xvdg1 sudo e2fsck -f /dev/xvdg1
These commands will resize and check that everything is good with your new file system.
Step 13: If everything is good, shut down the temporary instance. Detach both the old and new volumes. Attach the new, small volume to your original EC2 instance. This time, mount the drive to your boot device (/dev/sda1).
Note: As pointed out by Adriaan van Wyk in the comments, AWS naming convention is different depending on AMI (see here). But it will usually be either /dev/sda1 or /dev/xvda. So, your small new volume might need to be mounted to /dev/xvda. Please confirm. Or you could just try /dev/sda1 first, and if it doesn’t work, try /dev/xvda next.
Step 14: Boot up your original EC2 instance and test that everything works well with the new, small volume.
Step 15: When you are satisfied that all is well, you may go ahead and delete all the unused artifacts – the new EC2 instance you created, the old, over-sized EBS volume, and the snapshot of the old volume.
Have you have ever had to shrink Amazon EBS volumes? Did this article help you accomplish that? Please feel free to share your experience or contributions using the comments section below.