VPC is the foundation everything else in AWS sits on. EC2, RDS, ECS, Lambda in a VPC, EKS, all of it lives inside a VPC. Most engineers use VPCs without understanding them. They click through the wizard, accept the defaults, and move on. Then a security audit happens, or a cross-account connection fails, or a NAT Gateway bill arrives, and the gaps show up.

This guide builds VPC understanding from the ground up. Every concept is introduced with the problem it solves. By the end you will be able to design a production-grade multi-account, multi-region network architecture from scratch, and explain every decision.

Table of Contents

  1. What a VPC Is - The Core Abstraction
  2. CIDR Notation - The Language of IP Addressing
  3. Subnets - Dividing the Network
  4. Route Tables - Where Traffic Goes
  5. Internet Gateway - Public Internet Access
  6. NAT Gateway - Outbound-Only Internet for Private Resources
  7. Security Groups - Stateful Instance-Level Firewall
  8. Network ACLs - Stateless Subnet-Level Firewall
  9. VPC Endpoints - Private Access to AWS Services
  10. VPC Peering - Connecting Two VPCs
  11. Transit Gateway - Hub-and-Spoke Networking at Scale
  12. AWS Direct Connect - Dedicated Private Connectivity
  13. Site-to-Site VPN - Encrypted Tunnel to On-Premises
  14. Client VPN - Remote Access for Individuals
  15. DHCP Option Sets - Customising Network Configuration
  16. Elastic IPs and ENIs - IP Address Management
  17. Flow Logs - Network Traffic Visibility
  18. DNS in VPC - Route 53 Resolver
  19. PrivateLink - Exposing Services Privately Across Accounts
  20. RAM - Resource Access Manager for Cross-Account Sharing
  21. Production VPC Design - The Reference Architecture

What a VPC Is - The Core Abstraction

The Problem

When you launch a resource in AWS, an EC2 instance, an RDS database, a Lambda function, it needs a network to live in. Without network isolation, every resource in every AWS account in the world would be on the same flat network. Any resource could reach any other resource. Security would be impossible. Routing would be chaos.

What a VPC Is

A Virtual Private Cloud (VPC) is a logically isolated network that you define within AWS. It behaves like a traditional data centre network, with IP address ranges, subnets, routing tables, and firewalls, but it is software-defined. There is no physical hardware to rack. No cables to run. The entire network is configuration.

Within a VPC, you control:

  • The IP address range
  • How the network is divided into subnets
  • Which subnets can reach the internet
  • Which resources can communicate with each other
  • What traffic is allowed in and out

A VPC is regional. It exists within one AWS region and spans all Availability Zones in that region. Your subnets live in specific AZs within the VPC.

Default VPC vs Custom VPC

Every AWS account comes with a default VPC in every region. The default VPC:

  • Has a 172.31.0.0/16 CIDR block
  • Has a subnet in every AZ with public IP assignment enabled
  • Has an Internet Gateway attached
  • Has a default route to the Internet Gateway

The default VPC is designed for convenience, not production. It exists so you can launch an EC2 instance immediately without configuring networking. For anything beyond experimentation, you build a custom VPC.

Production VPCs are never the default. They have carefully planned CIDR ranges, private subnets for sensitive resources, controlled internet access, and explicit security boundaries.

CIDR Notation - The Language of IP Addressing

What CIDR Is

Before designing a VPC, you need to understand CIDR (Classless Inter-Domain Routing) notation. It is the language used to define IP address ranges.

A CIDR block looks like this: 10.0.0.0/16

The number after the slash is the prefix length, the number of bits that are fixed. The remaining bits define the host range.

An IPv4 address is 32 bits. 10.0.0.0/16 means the first 16 bits are fixed (10.0), and the remaining 16 bits are available for hosts and subnets.

Calculating Host Count

/16 prefix = 32 - 16 = 16 variable bits = 2^16 = 65,536 addresses /24 prefix = 32 - 24 = 8 variable bits = 2^8 = 256 addresses /28 prefix = 32 - 28 = 4 variable bits = 2^4 = 16 addresses 

AWS reserves 5 addresses in every subnet:

  • .0 - Network address
  • .1 - VPC router
  • .2 - AWS DNS
  • .3 - Reserved for future use
  • .255 - Broadcast address (not used, but reserved)

So a /28 subnet (16 addresses) gives you 16 - 5 = 11 usable addresses.

Choosing a VPC CIDR

RFC 1918 defines private IP ranges. Use these for VPCs:

Range CIDR Total Addresses
10.0.0.0 – 10.255.255.255 10.0.0.0/8 16.7 million
172.16.0.0 – 172.31.255.255 172.16.0.0/12 1 million
192.168.0.0 – 192.168.255.255 192.168.0.0/16 65,536

Planning rules:

  • Do not overlap CIDRs between VPCs you will ever connect. If VPC A is 10.0.0.0/16 and VPC B is 10.0.0.0/16, you can never peer them. Their address spaces overlap.
  • Plan for growth. A /24 VPC (256 addresses) feels fine until you need 300 resources.
  • Use consistent schemes across accounts. A common pattern: allocate a /8 or /10 to your organisation, then carve it into /16 per environment or account.

Example allocation for a multi-account organisation:

10.0.0.0/8 - Organisation total space 10.0.0.0/16 - Production account, us-east-1 10.1.0.0/16 - Production account, eu-west-1 10.2.0.0/16 - Staging account, us-east-1 10.3.0.0/16 - Development account, us-east-1 10.4.0.0/16 - Shared services account, us-east-1 10.5.0.0/16 - Security account, us-east-1 

Every VPC in the organisation has a unique, non-overlapping CIDR. They can be connected to each other without conflicts.

Subnets - Dividing the Network

What Subnets Are

A subnet is a range of IP addresses within your VPC. Every resource in your VPC, EC2 instances, RDS databases, Lambda functions, load balancers, is placed in a subnet.

Subnets serve two purposes:

  1. AZ placement - A subnet exists in exactly one Availability Zone. Placing resources in subnets across multiple AZs gives you resilience.
  2. Traffic control - Subnets are associated with route tables. The route table determines where traffic from that subnet can go.

Public vs Private Subnets

A subnet is public or private based on its route table, specifically, whether it has a route to an Internet Gateway.

Public subnet - Has a route to an Internet Gateway. Resources in a public subnet can communicate with the internet (if they have a public IP). The internet can initiate connections to resources with public IPs.

Private subnet - No route to an Internet Gateway. Resources in a private subnet cannot be reached from the internet and cannot initiate direct connections to the internet.

Private does not mean isolated. Resources in private subnets can still communicate with each other, with resources in other subnets via VPC routing, and with the internet via a NAT Gateway. They just cannot be directly reached from the internet.

The Standard Subnet Design

For a production VPC in 10.0.0.0/16 across three AZs:

VPC: 10.0.0.0/16 Public Subnets (for load balancers, NAT Gateways, bastion hosts): 10.0.0.0/24 - AZ-a (251 usable IPs) 10.0.1.0/24 - AZ-b 10.0.2.0/24 - AZ-c Private App Subnets (for EC2, ECS, EKS worker nodes): 10.0.10.0/23 - AZ-a (507 usable IPs) 10.0.12.0/23 - AZ-b 10.0.14.0/23 - AZ-c Private Data Subnets (for RDS, ElastiCache, OpenSearch): 10.0.20.0/24 - AZ-a (251 usable IPs) 10.0.21.0/24 - AZ-b 10.0.22.0/24 - AZ-c 

Three tiers, three AZs, nine subnets. Each tier has a distinct purpose and distinct security controls.

CloudFormation

Resources: VPC: Type: AWS::EC2::VPC Properties: CidrBlock: 10.0.0.0/16 EnableDnsHostnames: true EnableDnsSupport: true Tags: - Key: Name Value: production-vpc PublicSubnetA: Type: AWS::EC2::Subnet Properties: VpcId: !Ref VPC CidrBlock: 10.0.0.0/24 AvailabilityZone: !Select [0, !GetAZs ""] MapPublicIpOnLaunch: false # Never auto-assign public IPs Tags: - Key: Name Value: public-subnet-a - Key: Tier Value: public PrivateAppSubnetA: Type: AWS::EC2::Subnet Properties: VpcId: !Ref VPC CidrBlock: 10.0.10.0/23 AvailabilityZone: !Select [0, !GetAZs ""] MapPublicIpOnLaunch: false Tags: - Key: Name Value: private-app-subnet-a - Key: Tier Value: private-app PrivateDataSubnetA: Type: AWS::EC2::Subnet Properties: VpcId: !Ref VPC CidrBlock: 10.0.20.0/24 AvailabilityZone: !Select [0, !GetAZs ""] MapPublicIpOnLaunch: false Tags: - Key: Name Value: private-data-subnet-a - Key: Tier Value: private-data 

Notice MapPublicIpOnLaunch: false even on public subnets. Public IPs should be assigned explicitly where needed, not automatically. This forces intentionality.

Route Tables - Where Traffic Goes

What Route Tables Do

A route table is a set of rules, routes, that determine where network traffic is directed. Every subnet is associated with exactly one route table. Every VPC has a main route table that subnets use by default.

A route has two components:

  • Destination - The IP address range the route applies to
  • Target - Where to send traffic destined for that range

How Routing Works

When a resource in a subnet sends traffic, the VPC router looks at the destination IP address and finds the most specific matching route in the subnet's route table.

Route Table for Public Subnet: Destination Target 10.0.0.0/16 local ← All VPC traffic goes to local router 0.0.0.0/0 igw-abc123 ← All other traffic goes to Internet Gateway 

The local route is created automatically for every VPC. It covers the entire VPC CIDR and routes traffic within the VPC. You cannot delete it.

The 0.0.0.0/0 route (the default route) sends all traffic not matched by a more specific route to the specified target. For public subnets, the target is the Internet Gateway.

Route Table for Private App Subnet: Destination Target 10.0.0.0/16 local 0.0.0.0/0 nat-abc123 ← Internet-bound traffic goes to NAT Gateway 

Private subnets have a default route to the NAT Gateway instead of the Internet Gateway. Traffic can get out (via NAT), but nothing from the internet can initiate a connection in.

Route Table for Private Data Subnet: Destination Target 10.0.0.0/16 local ← No default route. No internet access at all. 

The data tier has no default route. Database servers have no path to or from the internet. They can only talk to resources within the VPC.

CloudFormation

 PublicRouteTable: Type: AWS::EC2::RouteTable Properties: VpcId: !Ref VPC Tags: - Key: Name Value: public-route-table PublicDefaultRoute: Type: AWS::EC2::Route DependsOn: VPCGatewayAttachment Properties: RouteTableId: !Ref PublicRouteTable DestinationCidrBlock: 0.0.0.0/0 GatewayId: !Ref InternetGateway PublicSubnetARouteTableAssociation: Type: AWS::EC2::SubnetRouteTableAssociation Properties: SubnetId: !Ref PublicSubnetA RouteTableId: !Ref PublicRouteTable PrivateAppRouteTableA: Type: AWS::EC2::RouteTable Properties: VpcId: !Ref VPC Tags: - Key: Name Value: private-app-route-table-a PrivateAppDefaultRouteA: Type: AWS::EC2::Route Properties: RouteTableId: !Ref PrivateAppRouteTableA DestinationCidrBlock: 0.0.0.0/0 NatGatewayId: !Ref NATGatewayA PrivateAppSubnetARouteTableAssociation: Type: AWS::EC2::SubnetRouteTableAssociation Properties: SubnetId: !Ref PrivateAppSubnetA RouteTableId: !Ref PrivateAppRouteTableA 

One private route table per AZ for the app tier. Why not one shared route table for all three private subnets? Because each private subnet routes internet traffic to the NAT Gateway in its own AZ. If AZ-a goes down, the NAT Gateway in AZ-a goes down too. Private subnets in AZ-b and AZ-c should route to their own NAT Gateways, not AZ-a's. One route table per AZ enables this.

Internet Gateway - Public Internet Access

What It Is

An Internet Gateway (IGW) is a horizontally scaled, redundant, highly available VPC component that enables communication between your VPC and the internet. It does two things:

  1. Provides a target in route tables for internet-routable traffic
  2. Performs Network Address Translation (NAT) for resources with public IP addresses, translating between the private IP inside the VPC and the public IP visible on the internet

How It Works

A resource in a public subnet with a public IP address:

  • Sends a packet to 8.8.8.8 (Google's DNS)
  • The VPC router matches 0.0.0.0/0 and sends the packet to the IGW
  • The IGW sees the source private IP (10.0.0.25) and the associated public IP (52.90.100.200)
  • The IGW translates the source to the public IP and forwards the packet
  • The response comes back to the public IP
  • The IGW translates back to the private IP and delivers it to the instance

This translation is called one-to-one NAT. One private IP maps to one public IP. The instance itself does not know its public IP, it only sees its private IP.

What Would Happen Without It

Without an Internet Gateway attached to the VPC, no subnet can reach the internet, regardless of route table configuration. The IGW is the gateway. The route table just tells traffic to go there.

 InternetGateway: Type: AWS::EC2::InternetGateway Properties: Tags: - Key: Name Value: production-igw VPCGatewayAttachment: Type: AWS::EC2::VPCGatewayAttachment Properties: VpcId: !Ref VPC InternetGatewayId: !Ref InternetGateway 

An IGW can only be attached to one VPC at a time. A VPC can only have one IGW.

NAT Gateway - Outbound-Only Internet for Private Resources

The Problem

Your application servers are in private subnets. They need to download OS patches, pull container images from ECR, or call external APIs. But they must not be directly reachable from the internet.

An Internet Gateway handles public subnets, resources with public IPs. Private resources have no public IPs. They need a way to initiate outbound connections to the internet without having an inbound-accessible public address.

What NAT Gateway Is

A NAT Gateway (Network Address Translation Gateway) sits in a public subnet and provides outbound internet access for private resources. Private resources send traffic to the NAT Gateway, which translates their private IP to its own Elastic IP (public IP) and forwards the traffic. Responses come back to the NAT Gateway, which translates back and delivers to the private resource.

The critical property: this translation is one-directional. The internet can respond to connections initiated from inside, but cannot initiate new connections to the private resources. There is no public IP on the private resource for the internet to target.

Architecture

Private EC2 (10.0.10.15) ↓ sends packet to 8.8.8.8 Private Route Table: 0.0.0.0/0 → nat-abc123 ↓ NAT Gateway (10.0.0.5, EIP: 52.90.100.201) in Public Subnet ↓ translates source 10.0.10.15 → 52.90.100.201 Internet Gateway ↓ 8.8.8.8 ↓ response to 52.90.100.201 NAT Gateway ↓ translates back to 10.0.10.15 Private EC2 

High Availability

A NAT Gateway is AZ-specific. If the AZ it is in fails, the NAT Gateway fails. For high availability, deploy one NAT Gateway per AZ and configure each AZ's private route table to use its own NAT Gateway.

 EIPA: Type: AWS::EC2::EIP Properties: Domain: vpc NATGatewayA: Type: AWS::EC2::NatGateway Properties: AllocationId: !GetAtt EIPA.AllocationId SubnetId: !Ref PublicSubnetA Tags: - Key: Name Value: nat-gateway-a EIPB: Type: AWS::EC2::EIP Properties: Domain: vpc NATGatewayB: Type: AWS::EC2::NatGateway Properties: AllocationId: !GetAtt EIPB.AllocationId SubnetId: !Ref PublicSubnetB Tags: - Key: Name Value: nat-gateway-b 

The Cost Reality

NAT Gateway costs money in two ways: hourly ($0.045/hour per gateway) and per GB processed ($0.045/GB). In a three-AZ design, three NAT Gateways cost approximately $97/month in idle costs before any data is processed.

For development environments, one NAT Gateway across all AZs is acceptable. For production, the HA cost is justified.

NAT Gateway is also a frequent source of unexpected AWS bills. A Lambda function in a VPC that calls an external API thousands of times per second generates significant NAT Gateway data processing costs. VPC Endpoints (section 9) eliminate this cost for AWS service traffic.

NAT Gateway vs NAT Instance

AWS used to recommend NAT Instances, EC2 instances configured to perform NAT. NAT Gateway replaced them. NAT Gateway is managed, scales automatically, is highly available within an AZ, and requires no administration. NAT Instance requires patching, scaling, and management. Always use NAT Gateway.

Security Groups - Stateful Instance-Level Firewall

What Security Groups Are

A Security Group is a virtual firewall that controls inbound and outbound traffic at the resource level, EC2 instances, RDS databases, Lambda functions in a VPC, load balancers.

Security Groups are stateful. If an inbound rule allows traffic in, the response traffic is automatically allowed out, regardless of outbound rules. You do not need matching outbound rules for established connections.

How They Work

A Security Group has inbound rules and outbound rules. Each rule specifies:

  • Protocol - TCP, UDP, ICMP, or All
  • Port range - Single port or range
  • Source/Destination - CIDR block, another Security Group, or prefix list
 WebServerSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: Security group for web application servers VpcId: !Ref VPC SecurityGroupIngress: # HTTPS from the load balancer only - IpProtocol: tcp FromPort: 443 ToPort: 443 SourceSecurityGroupId: !Ref ALBSecurityGroup # HTTP from the load balancer only (for redirect) - IpProtocol: tcp FromPort: 80 ToPort: 80 SourceSecurityGroupId: !Ref ALBSecurityGroup SecurityGroupEgress: # HTTPS to internet (for external API calls) - IpProtocol: tcp FromPort: 443 ToPort: 443 CidrIp: 0.0.0.0/0 # PostgreSQL to database security group - IpProtocol: tcp FromPort: 5432 ToPort: 5432 DestinationSecurityGroupId: !Ref DatabaseSecurityGroup # Redis to cache security group - IpProtocol: tcp FromPort: 6379 ToPort: 6379 DestinationSecurityGroupId: !Ref CacheSecurityGroup DatabaseSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: Security group for PostgreSQL RDS VpcId: !Ref VPC SecurityGroupIngress: # PostgreSQL only from web servers - IpProtocol: tcp FromPort: 5432 ToPort: 5432 SourceSecurityGroupId: !Ref WebServerSecurityGroup SecurityGroupEgress: [] # No outbound - databases don't initiate ALBSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: Security group for Application Load Balancer VpcId: !Ref VPC SecurityGroupIngress: - IpProtocol: tcp FromPort: 443 ToPort: 443 CidrIp: 0.0.0.0/0 # HTTPS from internet - IpProtocol: tcp FromPort: 80 ToPort: 80 CidrIp: 0.0.0.0/0 # HTTP from internet (for redirect) SecurityGroupEgress: - IpProtocol: tcp FromPort: 443 ToPort: 443 DestinationSecurityGroupId: !Ref WebServerSecurityGroup - IpProtocol: tcp FromPort: 80 ToPort: 80 DestinationSecurityGroupId: !Ref WebServerSecurityGroup 

Security Group Chaining

The most important pattern: reference Security Groups in rules, not CIDR blocks, wherever possible.

# Instead of this (allows any IP in the 10.0.10.0/23 range): - IpProtocol: tcp FromPort: 5432 ToPort: 5432 CidrIp: 10.0.10.0/23 # Do this (allows only resources in the WebServerSecurityGroup): - IpProtocol: tcp FromPort: 5432 ToPort: 5432 SourceSecurityGroupId: !Ref WebServerSecurityGroup 

When you reference a Security Group, the rule applies to any resource assigned that Security Group, regardless of IP address. It is identity-based, not location-based. A new web server added to the Security Group automatically gets database access. An instance not in the Security Group cannot reach the database, even if it is in the same subnet.

What Would Happen Without Correct Security Groups

The default Security Group in a VPC allows all outbound and all inbound from within the same Security Group. Applied broadly, this means all resources in the same Security Group can talk to each other on any port, a flat network with no segmentation. A compromised web server could reach the database directly. That is not a network architecture. That is one layer of failed perimeter security.

Network ACLs - Stateless Subnet-Level Firewall

What NACLs Are

A Network ACL (Access Control List) is a firewall at the subnet level. Unlike Security Groups (which are resource-level and stateful), NACLs are subnet-level and stateless.

Stateless means: each packet is evaluated independently. If an inbound rule allows a request in, you must also have an outbound rule that allows the response out, the return traffic is not automatically allowed.

NACL Rules

NACLs have numbered rules evaluated in order, lowest first. The first matching rule is applied.

 PublicSubnetNACL: Type: AWS::EC2::NetworkAcl Properties: VpcId: !Ref VPC # Inbound rules NACLInboundHTTPS: Type: AWS::EC2::NetworkAclEntry Properties: NetworkAclId: !Ref PublicSubnetNACL RuleNumber: 100 Protocol: 6 # TCP RuleAction: allow Egress: false CidrBlock: 0.0.0.0/0 PortRange: From: 443 To: 443 NACLInboundHTTP: Type: AWS::EC2::NetworkAclEntry Properties: NetworkAclId: !Ref PublicSubnetNACL RuleNumber: 110 Protocol: 6 RuleAction: allow Egress: false CidrBlock: 0.0.0.0/0 PortRange: From: 80 To: 80 # Ephemeral ports - required for return traffic (stateless!) NACLInboundEphemeral: Type: AWS::EC2::NetworkAclEntry Properties: NetworkAclId: !Ref PublicSubnetNACL RuleNumber: 120 Protocol: 6 RuleAction: allow Egress: false CidrBlock: 0.0.0.0/0 PortRange: From: 1024 To: 65535 # Ephemeral port range for response traffic # Deny all other inbound NACLInboundDenyAll: Type: AWS::EC2::NetworkAclEntry Properties: NetworkAclId: !Ref PublicSubnetNACL RuleNumber: 32766 Protocol: -1 # All protocols RuleAction: deny Egress: false CidrBlock: 0.0.0.0/0 # Outbound rules NACLOutboundAll: Type: AWS::EC2::NetworkAclEntry Properties: NetworkAclId: !Ref PublicSubnetNACL RuleNumber: 100 Protocol: -1 RuleAction: allow Egress: true CidrBlock: 0.0.0.0/0 

The Ephemeral Port Requirement

This is the most common NACL mistake. TCP responses use ephemeral ports temporary high-numbered ports (1024-65535) chosen by the operating system. When a client connects to port 443, the response goes back to the client's ephemeral port, some random port above 1024.

Because NACLs are stateless, they evaluate the response packet independently. If you have an inbound rule allowing port 443 but no inbound rule allowing ephemeral ports, the response to your own client is blocked. You must explicitly allow inbound ephemeral ports for return traffic from your outbound connections, and outbound ephemeral ports for return traffic to your inbound connections.

Security Groups vs NACLs - When to Use Which

Security Group NACL
Level Resource (ENI) Subnet
State Stateful Stateless
Rules Allow only Allow and Deny
Evaluation All rules evaluated Rules evaluated in order, first match wins
Default Deny all inbound, allow all outbound Allow all inbound and outbound

Use Security Groups as your primary traffic control mechanism. They are more expressive, easier to reason about, and stateful. NACLs are a secondary defence, use them to implement subnet-level deny rules for broad IP ranges (blocking a known malicious IP range) where Security Groups cannot deny.

Security Groups cannot "deny", they can only "allow". If you need to explicitly block traffic from a specific IP range even if a Security Group would allow it, that is a NACL use case.

VPC Endpoints - Private Access to AWS Services

The Problem

Your EC2 instances are in private subnets. They need to access S3, DynamoDB, Secrets Manager, SSM Parameter Store. Without VPC Endpoints, this traffic goes through the NAT Gateway, out of the VPC, across the internet (via AWS's network), and back in. You pay NAT Gateway data processing costs for every byte. The traffic leaves the VPC boundary.

What VPC Endpoints Are

VPC Endpoints allow private connectivity to AWS services without traffic leaving the AWS network. No NAT Gateway. No Internet Gateway. No public IP required. The traffic stays entirely within AWS.

Two types:

Gateway Endpoints

Available only for S3 and DynamoDB. Free. Added as a route in your route table.

 S3GatewayEndpoint: Type: AWS::EC2::VPCEndpoint Properties: VpcId: !Ref VPC ServiceName: !Sub "com.amazonaws.${AWS::Region}.s3" VpcEndpointType: Gateway RouteTableIds: - !Ref PrivateAppRouteTableA - !Ref PrivateAppRouteTableB - !Ref PrivateAppRouteTableC PolicyDocument: Version: "2012-10-17" Statement: - Effect: Allow Principal: "*" Action: - s3:GetObject - s3:PutObject - s3:DeleteObject Resource: - !Sub "arn:aws:s3:::${AppBucket}/*" - !Sub "arn:aws:s3:::${AppBucket}" DynamoDBGatewayEndpoint: Type: AWS::EC2::VPCEndpoint Properties: VpcId: !Ref VPC ServiceName: !Sub "com.amazonaws.${AWS::Region}.dynamodb" VpcEndpointType: Gateway RouteTableIds: - !Ref PrivateAppRouteTableA - !Ref PrivateAppRouteTableB - !Ref PrivateAppRouteTableC 

The endpoint adds a route to the route table: traffic destined for S3 or DynamoDB IP ranges goes to the endpoint, not to the NAT Gateway. No configuration change in your application, the AWS SDK already knows the S3 endpoint address. The routing is transparent.

The endpoint policy is an IAM-like policy that restricts which S3 buckets or DynamoDB tables can be accessed through the endpoint. This is an additional security control, even if an IAM policy allows access to another bucket, the endpoint policy can restrict it to only your application's buckets.

Interface Endpoints

Available for most other AWS services, SSM, Secrets Manager, KMS, SQS, SNS, ECR, CloudWatch, and many more. Uses AWS PrivateLink. Creates an Elastic Network Interface (ENI) in your subnet with a private IP address. Not ...