When setting up an EC2 instance in a VPC with public subnet, verify these critical components:
# Sample AWS CLI commands to verify resources
aws ec2 describe-instances --instance-ids i-1234567890abcdef0
aws ec2 describe-network-interfaces --filters Name=attachment.instance-id,Values=i-1234567890abcdef0
aws ec2 describe-route-tables --filters Name=association.subnet-id,Values=subnet-12345678
The most frequent issues I've encountered:
- Missing Internet Gateway (IGW) attachment to VPC
- No default route (0.0.0.0/0) pointing to IGW in route table
- Subnet not associated with route table
- Incorrect network ACL rules blocking traffic
Use this diagnostic sequence:
# 1. Verify IGW attachment
aws ec2 describe-internet-gateways --filters Name=attachment.vpc-id,Values=vpc-12345678
# 2. Check route table configuration
aws ec2 describe-route-tables --filters Name=vpc-id,Values=vpc-12345678
# 3. Validate subnet association
aws ec2 describe-subnets --filters Name=vpc-id,Values=vpc-12345678
# 4. Verify security group rules
aws ec2 describe-security-groups --group-ids sg-12345678
Your public subnet's NACL should have these inbound rules at minimum:
Inbound Rules:
Rule # | Type | Protocol | Port Range | Source | Allow/Deny
100 | SSH (22) | TCP (6) | 22 | 0.0.0.0/0 | ALLOW
110 | All ICMP | ICMP (1) | N/A | 0.0.0.0/0 | ALLOW
* | All traffic| All | All | 0.0.0.0/0 | DENY
Outbound Rules:
Rule # | Type | Protocol | Port Range | Destination | Allow/Deny
100 | All traffic| All | All | 0.0.0.0/0 | ALLOW
If basic checks pass, try these techniques:
- Use VPC Flow Logs to inspect traffic:
aws ec2 create-flow-logs --resource-type VPC --resource-ids vpc-12345678 \\ --traffic-type ALL --log-group-name VPCFlowLogs
- Check instance system logs:
aws ec2 get-console-output --instance-id i-1234567890abcdef0
- Test from another instance in same VPC
Here's a Terraform snippet that creates a properly configured VPC setup:
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
}
resource "aws_internet_gateway" "gw" {
vpc_id = aws_vpc.main.id
}
resource "aws_subnet" "public" {
vpc_id = aws_vpc.main.id
cidr_block = "10.0.1.0/24"
map_public_ip_on_launch = true
}
resource "aws_route_table" "public" {
vpc_id = aws_vpc.main.id
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.gw.id
}
}
resource "aws_route_table_association" "public" {
subnet_id = aws_subnet.public.id
route_table_id = aws_route_table.public.id
}
resource "aws_security_group" "allow_ssh" {
name = "allow_ssh"
description = "Allow SSH inbound traffic"
vpc_id = aws_vpc.main.id
ingress {
description = "SSH from anywhere"
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
When setting up EC2 instances within a VPC, several architectural components must be properly configured for successful connectivity. The most frequent pain points include:
# Sample AWS CLI command to check instance status
aws ec2 describe-instances --instance-ids i-1234567890abcdef0 \
--query 'Reservations[].Instances[].{State:State.Name, VPC:VpcId, Subnet:SubnetId}'
The VPC's route table must have a default route (0.0.0.0/0) pointing to an Internet Gateway for public subnets. Verify with:
# Check route table configuration
aws ec2 describe-route-tables \
--filters "Name=vpc-id,Values=vpc-12345678" \
--query 'RouteTables[].Routes[]'
Beyond basic SSH (port 22) and ICMP rules, consider these often-missed configurations:
# Security group inbound rules JSON example
[
{
"IpProtocol": "tcp",
"FromPort": 22,
"ToPort": 22,
"IpRanges": [{"CidrIp": "0.0.0.0/0"}]
},
{
"IpProtocol": "icmp",
"FromPort": -1,
"ToPort": -1,
"IpRanges": [{"CidrIp": "0.0.0.0/0"}]
}
]
Network Access Control Lists operate at the subnet level and can override security group rules. They're stateless, requiring explicit inbound/outbound rules:
# Example NACL rules allowing SSH and ICMP
aws ec2 describe-network-acls \
--filters "Name=vpc-id,Values=vpc-12345678" \
--query 'NetworkAcls[].Entries[]'
Sometimes the issue lies within the instance itself. Verify:
- SSH daemon running (systemctl status sshd)
- Correct key pair association
- Instance profile permissions
- Operating system firewall (iptables/ufw)
When all else fails, these AWS tools can pinpoint issues:
# VPC Flow Logs analysis
aws ec2 create-flow-logs \
--resource-type VPC \
--resource-ids vpc-12345678 \
--traffic-type REJECT \
--log-group-name VPCRejectLogs