Skip to content

What is a Virtual Private Cloud (VPC)? Part 2

Part 2 of 2: Routing & Gateways

In the first part of this blog, we talked about what exactly an AWS VPC is, and how the underlying network addressing is represented and defined. It covered the first two bullet points in this list of VPC Components:

VPC Components

  • The classless inter-domain routing (CIDR) Block
  • Subnets
  • Routing
  • Gateways

In Part 2, we will cover the last two bullet points, which describe how these networks pass information internally and externally.

Routey McRouteface

As mentioned in Part 1, in order for traffic to get to different places (inside and outside) of these subnets and networks, it needs to know how to get where it’s going. That’s where routing - and specifically route tables - comes in. In an AWS VPC, your subnets will all be assigned to a route table: either one you create, or the default table (called Main)  that is generated when you create the VPC.

Let’s say you have a VPC with three subnets:

  1. PublicSubnet1 -
  2. PrivateSubnet1 -
  3. IsolatedSubnet1 -

As we said, for each subnet, there will be a route table associated. There will be an entry in this table for each network for which traffic might be destined.

Public Subnets

For example, PublicSubnet1’s routing table may look like this:

| Destination  | Target        |
| ------------ | ------------- |
|  | Local         |
|    | igw-123456789 |

In this example, the first row of this table is defined like this:     Local

This is telling the subnet that any interfaces associated with it should send traffic destined for the network over the local route. This local route is the default for the interfaces and addresses that are local to the VPC. It is added to all route tables by default and is what ensures that all subnets within the VPC can talk to each other.

The second row of the table is this:       igw-123456789

This is the route that tells the public subnet resources (those that have a public IP address assigned) how to get to the internet. As we mentioned before, for the public subnet, traffic destined for the internet should be sent through an internet gateway, which simply is the bridge between the public interfaces in your VPC network and the public addresses of the internet.

Private Subnets

Private subnets, on the other hand, are handled in a similar way, but the big caveat here is resources here don’t get public IP addresses, so they can’t send traffic through an internet gateway. They have to use a NAT device, which is either a NAT Gateway (an AWS-managed resource) or a NAT instance (an instance you manage yourself). In most cases, you’ll probably use a NAT Gateway, as it removes the need to manage that portion of your infrastructure, but you can use NAT instances if you prefer. In either case, this is a resource that will act as the gateway for internet-bound traffic for your private subnets. They are created in public subnets and get IP addresses, which will end up being the NAT address for resources in your private subnets.

Let’s look at what PrivateSubnet1’s routing table would be, as an example:

| Destination  | Target        |
| ------------ | ------------- |
|  | Local         |
|    | nat-123456789 |

You may be saying to yourself, “Self, that’s almost identical to the public subnet route table!” And you’d be right. It is almost identical. The route for local traffic is the same because, as we discussed, all subnets in a VPC can talk to each other by default. But, the route for the internet is different because of the NAT stuff we talked about earlier. That route is just saying send all traffic destined for the internet through that gateway/instance.

The big thing to know here is that, although resources in your private subnets can initiate outbound connections to the internet (assuming they are set up with route tables similar to the above), they can’t receive internet traffic directly. An example of this would be a web server or app server running in a private subnet. It’s a good idea to run those types of resources in a private subnet because it helps reduce their exposure to the wild and all of the unsavory things that happen there.

But, if your web or app server can’t receive internet traffic, how is it supposed to serve… internet traffic…?! In these cases, we’d put an AWS service-based resource - like an ELB (Elastic Load Balancer) in our public subnet, and have it be the ingress point into your application. This allows you to offload some of the operational and security load of your architecture per the AWS Shared Responsibility Model. You still need to configure things in a secure way (SSL, IAM policies, etc.), but you can shift your instances and such back a layer to private subnets so the only way to get to them is through another AWS managed service that is configured in the public subnets.

Isolated Subnets

The third type of subnet we listed above were Isolated subnets. These are a lot like Private subnets, but for resources whose traffic should not have access to the internet. These subnets are good for things like databases, or internal applications or microservices that only need to talk to other internal resources.

Its routing table is very simple. For our IsolatedSubnet1 example, it would look like this:

| Destination  | Target        |
| ------------ | ------------- |
|  | Local         |

That’s it. One route for the local network, and nothing else. This ensures that traffic only knows how to talk on the 10.0.x.x network, and keeps local traffic… well, local.

Gateways (Not the Cow Computers)

We talked about the different gateways in Part 1 of this series, and for these purposes, there’s not much more to say. As a refresher, the main points are these:

  • In a VPC, no traffic gets to the internet without going through a gateway
  • There are two types of gateways:
  1. Internet Gateways
  • The default gateways for public subnets
  • There is no additional cost associated with these
  1. NAT Gateways/Instances
  • Used for private subnets
  • These have additional costs associated
  • Created in public subnets and get public IP addresses

For the purposes of this article, we’re limiting our scope to just, “my machine needs to talk to the internet, and it’s in a public|private|isolated subnet - how do I do that?!” purposes. There are other gateways and such to help you connect to your networks and your networks to connect to each other. If you’re interested in diving deeper into those, fantastic! You can find a lot of that info here.


In this article, we talked about routing, and how traffic flows internally and externally.  We described the different types of subnets and how they talk to each other, how routing tables affect how traffic flows, and what gateways are how those pass traffic to the internet (or don’t!).

Combined with Part 1 of this series, there you have a high-level overview of what VPCs are and how they work. There are more topics associated with them that we could talk about (like Endpoints and Peering), but the above should be enough to get an idea of what’s going on when the parts of your application are talking to each other. Networking can be a complicated topic, but thankfully the AWS documentation for it is pretty good. If you need a quick reference sheet, however, hopefully this document will provide some value to you.

B-T-Dubs, if you use the AWS Cloud Development Kit, then you can create VPCs for your application with just a few lines of code.

Author Spotlight:

Chris Yommer

Keep Up To Date With AWS News

Stay up to date with the latest AWS services, latest architecture, cloud-native solutions and more.