I solved this myself. This is what I had to do.
Create VPC (Virtual Private Cloud) subnet 172.31.0.0/16
Create an IGW (Internet Gateway)
Create a public subnet within the VPC subnet 172.31.100.0/24
Create a public route table that has a route 0.0.0.0/0 pointing to the IGW
Add the public subnet to the public route table. The public subnet should now also use the public route table.
Create EC2s without access from the Internet must be in a private subnet that does not have a route to the IGW
Create an EIP (Elastic IP)
Create a NAT (NAT Gateway) in the private subnet and associate the EIP
Create a private route table for the private subnet and add a route of 0.0.0.0/0 pointing to the NAT
The public and private subnets must both be within the VPC subnet but not overlapping.
The default GW from cloud-init now works for the EC2.
What is the VPC subnet route priority when two targets have the same default 0.0.0.0/0 route as the destination?Accepted Answerasked 2 years ago
Understanding route table to NAT GatewayAccepted Answerasked 2 years ago
The route for the VPC not showing in iproute2 when a subnet has different maskAccepted Answerasked 8 months ago
How Instances in Private subnet can connect to Internet with NAT InstanceAccepted Answerasked 2 months ago
VPC subnet routing.Accepted Answerasked 8 months ago
cloud-init not setting default route to NAT Gatewayasked 2 years ago
EC2 instance in private subnet shows IPv4 address of NAT instanceasked 3 years ago
Public ALB - NAT Gatewayasked 3 years ago
NAT gateway with outbound and inbound trafficasked a year ago
RouteTable requirementsAccepted Answerasked 3 years ago