I did this in my Amazon Lightsail vps in order to convert it over to using LVM. First, you have to disable the cloud-init package from automatically growing the partition on each boot. IIRC, you need to comment out or delete the lines in /etc/cloud/cloud.cfg that reference growpart and resizefs. Then you can add these two scripts:
#!/bin/sh
PREREQ=""
prereqs()
{
echo "$PREREQ"
}
case "${1:-}" in
prereqs)
prereqs
exit 0
;;
esac
. /usr/share/initramfs-tools/hook-functions
# copy the binary as early as possible
copy_exec /sbin/resize2fs /sbin
copy_exec /sbin/e2fsck /sbin
Put that in /etc/initramfs-tools/hooks/resize-hook
#!/bin/sh
PREREQ=""
prereqs()
{
echo "$PREREQ"
}
case $1 in
# get pre-requisites
prereqs)
prereqs
exit 0
;;
esac
e2fsck -fy /dev/sda1
resize2fs /dev/sda1 9g
Change the 9g to whatever size you want the fs shrunk to and put that in /etc/initramfs-tools/scripts/local-premount/resize. Don't forget to chmod the two scripts +x, and rebuild your initramfs with update-initramfs.
After you reboot, verify that the filesystem did get shrunk (df), use the resizepart command in parted to shrink the partition. It' a good idea to leave an extra gb or so in the partition to make sure you don't shrink the partition smaller than the filesystem, then run resize2fs on it later to expand it to fill the whole new partition size.
Also after you verify that the filesystem was shrunk, remove the two above scripts and rebuild your initramfs again.