A detailed look at the AWS VPC

What is the Virtual Private Cloud (VPC)

A VPC is a logically isolated area of the AWS infrastructure in which you can define your own network configuration (IP ranges, subnets, route tables & network gateways) & launch your AWS resources into an area, over which you have complete control – it’s intended to resemble your private on-premise data centre.

A VPC can be launched into a specific region. You can then place subnets in different availability zones within that region, within the VPC. This enables you to create fault tolerant and highly available applications and services by straddling multiple availability zones and/or regions.

Where does VPC fit in your environment?

The VPC encapsulates many of the core resources within AWS. As is shown on the diagram below, it contains your virtual servers; database servers; load balancers; app services; lambda and analytics services. Each of these will be discussed throughout the remainder of this book.

As previously mentioned, the VPC has its own network configuration (as defined by you) into which you can launch your AWS resources.

Access to the resources in the VPC is controlled by IAM (as discussed previously) in addition to network access control lists (NACL) and security groups which we will discuss in this section.

What are the components of a VPC?

The VPC has a number of components, those components have been outlined on the diagram at the beginning of the VPC section. Let’s step through each item, one at a time.

IGW (Internet Gateways)

Internet Gateways (IGW) are an integral part of the VPC. They provide your network with a route to the open internet (enabling websites to be accessed by users & instances to download updates).  They are horizontally scaled, redundant, highly available and don’t need to be managed. They’ll automatically scale to meet traffic requirements and will automatically be replaced if they fail.

The IGW has two main purposes. The first is to allow communication between the AWS resources within your VPC and the internet and the second is to perform NAT translation for instances that have a public IP address.

It’s important to note that only one IGW can be attached to a VPC at any given time and that you cannot detach an IGW from a VPC while there are active AWS resources within the VPC (e.g. EC2 Instances).

Route Tables

Route tables provide a set of rules (or routes) which direct traffic to the intended destination.

When a route table is connected to an Internet Gateway, it will have a rule defined in the rules tab which will explicitly refer to the IGW, which will enable internet access. If an IGW is detached from a VPC the route table will show a status of ‘black hole’ and your subnets attached to that route table will have no route to the internet .

The route table also enables you to configure routes between subnets (both public and private) within a VPC – these subnets must be in the same region but can be in different availability zones.

Note: you cannot delete a route table if it has any dependencies. This can include any Internet Gateways or subnets associated to the route table.

The below is an example of a route table. You’ll see that we have two records in place, each with two columns – destination and Target.


With the top line of the route table, you’ll notice that the target is local (we call this the ‘local route’). That means this is to be routed internally – between subnets within the VPC, this will not require access to the open internet. As such, the destination of this record is simply the CIDR block range of the VPC itself.

Side Note:

You cannot modify the ‘local route’

The second row will show the target as being the IGW (Internet Gateway), which indicates that this should be able to connect to the open internet – as would be required if you were hosting a website. The destination of means that it can go to any destination on the open web.

Best practice is to leave the default route table as it is. If any modifications are required, it’s better to create a new route table.

In many cases, you may choose to have a private and a public route table for your VPC. Both would have the same local route, meaning communication between subnets would be possible. However, the private subnet would be attached to a route table that was NOT attached to an internet gateway.

Note: you can have multiple route tables per VPC.


A subnet is a subsection of a network. In AWS, we can have multiple subnets within a single VPC and those subnets can span multiple availability zones. However, all subnets within a VPC must be in the same region.

When you first setup your AWS account, you’ll notice that you have a default VPC and a number of subnets (one for each availability zone within the region). Each of those subnets will be attached to an internet gateway and will be public subnets.

Each instance launched into the default VPC will have both a private and public subnet by default – this setting can be altered to suit your requirements.

Side Note:

A public subnet is defined as one that has a route to the internet. A private subnet is one that does not have a route to the internet. Both public and private subnets can communicate with other subnets within a VPC using the local route.

Private subnets can benefit from enhanced security as they’re not available to the open web. However, this can also mean that they’re unable to download and install software updates. This can be solved via the use of a NAT instance.

In order to make a subnet private, you’ll need to create a new route table that is NOT attached to an internet gateway (IGW) and associate a subnet with that table. Note that all subnets must be associated to a route table.

Subnet associations with a route table can be either explicit or non-explicit. No subnet is explicitly associated with the default route table – they’re non-explicitly associated until they’re explicitly associated with another (non-default) route table.

Network Access Control Lists (NACL)

Network Access Control Lists (NACL) are an optional layer of security which essentially act as a firewall for controlling traffic in or out of one or more subnets. It does this through the enforcement of traffic rules based on protocol. For example, you may wish to block all inbound HTTP traffic to your subnet.

To do this, we assign a rule number. The lower the number we assign, the higher priority that rule is given and once one rule is evaluated and executed, all following rules are ignored. So, let’s say we have the below rules:

Rule NumberProtocolSourceAllow / Deny

In this case, our HTTP traffic will come into the NACL. It’ll start evaluating the rules that it has and will first come across rule 90 and will allow the HTTP traffic to enter the subnet. Even though we have a deny rule below, it always executes the rule with the lowest rule number.

Remember, Network Access Control Lists are stateless. This means that traffic must be allowed in both inbound and outbound rules if a reply is to be required.

Side Note:

The default NACL in the default VPC will allow all traffic (both inbound & outbound) by default while any new NACL’s will deny all traffic by default. 

N.B. when the source is set to, it means rule will apply to all traffic sources.

Through the NACL interface in the AWS management console, we can associate subnets to the NACL. Remember, a subnet can be associated with one NACL at a time.

While the NACL enforces security at a subnet level, EC2 instances may also apply additional security at the security group level.

Security Groups

Security groups work on the instance level. They’re relatively similar to Network Access Control Lists in the sense that you can configure rules to allow certain types of traffic.

There are two noticeable differences between a NACL and a security group:

  • Security groups only support allow rules
  • Security groups are stateful
  • All rules are evaluated before a decision is made

What does it mean to be stateful? Well, let’s say you allow inbound SSH traffic to your instance and that traffic requires a response from your server but you do not have SSH allowed in the outbound rules of your security group – it will still allow you to send the response. This is not true with NACL’s.

VPC Limits

There are a number of limits placed on resources in AWS. These can be lifted by submitting a support request to AWS. However, by default, those limits are:

#VPC’s Per Region5
#Internet Gateways Per Region5
#Customer Gateways Per Region50
#VPN Connections Per Region50
#Route Tables Per Region200
#Entries Per Route Table50
#Elastic IP Addresses5
#Security Groups Per VPC500
#Rules Per Security Group50
#Security Groups Per Network Interface5

VPC Peering

VPC peering is the process of sharing internal resources of multiple VPC’s via private IP addresses. This can only happen between 2 VPC’s in the same region,

VPC’s can be peered when they’re part of different AWS accounts (as long as they’re in the same region).

Side Note:

To peer VPC’s they must have separate, non overlapping CIDR block ranges

Transitive connections are not permitted. This means, if VPC2 is connected to VPC1 and VPC1 is connected to VPC3 then VPC2 and VPC3 will be unable to communicate. They must have direct links.

When peering, you can choose to peer the entire VPC or just specific subnets within it.

Bastion Hosts & NAT Gateways

A bastion host is an EC2 instance that lives in a public subnet. It’s used as a gateway to access an instance in a private subnet.

The bastion host is the critical strong point of the network as all traffic must flow through it to reach its destination.

The NAT gateway works hand in hand with the bastion host. It provides those EC2 instances in the private subnet with a route to the internet and prevents hosts from outside the VPC making connection to those private instances associated with the NAT gateway.

The NAT Gateway only allows incoming traffic if it is responding to an outgoing message from the instance in a private subnet. The NAT Gateway must be part of the public subnet and must be associated with the private subnet route table.

Side Note:

A NAT instance has the same purpose as a NAT gateway, except it’s an actual EC2 instance rather than a managed service by AWS. The NAT gateway is a newer option & NAT instances are now considered to be legacy.

VPC Troubleshooting

EC2 instances aren’t being auto-assigned a public IPYou can check the auto-assign IP settings for the subnet. Here, you may find that it’s set to ‘disable’.
Nat gateway is configured but instances inside the private subnet cannot download packagesYou’ll need to add a route to the NAT gateway into the route table for the private subnet.
Traffic not reaching instancesEven if your security group allows the traffic, your NACL (Network Access Control List) may be blocking it. Check your NACL as the first step of troubleshooting.
Cannot SSH to resources in a private subnetYou’ll need to ensure that you’re utilizing a bastion host or VPN connectivity to be able to SSH to instances in a private subnet.
Unable to create VPC peeringThe two VPCs must be part of the same region in order for peering to work.