How to Reduce EC2 Root Volume Size

Posted By : Tarun Singhal | 25-Apr-2018

 

Before starting, I must mention that reduction of EBS volume size is not officially supported by AWS. This is apparent from the fact that you can only increase the size of the EBS volume using the AWS console/API and not decrease it. This is due to the fact that reducing the volume size can lead to data corruption or perhaps, data loss. Especially if the volume involved is a root volume, the impact can be pretty heavy.
Therefore, I advise to create an AMI of their instance first and test the suggested steps in a test environment and use the steps on the production instance only after successful implementation in the test instance.
Also, please know that the required steps can depend on the OS of the instance and the filesystem type used in the volume.

Described below is the procedure to reduce the root volume size (500 GB ; FileSystem - ext4) of an Amazon Linux instance to 100 GB (it should work on major Linux distro as well). Please know that the mentioned process involves an indirect method where the EBS volume’s size is itself not reduced. Rather, a new volume is created of the desired reduced size and this volume is configured to be the root volume using gdisk to reproduce the partition table, rsync to copy the OS, and a chroot environment to recreate grub and kernel information on the smaller volume. You can delete the original volume once you are satisfied with the new volume.
Please follow the steps below (Strongly recommended - Please ensure the you have created an AMI of your instance before proceeding with the below mentioned steps)-

  • Launch or obtain an existing Amazon Linux AMI instance using a 500GB root EBS volume, and then launch a temporary worker instance (referred to as i-worker) using that same Amazon Linux AMI. Create a 100GB EBS volume. Be sure all these resources are in the same AZ so that you can move volumes around.

  • Stop 500GB instance, detach root device, and attach to “i-worker” instance as /dev/sdf; attach 100GB volume as /dev/sdg

  • SSH into i-worker, change to root user (or perform all commands as sudoer), and print partition table for /dev/xvdf (/dev/sdf will be read by OS as /dev/xvdf): # ```

    gdisk -l /dev/xvdf 
    
  • Re-create this exact layout on /dev/xvdg:

    # gdisk /dev/xvdg 
    

    enter the following values: n (new partition) 128 (partition #) 2048 (sector start) [default] 4095 (sector end) ef02 (Code for BIOS Boot Partition) [enter] n [1] (partition # = 1) [default] [4096] (sector start 4096) [default] [enter] (last sector, takes up entire space) [default] [enter] (Code = 8300) [default - Linux filesystem] w (write) y (overwrite existing partitions)

  • Double check that it looks the same now: (end sector of partition 1 will differ, exact terminology in “Name” column might be slightly different)

    # gdisk -l /dev/xvdf 
    

    Number Start (sector) End (sector) Size Code Name 1 4096 1048575966 500.0 GiB 8300 Linux 128 2048 4095 1024.0 KiB EF02 BIOS Boot Partition
    .# gdisk -l /dev/xvdg Number Start (sector) End (sector) Size Code Name 1 4096 209715166 100.0 GiB 8300 Linux filesystem 128 2048 4095 1024.0 KiB EF02 BIOS boot partition

  • Create mount points for the 500GB and 100GB volumes, create filesystem on /dev/xvdg1, then mount:
    .# mkdir /old /new
    .# mkfs.ext4 /dev/xvdg1
    .# mount /dev/xvdf1 /old
    .# mount /dev/xvdg1 /new ’

  • rsync the OS from the 500GB (/old) to the 100GB (/new):

    # rsync -aAXv --exclude={"/dev/*","/proc/*","/sys/*","/tmp/*","/run/*","/mnt/*","/media/*","/lost+found","/old","/new"} /old/ /new 
    
  • Bindmount important directories to prepare the chroot environment:

    # for dir in {/dev,/dev/pts,/sys,/proc}; do mount -o bind $dir /new$dir; done 
    
  • chroot into the new 100GB mounted filesystem: # chroot /new /bin/bash 10. Back up the grub configuration:

    # cp /boot/grub/grub.conf ~/ 
    
  • Delete all the things:

    # rm -rf /boot/* 
    
  • Reinstall all the things (hangs for a few moments while performing SELinux relabeling):

    # yum reinstall grub kernel -y 
    
  • Reinstall grub twice to populate /boot/grub/device.map: (if you get strange messages and errors, keep going)

    # grub-install --recheck /dev/xvdg # grub-install --recheck /dev/xvdg 
    
  • Enter bootloader shell to configure grub:
    .# grub <== enter grub command-line shell device (hd0) /dev/xvdg <== define the new volume root (hd0,0) <== set GRUB’s root device to the partition that contains boot directory (counting starts at 0) setup (hd0) <== install GRUB boot loader on MBR of first drive (you’ll get failure notices, ignore these) quit

  • Rebuild the grub configuration from backup:

    # cat ~/grub.conf > /boot/grub/grub.conf 
    
  • Redo the menu.lst symlink:

    # ln -s /boot/grub/grub.conf /boot/grub/menu.lst 
    
  • Reinstall kernel:

    # yum reinstall kernel -y 
    
  • Relabel the new 100GB partition:

    # e2label /dev/xvdg1 / 
    
  • Ensure the initial RAMdisk and kernel version match the contents of /boot/grub/grub.conf:

    # cat /boot/grub/grub.conf 
    

    stat (copy-paste the filename for “kernel” in the grub.conf) # stat (copy-paste the filename for “initrd” in the grub.conf)

  • Exit chroot environment, get back to base root directory:

    # exit # cd 
    
  • Perform recursive unmounting: (alternatively, you can stop the “i-work” instance):

    # umount -R /new # umount -R /old (optional)
    
  • Detach /dev/xvdg (100GB) from your i-worker instance, re-attach to standard Amazon Linux instance as /dev/xvda

  • Start the original instance. Once the instance comes up fine, SSH into it and check for all the configuration/content and if you are satisfied, please feel free to delete the previous volume. Please have the above steps tested in your test instances. Should they not work for you, please let us know where exactly you are facing problem and the error you are encountering.

Lastly, please know that EBS size reduction is not officially supported by us and all these tasks fall in sys-admin domain. I hope this helps.

About Author

Author Image
Tarun Singhal

Tarun is a RedHat Certified System Administrator. He is very keen to learn new technologies. He has good command over tools like Ansible, Gitlab-CI etc.

Request for Proposal

Name is required

Comment is required

Sending message..