I was working on project using AWS and found out that EC2 instances with private subnets in VPC must have a “shadow” subnet with routing to the Internet gateway or else external LB will not be accessible.

First of all create your Internet Gateway and NAT Gateway under VPC, this is an important concept in AWS VPC; your IG gateway provides incoming connection while your NAT gateway provides outgoing connection.

My VPC subnet for example is ( then define your private subnets as:

Name Subnet Availability
subnet1-a zone a
subnet2-b zone b
subnet1-a-shadow zone a
subnet2-b-shadow zone b

Create your EC2 instances host1-a and host2-b under subnet subnet1-a and subnet1-b respectively, check that the create hosts are using the IP address correctly and you can access the Internet.

In your Route Table you should have 2 routes, the Main route should point to your NAT gateway so EC2 instances by default should have Internet access via the NAT gateway, I name this VPC-RT-NAT:

Destination Target local nat-08bbb950567fc5300>

Then the other route I named VPC-RT-PUBLIC points to my Internet Gateway

Destination Target local igw-5e67e11b

Now go back to your Subnets page under VPC Services and edit the route table for subnets subnet1-a-shadow and subnet2-b-shadow, change it to use VPC-RT-PUBLIC route table.

Next; on the EC2 Services; create new interfaces under Network Interfaces pages:

Network Interface Subnet ID Description
eni-3c6bc01a subnet1-a-shadow Shadow interface for host1-a
eni-3c6bc02b subnet2-b-shadow Shadow interface for host2-b

Attach these newly created interfaces to their respective EC2 instance hosts. Note that when you login into you hosts and use ifconfig -a command, the added interfaces will not assign the private IPs under these shadow subnets, only the IPs for subnet1-a and subnet2-b and this is normal – thats why we call them shadows.

Finally create your load balancer and select subnets subnet1-a-shadow and subnet2-b-shadow and after a few minutes when the DNS updates you should be able to ping and access your LB’s through its DNS name.