Ok, so your disk is indeed 20GB large, so that worked fine.
Unlike with containers, all LXD can do is grow your disk and partition table, it can’t do the partition resizing for you.
You can use something like growpart (cloud-guest-utils package) to grow your /dev/sda2 to fill the partition table, then reboot and extend the filesystem to match.
That’s something like growpart /dev/sda 2 and after reboot resize2fs /dev/sda2
Note that the cloud images will do that automatically for you during boot.
So using images:ubuntu/focal/cloud which comes with cloud-init and growpart should boot with the full 20GB, while images:ubuntu/focal which does not, will boot with the default 4GB and require you to handle growing it.
Because the logic that brings it in (cloud-init) is quite large, that’s why we have the separate cloud image.
Also, not everyone wants this behavior. If you want to actually partition things to have multiple partitions, having it auto-grow on you at boot is a bit unfortunate.