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
- Create a new ec2 instance, B, with the same OS as the instance A. As storage, pick a volume that's the same type as VA, but with a size of 10GB. (or whatever your target size is). So now we have an instance B which uses this new volume (let's call it VB) as a root volume.
- Once the new instance (B) is running. Stop it and detach it's root volume (VB).
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
- Format VB's main partition with an ext4 filesystem:
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:
/dev/xvdf1 does not exist for whatever reason, you need to create it. First enter:
sudo fdisk /dev/xvdf.
ii) Wipe disk by entering:
iii) Create a new partition by entering:
p to create primary partition
v) 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:
You should see something like:
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
xvda 202:0 0 250G 0 disk
└─xvda1 202:1 0 250G 0 part
xvdf 202:80 0 80G 0 disk
└─xvdf1 202:81 0 80G 0 part
xvdg 202:96 0 250G 0 disk
└─xvdg1 202:97 0 250G 0 part
Now proceed to Step 11.
- Mount it to this directory:
mount -t ext4 /dev/xvdf1 /target
- This is very important, the file system needs an e2label for Linux to recognize it and boot it, use "e2label /dev/xvda1" on an active instance to see what it should be, in this case the label is: "/"
e2label /dev/xvdf1 /
- Mount VASNAP on /source:
mount -t ext4 /dev/xvdg1 /source
- Copy the contents:
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 VB:
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.