After migrating my physical server to AWS recently I needed to shrink the boot volume a bit. The original server’s drive was ~1TB, so that’s the size my boot EBS volume was after the migration, but since I only have about 125GB of used space I wanted to reduce the overall volume size to about 150GB. Not surprisingly AWS doesn’t provide a native way to do this so I had to get creative. I found most of the steps on the AWS Developer Forum and have adapted them to my needs, along with adding a few. And just like with the physical server-to-cloud migration we’ll do here what many say can’t be done….
Step 1 – Create Snapshot of Volume
Using the AWS Console or AWS CLI create a snapshot of the volume you want to reduce, or an AMI of the instance. This will protect you in case something goes off the rails, making it quick and easy to recover.
aws ec2 create-snapshot --volume-id vol-1234567890abcdef0 --description "Snapshot of my root volume."
Step 2 – Shrink Volume
On the server in Disk Management, right-click the volume and select Shrink Volume. Select the desired size and let it run. Depending on a variety of factors this could take a while (several minutes to an hour or so) so be patient.
Step 3 – Stop Server and Detach Volume
When the volume shrink completes, stop (power off) the server. Preferably from within Windows, or use the AWS console or AWS CLI to do so. Then, detach the volume from the Windows server:
aws ec2 detach-volume --volume-id vol-1234567890abcdef0
Step 4 – Start Ubuntu EC2 Instance, Attach Volumes
Select the appropriate Ubuntu AMI (version and region) and launch it. Either through the web console or AWS CLI.
aws ec2 run instances --image-id-<AMI ID> --key-name <key> --count 1 --instance-type m1.large --security-group-ids sg-<SecGroup> --placement AvailabilityZone=<AZ>
Create a new EBS volume the size you want, making it at least the same size or larger than the shrunk volume size. Attach the volume you want to clone to the Ubuntu instance and choose a mount point. For this document we will use “sdo”. “o” for Original (Note “sdo” in the AWS interface gets remapped to “xvdo” in ubuntu). Attach the new volume you want to clone to to the Ubuntu instance and choose a mount point. We will use “sdn”. “n” for New. (Note “sdn” in the AWS interface gets remapped to “xvdn” in Ubuntu).
aws ec2 create-volume --size 150 --region <region%gt; --availability-zone <AZ> --volume-type gp2
aws ec2 attach-volume --volume-id vol-1234567890abcdef0 --instance-id i-01474ef662b89480 --device /dev/sdo
aws ec2 attach-volume --volume-id vol-1234567890abcdef1 --instance-id i-01474ef662b89480 --device /dev/sdn
Step 5 – Connect to Ubuntu, Run Commands
Connect to the Ubuntu instance and elevate yourself to SU with sudo su.
View and Save partition information for the “original” disk:
fdisk -l -u /dev/xvdo
Setup partitions for the “new” disk:
fdisk /dev/xvdn
At the prompt (Command (m for help):
“n” to create a new partition
“p” to make it a primary partition
Select a partition number (match the original setup)
Enter the first sector (match the original setup)
Enter the last sector (for first partition match the original, for a second, use the default last sector)
“t” to set the partition type to 7 (HPFS/NTFS/exFAT) on all partitions
Repeat the above process for all needed partitions
“a” to set the boot flag on partition 1
“p” to review the setup
“w” to write changes to disk and exit
Run the following to verify settings on both “old” and “new” drives:
fdisk -l -u /dev/xvdo
fdisk -l -u /dev/xvdn
Copy the MBR (Master Boot Record). The MBR is on the first sector of the disk, and is split into three parts: Boot Code (446 bytes), Partition Table (64 bytes), Boot Code Signature = 55aa (2 bytes). We only want the boot code, and will copy it with the the “dd” command to do a direct bit copy from disk to disk:
dd if=/dev/xvdo of=/dev/xvdn bs=446 count=1
Clone the NTFS file system one partition at a time (/dev/xvdo1, /dev/svdo2):
ntfsclone --overwrite /dev/xvdn1 /dev/xvdo1
ntfsclone --overwrite /dev/xvdn2 /dev/xvdo2
Step 6 – Detach from Ubuntu, Attach to Windows
Detach both volumes from Ubuntu instance and attach new volume to Windows instance as device /dev/sda1:
aws ec2 detach-volume --volume-id vol-1234567890abcdef0
aws ec2 detach-volume --volume-id vol-1234567890abcdef1
aws ec2 attach-volume --volume-id vol-1234567890abcdef1 --instance-id i-01474ef662b8948a --device /dev/sda1
Step 7 – Verify and Cleanup
Start the Windows instance:
aws ec2 start-instances --instance-ids i-1234567890abcdef0
Note: it may take several minutes to start the instance, so don’t be impatient or alarmed….. Once the instance starts, logon to the Windows instance, then run chkdsk to validate the drive and correct any errors:
chkdsk c: /f
Terminate Ubuntu instance:
aws ec2 terminate-instances --instance-ids i-1234567890abcdef0
Finally, as good measure make an AMI of your instance or Snapshot of the volume.