How-To: Reduce the size of AWS EBS root volume

Amazon only allows increasing the size of their AWS EBS volumes. While unfortunate, we can sympathize with Amazon, they’re doing it for a good reason (let’s leave it at that).

So, if you have let’s say 100GB EBS volume attached to your EC2 and you’re only using 20 GBs, modifying the volume to anything lower than 100 GB will generate an error: The size of a volume can only be increased, not decreased.

This essentially means you’re stuck with a large volume, wasting resources and paying large bills. The following article is a walkthrough of the process of getting around this issue and reducing the size of Amazon EBS root volume.

Important

  • Before you follow any of the below steps, create an image backup of your AWS instance!
  • This is a sure way to protect yourself from any possible data loss.
  • By following this guide, you automatically agree that I cannot be held liable for any loss of data.

 

Step by Step process

Find the used space of your volume by issuing the: df -h command. In my case I am using only 16 GB (21%) of the provisioned 79 GB root volume:

Take a snapshot of the EBS volume in question, by opening AWS console and going to the Volumes section. Then select the volume, right-click and choose Create Snapshot:

Once completed, you’ll see a snapshot under the Snapshots menu:

Create a new EBS volume with the decreased size. In my case, I want to go from 80 to 25 GB (as I am only using 16 GB at the moment):

To do so, go to Volumes and click Create Volume, make sure to select encryption if your original volume was encrypted and also choose the same Availability Zone, in my case it needed to look like this:

It will only take a second to see the new volume created:

Now, we’ll have the original volume (I named it: joe0.com old volume) and we also have a new and available volume, which I called: joe0.com new volume:

Now, we need to attach the new volume to our instance.

In the Volumes menu, select the new volume and click Attach volume:

Follow through, by selecting your original instance and pressing Attach button:

Wait until the process of attaching a new volume is completed.

Now, login to your instance using SSH and list all attached volumes by using lsblk command.

The new shrunk volume is NVME SSD 1 drive 1 and marked as nvme1n1. This disk has no partitions yet.

Check whether the volume has any data or not using the command: sudo file -s /dev/nvme1n1

If it says: /dev/nvme1n1: data, the volume is empty and we can go ahead and format it.

Warning: If it says anything other than ‘/dev/nvme1n1: data‘ make sure that you DO NOT format the volume, as you’re probably looking at the wrong drive and you may compromise your system if you continue.

 

Now, let’s format the volume using the command sudo mkfs -t ext4 /dev/nvme1n1

Now we need to mount the new volume into the/mnt directory. Run this command:

sudo mkdir /mnt/new-volume .

And then mount the newly created volume into this directory. To do so, run the following command:

sudo mount /dev/nvme1n1/mnt/new-volume .

Then check volume by running the command df -h

As we can see, the new volume is mounted as /dev/nvme1n1 in the /mnt/new-volume directory.

Now we need to copy the data from the old volume to the new volume.

The best way to do this is by using RSYNC (a versatile file-copying tool).

Use this command to copy the files from the old to the new volume.

sudo rsync -axv / /mnt/new-volume/.

Note: The following step will take a while, so take your time and wait until it’s completed. It took about 20 minutes to copy my 25 GB volume.

 

Once the copying process is complete, we’ll need to prepare the new volume by installing a boot loader package from the GNU Project called: grub on our new volume.

We can do this by running the command sudo grub-install --root-directory=/mnt/new-volume/ /dev/nvme1n1.

The new volume is ready, thus, we can unmount the new-volume sudo umount /mnt/new-volume .

Now, we need to find the UUID of the original filesystem, we will do so, by using blkid, which is a command-line utility to locate/print block device attributes.

Just for reference, UUID is a universally unique identifier that is generally assigned to all computer systems.

So, let’s check UUID using the command sudo blkid :

Copy the UUID part somewhere and store it, we’ll need it soon.

Let’s unmount the new volume, run: sudo umount /mnt/new-volume/

Then let’s check the disk: sudo fsck -f /dev/nvme1n1

And once that is completed, we need to replace UUID on the new volume using the following command:

sudo tune2fs -U "SAVED_UUID" /dev/nvme1n1.

Here is what the outcome should look like:

Check the system label from old-volume using command sudo e2label /dev/nvme0n1p1 ; It will display string like / .

Then, replace the new volume label with the old volume label using the following command sudo e2label /dev/nvme1n1/  and you can log out of your Linux server.

Now we can stop our main instance:

Once the instance stopped, in the AWS console, visit Volumes and select the old volume and detach it.  Then also detach new volume.

Then attach the new volume:

And start your instance:

Once done, verify that your instance is working with the new downsized volume:

And that’s it, hopefully, this guide helped you to resize the disk and save on AWS cost.