A VPC is sealed until you give it a door. An internet gateway is that door: one per VPC, run by AWS, nothing to size or patch.
Creating and attaching it
IGW=$(aws ec2 create-internet-gateway --tag-specifications 'ResourceType=internet-gateway,Tags=[{Key=Name,Value=market}]' --query InternetGateway.InternetGatewayId --output text)aws ec2 attach-internet-gateway --internet-gateway-id $IGW --vpc-id $VPCAttached, the door exists, but no traffic goes through it yet: traffic only goes where a route sends it. In the market, the route goes in the public table, so point RT at it first: RT=$(aws ec2 describe-route-tables --filters Name=tag:Name,Values=public --query "RouteTables[0].RouteTableId" --output text).
The route
aws ec2 create-route --route-table-id $RT --destination-cidr-block 0.0.0.0/0 --gateway-id $IGW0.0.0.0/0 fixes no bits, so it matches every address. The table now reads:
| Destination | Target |
|---|---|
10.0.0.0/16 | local |
0.0.0.0/0 | the internet gateway |
The most specific match wins, so traffic for the VPC still stays inside and everything else goes out.
Every subnet that uses this table is now a public subnet. That is the whole definition: a route to an internet gateway. The private table gets no such route, and its subnets stay out of reach.