Enlarging an EC2 instance is easy like a breath (for instance, create an AMI, launch an instance from it and then change the storage size).
But reducing it becomes more difficult. I’d like to reduce an Amazon Web Services (AWS) EC2 instance Elastic Block Store (EBS) root volume size. There are a couples of old high level procedures on the net. The more detailed version I found is a one year old answer on a StackOverflow question: how to can i reduce my ebs volume capacity, steps have a pretty high level:
Create a new EBS volume that is the desired size (e.g. /dev/xvdg)
Launch an instance, and attach both EBS volumes to it
Check the file system (of the original root volume): (e.g.) e2fsck -f /dev/xvda1
Maximally shrink the original root volume: (e.g. ext2/3/4) resize2fs -M -p /dev/xvda1
Copy the data over with dd:
Choose a chunk size (I like 16MB)
Calculate the number of chunks (using the number of blocks from the resize2fs output): blocks*4/(chunk_size_in_mb*1024) – round up a bit for safety
Copy the data: (e.g.) dd if=/dev/xvda1 ibs=16M of=/dev/xvdg obs=16M count=80
Resize the filesystem on the new (smaller) EBS volume: (e.g.) resize2fs -p /dev/xvdg
Check the file system (of the original root volume): (e.g.) e2fsck -f /dev/xvdg
Detach your new EBS root volume, and attach it to your original instance
I’m unable to find a detailed step by step “how to” solution.
My EBS root volume is attached to a HVM Ubuntu instance.
Any help would be really appreciated.
Best Answer
None of the other solutions will work if the volume is used as a root (bootable) device.
The newly created disk is missing the boot partition, so it would need to have GRUB installed and some flags set up correctly before an instance can use it as a root volume.
My (as of today, working) solution for shrinking a root volume is:
Background: We have an instance A, whose root volume we want to shrink. Let's call this volume VA. We want to shrink VA from 30GB to let's say 10GB
NOTE: The following steps are mostly taken from @bill 's solution:
Stop the instance you want to resize (A).
Create a snapshot of the volume VA and then create a "General Purpose SSD" volume from that snapshot. This volume we'll call it VASNAP.
Spin a new instance with amazon Linux, we'll call this instance C. We will just use this instance to copy the contents of VASNAP to VB. We could probably also use instance A to do these steps, but I prefer to do it in an independent machine.
Attach the following volumes to instance C. /dev/xvdf for VB. /dev/xvdg for VASNAP.
Reboot instance C.
Log onto instance C via SSH.
Create these new directories:
mkdir /source /target
mkfs.ext4 /dev/xvdf1
If you get no errors, proceed to Step 11. Otherwise, if you do not have
/dev/xvdf1
, you need to create the partition by doing the following i-vii:i) If
/dev/xvdf1
does not exist for whatever reason, you need to create it. First enter:sudo fdisk /dev/xvdf
.ii) Wipe disk by entering:
wipefs
iii) Create a new partition by entering:
n
iv) Enter
p
to create primary partitionv) Keep pressing enter to continue with default settings.
vi) When it asks for a command again, enter
w
to write changes and quit.vii) Verify you have the
/dev/xvdf1
partition by doing:lsblk
You should see something like:
Now proceed to Step 11.
mount -t ext4 /dev/xvdf1 /target
e2label /dev/xvdf1 /
mount -t ext4 /dev/xvdg1 /source
rsync -vaxSHAX /source/ /target
Note: there is no "/" following "/target". Also, there may be a few errors about symlinks and attrs, but the resize was still successful
umount /target
Back in AWS Console: Dettach VB from instance C, and also dettach VA from A.
Attach the new sized volume (VB) to the instance as: "/dev/xvda"
Boot instance A, now it's root device is 10GB :)
Delete both instances B and C, and also all volumes but VB, which is now instance A's root volume.