I created AWS infrastructure with Terraform. The EC2 instances cannot access the Internet unless they or their subnets have a public IP address assigned directly to them. The public subnet is associated with a route table which has a route to the IGW for 0.0.0.0/0 The private subnet is associated with a different route table which has a route to the NAT Gateway for 0.0.0.0/0
I am using user data to install nginx on the EC2 instances, it fails because the instances do not have Internet access. The infrastructure also has a load balancer to route traffic on port 80 to the instances on the public subnet.
If I add map_public_ip_on_launch = true to the public subnets then they get Internet access. Isn't the purpose of the IGW and NAT GW to provide Internet access without having to assign public IPs? The NAT GW has a public IP of course. NACL and SG allow all outbound traffic.
An instance can obtain access to the Internet:
Based on the fact that you say it works when assigning a Public IP address, it would appear that you are launching the instances in a public subnet.