AWS Internet Gateway: The Bridge Between Your VPC and the Public Internet
An Internet Gateway (IGW) is the AWS-managed resource that connects your VPC to the public internet. Without one attached to your VPC — and without the correct route table entries pointing to it — no resource in your VPC can reach the internet, and no internet traffic can reach your VPC.
The IGW is horizontally scaled, redundant, and highly available within a region. You do not configure capacity or worry about bandwidth limits. AWS handles the underlying infrastructure.
What an IGW Actually Does
The IGW performs two functions:
Outbound NAT for EC2 instances with public IPs: When a packet leaves an EC2 instance with a public IP, the IGW translates the private source IP (e.g., 10.0.1.45) to the associated public IP (e.g., 54.123.45.67) before putting it on the internet.
Routing: It provides a target for route table entries. When a route table has 0.0.0.0/0 → igw-0abc123, traffic destined for the internet goes to the IGW.
EC2 instance private IP: 10.0.1.45EC2 instance public IP: 54.123.45.67 (Elastic IP or auto-assigned)
Outbound packet path: 10.0.1.45 → [IGW translates source to 54.123.45.67] → Internet
Inbound packet path: Internet → [IGW translates destination 54.123.45.67 to 10.0.1.45] → EC2There is no NAT for Elastic IPs — the public IP is one-to-one mapped at the IGW. For NAT Gateway (which shares one public IP across many private IPs), see the NAT Gateway article.
The Three Requirements for Internet Access
All three conditions must be met for an EC2 instance to communicate with the internet:
Requirement 1: Internet Gateway attached to the VPC aws ec2 attach-internet-gateway --vpc-id vpc-0abc --internet-gateway-id igw-0def
Requirement 2: Route table has 0.0.0.0/0 → IGW Destination Target 10.0.0.0/16 local 0.0.0.0/0 igw-0def ← this line must exist
Requirement 3: Instance has a public IP address Either auto-assigned on launch OR an Elastic IP associatedMissing any one of these three and the instance cannot reach the internet. This is the most common troubleshooting starting point.
Setting Up an Internet Gateway
# Create the VPCVPC_ID=$(aws ec2 create-vpc \ --cidr-block 10.0.0.0/16 \ --query 'Vpc.VpcId' --output text)
# Create the Internet GatewayIGW_ID=$(aws ec2 create-internet-gateway \ --query 'InternetGateway.InternetGatewayId' --output text)
# Attach IGW to VPC (one IGW per VPC maximum)aws ec2 attach-internet-gateway \ --internet-gateway-id $IGW_ID \ --vpc-id $VPC_ID
# Create a public subnetSUBNET_ID=$(aws ec2 create-subnet \ --vpc-id $VPC_ID \ --cidr-block 10.0.1.0/24 \ --availability-zone us-east-1a \ --query 'Subnet.SubnetId' --output text)
# Enable auto-assignment of public IPs for this subnetaws ec2 modify-subnet-attribute \ --subnet-id $SUBNET_ID \ --map-public-ip-on-launch
# Create route table with internet routeRTB_ID=$(aws ec2 create-route-table \ --vpc-id $VPC_ID \ --query 'RouteTable.RouteTableId' --output text)
aws ec2 create-route \ --route-table-id $RTB_ID \ --destination-cidr-block 0.0.0.0/0 \ --gateway-id $IGW_ID
# Associate route table with the subnetaws ec2 associate-route-table \ --subnet-id $SUBNET_ID \ --route-table-id $RTB_IDAt this point, any EC2 instance launched in this subnet with a public IP can reach the internet.
IGW and Elastic IPs
When you associate an Elastic IP with an EC2 instance, the IGW handles the mapping. The instance still only sees its private IP (10.0.1.45) when it checks its own network interface. The Elastic IP translation happens at the IGW, invisibly to the instance.
# Allocate an Elastic IPEIP_ALLOC=$(aws ec2 allocate-address \ --domain vpc \ --query 'AllocationId' --output text)
EIP=$(aws ec2 describe-addresses \ --allocation-ids $EIP_ALLOC \ --query 'Addresses[0].PublicIp' --output text)
# Associate with a running instanceaws ec2 associate-address \ --instance-id i-0abc123 \ --allocation-id $EIP_ALLOC
echo "Instance now reachable at: $EIP"If you check the instance’s network configuration from within the OS, you see only the private IP. The Elastic IP is entirely handled by the IGW.
One IGW Per VPC
Each VPC can have only one Internet Gateway attached. You cannot attach two IGWs for redundancy or extra throughput — the IGW is already internally redundant and scales automatically.
If you detach an IGW from a VPC, all internet connectivity from public subnets immediately stops. This is useful for incident response (to isolate a compromised environment) but irreversible while the IGW is detached.
IGW vs NAT Gateway: The Core Difference
┌───────────────────────────────────────────────────────────────┐│ IGW vs NAT Gateway Comparison ││ ││ Internet Gateway (IGW) NAT Gateway ││ ───────────────────────────────────────────────────────── ││ Supports inbound AND outbound Outbound ONLY ││ Instance needs a public IP No public IP on instances ││ One per VPC One per AZ (recommended) ││ Free Costs per hour + per GB ││ For public subnets For private subnets │└───────────────────────────────────────────────────────────────┘Public subnet resources (ALB, bastion hosts) use the IGW directly. Private subnet resources (application servers, databases) that need outbound internet access use a NAT Gateway, which itself connects through the IGW.
Traffic Flow Diagram
┌─────────────────────────────────────────────────────────────────┐│ Complete VPC Internet Flow ││ ││ Internet ││ │ ││ ▼ ││ Internet Gateway (IGW) ││ │ ││ ├── Public Subnet (10.0.1.0/24) ││ │ ├── ALB (gets internet traffic directly) ││ │ └── NAT Gateway (provides outbound for private) ││ │ │ ││ └── Private Subnet (10.0.11.0/24) ││ └── App Server ││ (outbound: App → NAT GW → IGW → Internet) ││ (inbound: Internet → IGW → ALB → App) │└─────────────────────────────────────────────────────────────────┘Application servers in private subnets never receive unsolicited inbound internet connections. All user traffic reaches them through the ALB, which is in the public subnet and directly connected to the IGW.
Troubleshooting Internet Connectivity
When an EC2 instance in a public subnet cannot reach the internet, check in this order:
- IGW attached:
aws ec2 describe-internet-gateways --filters Name=attachment.vpc-id,Values=vpc-0abc - Route exists:
aws ec2 describe-route-tables --filters Name=association.subnet-id,Values=subnet-0abc- Look for a route with destination
0.0.0.0/0targeting the IGW
- Look for a route with destination
- Public IP assigned: Check the instance details for PublicIpAddress — if it shows None, the instance has no public IP
- Security group outbound: The default allows all outbound, but a custom SG might block it
- NACL: Check for explicit deny rules on the subnet’s NACL
Use VPC Flow Logs to see whether traffic is being accepted or rejected:
aws ec2 create-flow-logs \ --resource-type Subnet \ --resource-ids $SUBNET_ID \ --traffic-type REJECT \ --log-destination-type cloud-watch-logs \ --log-group-name /vpc/rejected-flows \ --deliver-logs-permission-arn arn:aws:iam::123456789012:role/flow-logs-roleRejected traffic in the flow logs points to a security group or NACL block. Missing traffic entirely suggests a routing problem.
Common Interview Questions
Q: Can you attach an IGW to more than one VPC? No. An Internet Gateway can only be attached to one VPC at a time. You can detach and reattach to a different VPC, but you cannot serve multiple VPCs simultaneously.
Q: Does an instance in a private subnet with NAT Gateway also need an IGW?
Yes, but indirectly. The NAT Gateway is in a public subnet, and the public subnet’s route table points 0.0.0.0/0 to the IGW. The NAT Gateway routes traffic through the IGW on behalf of private subnet instances.
Q: What happens if you delete the IGW while instances are using it? First, you must detach it from the VPC before you can delete it. Once detached, internet connectivity stops immediately for all public subnet resources. Existing TCP connections that survive the loss of internet access fail; any new outbound or inbound connections fail.
Q: How do you allow a specific EC2 instance to receive SSH from only your IP? Security group inbound rule: TCP port 22, source = your public IP/32. This works through the IGW — your SSH client connects to the instance’s public IP, the IGW translates it to the private IP, and the security group allows the specific source.