VPC


Additional Resources


AWS Networking Fundamentals Guide

VPC Basics

Docsarrow-up-right

What is a VPC?

A Virtual Private Cloud (VPC) is an isolated area of your AWS account with its own virtual network and IP address space. Nearly every AWS resource deploys into a VPC.

A VPC, or virtual private cloud, is an isolated area of your AWS account that has its own virtual network and IP address space. Just about every AWS resource deploys into a VPC. If you don’t explicitly specify a VPC, the resource will be deployed into the Default VPC, which is part of every AWS account created after 2013. If for some reason you deleted the Default VPC in your account, either use a different region (each region has its own Default VPC) or create a new Default VPC using the AWS Web Console. Otherwise, you’ll need to update almost every example to include a vpc_id or subnet_id parameter pointing to a custom VPC.

  • VPCs can’t span across regions, they are always within one. You can create up to 5 VPC within a Region (unless you request more). To communicate across regions, you would use VPC peering, VPN, or Transit Gateway to connect separate VPCs in different regions.

Default VPC

  • Every AWS account created after 2013 includes a Default VPC in each region.

  • If you don't specify a VPC, resources deploy to the Default VPC automatically

  • If for some reason you deleted the Default VPC in your account, either use a different region (each region has its own Default VPC) or create a new Default VPC using the AWS Web Console.

  • Each region has its own Default VPC with a Public Subnet in each AZ and an internet gateway. It can allow you to quickly launch public internet facing EC2 instances (or other resources) without additional setup. This however, is only recommended for experimenting, because for many real-world cases you'll likely not want directly public facing resources. You should create custom VPCs for your specific use cases.

Without a Default VPC, you'll need to specify vpc_id or subnet_id parameters pointing to a custom VPC when creating resources.


IP Addressing and CIDR Blocks

What is a CIDR Block?

CIDR (Classless Inter-Domain Routing) defines a range of private IP addresses available within your VPC.

  • Or how many private IP addresses are available in the VPC.

  • Any resource that will be deployed in this VPC will be assigned an IP address from that range.

  • If you want a resource to be public, you will need to assign a public IP address to it which will come from a pool of AWS managed public IPs. So CIDR is only responsible for private IP addresses.

  • Can be IPv4 or IPv6.

Tool: Use cidr.xyzarrow-up-right for CIDR calculations

IP Address Structure

  • IPv4 addresses consist of 32 bits total

  • Divided into 4 octets (8 bits each)

  • Each octet can range from 0-255

  • Example: 10.0.0.0

Understanding CIDR Notation

Example: 10.0.0.0/16

  • 10.0.0.0 = Starting address of the network

  • /16 = Prefix length (how many bits define the network portion)

Breakdown:

  • 32 total bits in an IPv4 address

  • /16 means first 16 bits (2 octets) are fixed for the network

  • Remaining 16 bits (2 octets) are available for host addresses

  • This allows 65,536 possible IP addresses (2^16)

Visual representation:

This means that every IP address in that private network will start with 10.0._._, where the other 2 numbers can be anything from the range 0-255.

All IPs in this network: 10.0.0.0 through 10.0.255.255

Different Prefix Lengths

If you had other prefix length, you would allow more places to be used as network part of the address.

CIDR
Network Bits
Host Bits
Available IPs
IP Range

/16

16

16

65,536

10.0.0.0 - 10.0.255.255

/24

24

8

256

10.0.0.0 - 10.0.0.255

/28

28

4

16

10.0.0.0 - 10.0.0.15

Private vs Public IP Addresses

  • CIDR blocks assign private IPs used within your VPC

  • Public IPs come from AWS-managed pools and must be explicitly assigned

  • Resources need public IPs to be directly accessible from the internet

IPv6 Support

VPCs can also use IPv6 CIDR blocks in addition to or instead of IPv4.


Subnets: Public vs Private

Docsarrow-up-right

Subnets are segments of your VPC's IP address range where you can place groups of isolated resources.

Public Subnets

  • Resources can communicate directly with the internet

  • Require an Internet Gateway

  • Typically host: Load Balancers, NAT Gateways, Bastion Hosts

A “public subnet” in AWS is not truly public in the sense of being exposed to everyone. It is still private, internal, and isolated inside your VPC.

The term “public” only means:

Resources inside this subnet can reach the internet directly because the subnet’s route table has a default route (0.0.0.0/0) pointing to an Internet Gateway (IGW).

Nothing more.

A public subnet = private AWS subnet with a route to the Internet Gateway.

That’s it.

It is still:

  • inside your VPC (isolated from other VPCs)

  • using private IP addresses

  • governed by security groups and NACLs

  • invisible to the internet unless you allow it

  • not reachable unless an instance inside has a public IP or Elastic IP

So even “public” subnets aren’t exposed unless you explicitly open them.

But in AWS networking, it's a logical concept:

  • Public subnet = traffic may go out to the internet

  • Private subnet = traffic cannot go out directly

Neither is actually “public” in the sense of a LAN with no firewall.

What does get exposed in a public subnet?

Only resources that meet all of these conditions:

  • They have a public IP or Elastic IP

  • Their subnet route table has 0.0.0.0/0 → IGW

  • Their security group allows inbound internet traffic

  • Their NACL allows inbound/outbound traffic

If any of those is missing → they are NOT reachable from the internet.

Why do we even need “public subnets”?

To host things that must talk directly to the internet, such as:

  • load balancers (ALB/NLB with public IP)

  • bastion hosts (if not using SSM Session Manager)

  • NAT gateways

  • public-facing APIs

  • reverse proxies

  • CloudFront origins (if you’re not using OAC)

Everything else (databases, app servers, EMR, ECS tasks, Lambda ENIs) belongs in private subnets.

Public ≠ Unsecured

Example:

EC2 in public subnet

  • Public IP: yes

  • SG: denies all inbound → Completely unreachable, despite being in a public subnet.

EC2 in private subnet

  • NAT gateway: yes

  • SG: allows egress → Can access internet outbound but cannot be accessed inbound

Private Subnets

  • Resources cannot be directly accessed from the internet

  • Can initiate outbound connections via NAT Gateway

  • Typically host: Application servers (EC2), Databases (RDS), Internal services

Best Practice

Use private subnets for application and data layers, public subnets only for internet-facing components.


Gateways and Connectivity

Internet Gateway (IGW)

  • Enables communication between your VPC and the internet

  • Allows resources in public subnets to send/receive internet traffic

  • Horizontally scaled, redundant, and highly available

  • Required for resources that need direct internet access

Use cases:

  • Receiving requests through Application Load Balancers

  • Allowing users to access public-facing applications

  • Downloading updates and patches from the internet

NAT Gateway (Network Address Translation)

  • Allows resources in private subnets to access the internet or other AWS services

  • But prevents the internet from initiating inbound connections to those resources

  • Acts as a one-way door for outgoing traffic but protects from ingoing traffic

Think of it as: A controlled doorway that allows outbound traffic while protecting internal resources.

Architecture:

  • NAT Gateway resides in a public subnet

  • Private subnet resources route through it for internet access

  • Provides security by hiding private IPs from the internet

Use cases:

  • Downloading software updates and patches

  • Accessing external APIs

  • Pulling container images

  • Connecting to external databases or services

Key Difference

  • Internet Gateway: Two-way communication (public subnets)

  • NAT Gateway: One-way outbound only (private subnets)


What is Elastic IP (EIP)?

What it is: A static, public IPv4 address that you can attach to an EC2 instance or NAT gateway.

Why it exists: Normally, EC2 public IPs change when you stop/start the instance. Elastic IP stays the same, so you can reliably point clients or DNS records to the instance.

Typical use-cases:

  • When a public-facing server needs a fixed IP (e.g., a legacy app that doesn't use DNS).

  • When you need a stable SSH/RDP access point.

  • When you want to quickly remap the IP to another instance during failure (zero DNS propagation time).

Key notes:

  • Only IPv4.

  • AWS charges you when an EIP is not attached, encouraging you not to “hoard” public IPs.


Route Tables

What are Route Tables?

Route Tables contain rules (routes) that determine where network traffic is directed within your VPC.

Default Route Table

When you create a VPC, AWS automatically creates a default Route Table that:

  • Allows internal communication within the VPC (between subnets)

  • Does NOT include routes for internet connectivity

Route Table Association

  • Each subnet must be associated with one Route Table

  • Multiple subnets can share the same Route Table

  • You can create custom Route Tables for different requirements

Configuring Route Tables

For Public Subnets:

This routes all internet-bound traffic (0.0.0.0/0) to the Internet Gateway.

For Private Subnets:

This routes internet-bound traffic through the NAT Gateway in the public subnet.

Important

Without proper route configurations, your subnets won't know how to direct traffic to the internet or even within the VPC itself.


Security: ACLs and Security Groups

AWS provides two layers of security for controlling network traffic.

Security Groups (Instance-Level Firewall)

Characteristics:

  • Operate at the instance level (EC2, RDS, etc.)

  • Stateful: Return traffic is automatically allowed

  • Act as virtual firewalls for individual resources

Default Behavior:

  • Deny all inbound traffic by default

  • Allow all outbound traffic by default

Rules:

  • Specify allowed traffic using protocol, port, and source/destination

  • No explicit "deny" rules (only allow rules)

  • Changes take effect immediately

Example: EC2 Security Group

Security Group Chaining

A powerful pattern where Security Groups reference each other:

Example Architecture:

  1. ALB Security Group: Allows HTTP/HTTPS from internet (0.0.0.0/0)

  2. EC2 Security Group: Allows traffic only from ALB Security Group

  3. RDS Security Group: Allows traffic only from EC2 Security Group

Traffic Flow:

This creates a secure chain where each layer only accepts traffic from the previous layer.

Network ACLs (Subnet-Level Firewall)

Characteristics:

  • Operate at the subnet level

  • Stateless: Must explicitly allow both inbound AND outbound traffic

  • Provide an additional security layer

  • Rules are evaluated in numerical order

Default Behavior:

  • Allow all inbound traffic by default

  • Allow all outbound traffic by default

When to Use:

  • Implementing security policies at the subnet level

  • Blocking specific IP ranges across all resources in a subnet

  • Meeting compliance requirements for layered security

  • Granular control over traffic patterns

Example: Network ACL

Security Groups vs Network ACLs

Feature
Security Groups
Network ACLs

Level

Instance

Subnet

State

Stateful

Stateless

Rules

Allow only

Allow and Deny

Default

Deny inbound, Allow outbound

Allow all

Evaluation

All rules

Numerical order

Return Traffic

Automatic

Must be explicit

Best Practices

  1. Use Security Groups as your primary defense

  2. Use Network ACLs for additional subnet-level controls

  3. Implement Security Group chaining for layered security

  4. Follow the principle of least privilege (only allow necessary traffic)


Load Balancing

Application Load Balancer (ALB)

https://docs.aws.amazon.com/elasticloadbalancing/latest/application/introduction.html#:~:text=An%20Application%20Load%20Balancer%20functions,registered%20with%20multiple%20target%20groups.arrow-up-right

The ALB distributes incoming application traffic across multiple backend targets (EC2 instances, containers, etc.).

Why Use an ALB?

  • Distributes traffic for high availability

  • Performs health checks on targets

  • Supports path-based and host-based routing

  • Handles SSL/TLS termination

  • Provides connection draining and sticky sessions

Typical Architecture:

Placement:

  • ALB must be in public subnets (at least 2 for high availability)

  • Targets (EC2) typically in private subnets

  • ALB Security Group allows internet traffic

  • EC2 Security Group allows traffic only from ALB

Key Features:

  • Layer 7 (Application layer) routing

  • Content-based routing

  • WebSocket and HTTP/2 support

  • Integration with AWS services (ECS, EKS, Lambda)


VPC Peering

What is VPC Peering?

A VPC peering connection allows two VPCs to communicate using private IP addresses as if they were in the same network.

Documentation: AWS VPC Peering Guidearrow-up-right

Use Cases:

  • Connecting different environments (dev, staging, prod)

  • Sharing resources between different applications

  • Connecting VPCs across different AWS accounts

  • Multi-region architectures

Limitations:

  • No transitive peering (if VPC A peers with B, and B peers with C, A cannot communicate with C)

  • CIDR blocks cannot overlap

  • Must update route tables in both VPCs

Configuration Steps:

  1. Create peering connection request

  2. Accept the request in the peer VPC

  3. Update route tables in both VPCs

  4. Update Security Groups to allow traffic


Troubleshooting Connectivity

When encountering connectivity issues, check these components in order:

1. Route Tables

  • ✅ Does the subnet have a route to the destination?

  • ✅ Is the route pointing to the correct target (IGW, NAT, etc.)?

  • ✅ Is the subnet associated with the correct Route Table?

2. Internet Gateway / NAT Gateway

  • ✅ Is the IGW attached to the VPC?

  • ✅ Is the NAT Gateway in a public subnet?

  • ✅ Does the NAT Gateway have an Elastic IP?

3. Security Groups

  • ✅ Are inbound rules allowing the required traffic?

  • ✅ Are you specifying the correct protocol and port?

  • ✅ Is the source specified correctly (IP, CIDR, or Security Group)?

4. Network ACLs

  • ✅ Are both inbound and outbound rules configured?

  • ✅ Is traffic being explicitly denied?

  • ✅ Are ephemeral ports allowed for return traffic?

5. Instance/Resource Level

  • ✅ Does the instance have a public IP (if in public subnet)?

  • ✅ Is the application/service running and listening on the correct port?

  • ✅ Are OS-level firewalls (iptables, Windows Firewall) configured?

6. DNS and Connectivity

  • ✅ Can you resolve DNS names?

  • ✅ Are you using the correct endpoint/hostname?

  • ✅ Is the VPC DNS resolution enabled?

Debugging Tools

  • VPC Flow Logs: Capture IP traffic information

  • VPC Reachability Analyzer: Test connectivity between resources

  • Network Access Analyzer: Identify unintended network access

  • AWS CLI/Console: Verify configurations

  • ping/telnet/nc: Test connectivity from instances


Cost Considerations

Understanding AWS networking costs helps optimize your architecture.

Resource: AWS Networking Costs Blogarrow-up-right

Key Cost Factors

1. Data Transfer Costs

  • Within the same AZ: Usually free

  • Between AZs in same region: ~$0.01/GB each way

  • Between regions: ~$0.02/GB

  • To internet: Starts at $0.09/GB (decreases with volume)

  • From internet: Free

2. NAT Gateway Costs

  • Hourly charge: ~$0.045/hour

  • Data processing: ~$0.045/GB processed

  • Can become expensive with high traffic volumes

3. Load Balancer Costs

  • ALB hourly charge: ~$0.0225/hour

  • LCU (Load Balancer Capacity Units): Based on traffic processed

4. VPC Endpoints (Optional)

  • Interface endpoints: ~$0.01/hour per AZ + data processing

  • Gateway endpoints (S3, DynamoDB): Free

Cost Optimization Tips

  • Use VPC endpoints to avoid NAT Gateway charges for AWS services

  • Keep resources in the same AZ when possible

  • Use CloudFront CDN to reduce data transfer costs

  • Consider single NAT Gateway for non-production environments

  • Monitor and analyze traffic patterns with VPC Flow Logs

  • Use AWS Cost Explorer to identify expensive data transfer paths


Bastion Host (Jump Host)

What is Bastion Hostarrow-up-right

What it is: A hardened EC2 instance in a public subnet used as a secure entry point to access servers in private subnets.

Why it exists: You don’t want to expose your private servers directly to the internet. Instead, you SSH into the bastion, and from there, SSH into private instances.

Typical design:

  • Bastion in public subnet, with:

    • a security group allowing SSH only from specific IPs (your office / home)

    • tight IAM + auditing

  • Private instances' security groups allow SSH only from the bastion SG.

Modern alternative: AWS SSM Session Manager (more secure, no inbound ports, no Bastion needed).


Summary of concepts


Quick Reference Architecture

Typical Production VPC Setup

Security Group Chain

Route Table Configuration


Example Scenario

A web application running on an EC2 instance that allows you to query a database running on RDS.

Here's roughly what it would look like:

Creating a VPC

  • 1 VPC with two AZs with 1 Public and 1 Private Subnet in each.

  • EC2 and RDS deployed in the Private Subnets

  • And NAT Gateway deployed in the Public Subnets

  • 1 ALB to manage and route traffic to EC2 and RDS

Here's configuration you would do for your subnets:

Subnet Name

CIDR Block

AZ

Usage

Public Subnet 1

10.0.1.0/24

AZ 1

Public subnet

Private Subnet 1

10.0.2.0/24

AZ 1

Private subnet

Public Subnet 2

10.0.3.0/24

AZ 2

Public subnet

Private Subnet 2

10.0.4.0/24

AZ 2

Private subnet

Note that there's no internet connectivity for now, and no Application Load Balancer. If you deploy any resources into a Public Subnet, they will not be accessible via the internet and will not be able to establish connections to other resources on the internet either. That is because VPC with Subnets alone create an isolated network with no traffic in or out.

In fact, both the EC2 instance and RDS should be in private subnets and wouldn't need direct connectivity with the Internet. But there are 2 considerations to keep in mind:

  • The first is that the applications running on the EC2 do need to occasionally download updates from resources on the Internet for things like application upgrades and patching.

  • And the second consideration is that you would still need a way to submit requests to the application running on the EC2 Instance through the load balancer so that you can query your data on RDS.

Internet Gateway and NAT Gateway

We need to add an Internet Gateway as the "door" to our network. Internet gateways allow resources in your public subnets to connect with the Internet. They support both inbound and outbound traffic.

Creating and attaching an Internet Gateway is however only 1 step towards allowing to-/inbound connections to our public subnets. You also need to configure routes in the Route Table and Network Security Rules.

We will be attaching an Internet gateway to allow traffic to flow to and from the public subnets. How will this help if our resources are in the private subnets?

Taking into account the 2 considerations we mentioned earlier, our EC2 instance needs to be able to make outgoing connections from the VPC in order to download updates. On top of that, we need the ability to submit requests to the application from the internet. The NAT gateway and ALB can help us meet those requirements.

With a NAT gateway in place, your EC2 Instances in the private subnet can download updates and patches from the Internet without exposing them directly to the public Internet.

The next requirement is allowing external users to submit requests to our application. The ALB distributes incoming traffic across multiple back end targets (e.g. EC2 instances) across two AZs. It will be the entry point for external users. This way, ALB will handle the load and ensure the app remains responsive and its resources (EC2) are private.

In the Management Console or via any other method, create and attach and Internet Gateway to your VPC. Create NAT gateways for each public subnet and attach an Elastic IP.

Configuring a Route Table

Route tables are essentials for directing network traffic within your VPC.

Each subnet can be associated with a Route table which contains a set of rules/routes that determine where network traffic is directed.

When you create a VPC, AWS automatically creates a Default Route Table. This default route table allows internal communication within the VPC, meaning resources in different subnets can communicate with each other. However, it doesn't include routes for internet connectivity. This is where you need to customize your Route tables to meet your specific requirements. Without these routes your subnets won't know how to direct traffic either to the internet or within the VPC itself.

For public subnets, you'll configure the route table to direct all internet bound traffic to the Internet Gateway. This allows resources in the public subnet to access the internet.

For private subnets, you'll direct internet bound traffic to the NAT Gateway in the public subnet. This allows resources in the private subnet to make outbound connections to the internet while preventing inbound connections from the internet.

Network ACLs and Security Groups

In our scenario, the ALB will send internet traffic to the EC2 instances which would then create connections with the RDS instances for queries. You can configure networking rules to allow only the network traffic you want to reach these instances. By default, no traffic is allowed to reach these instances, even with the route tables in place. To change that, you first need to understand Security Groups (SGs) and Network Access Control Lists (NACLs or Network ACLs).

Think of Security Groups as instance-level virtual firewalls, controlling both inbound and outbound traffic.

By default, Security Groups deny all inbound traffic and allow all outbound traffic.

This statefulness simplifies the network management, because you don't have to create matching outbound rules for every inbound rule.

Resources that are placed in VPCs such as EC2 instances, ALB, and RDS databases use Security Groups. All can use different security rules and the rules for Security Groups can reference other Security Groups.

In our example, we have an ALB that would need to accept traffic for HTTP on port 80 and HTTPS on port 443 from the internet. Then, we have an EC2 instance hosting a web server, so you need to allow HTTP and HTPS traffic coming from the ALB. So, you could reference these security groups used by the load balancer.

We also have RDS database instances which would need to allow TCP on port 3306 (which is commonly used for MySQL) coming from the securty group used by EC2 instances. This is called Security Group Chaining.

Now, let's talk about Network ACLs which provide an additional layer of security at the Subnet level. Unlike security groups which are stateful, NACLs are stateless. This means you need to define both inbound and outbound rules explicitly. They offer more granular control over the traffic and can be particularly useful for implementing security policies at the subnet level.

By default, Network ACLs allow all inbound and outbound traffic, but you can modify these rules to meet your specific requirements.

Here's how our infrastructure ended up looking:



Last updated