AWS PrivateLink vs. VPC Peering: When to Use Each for EC2 Communication

AWS PrivateLink vs. VPC Peering: When to Use Each for EC2 Communication

When architecting AWS environments, securely connecting EC2 instances across different VPCs is crucial. Two commonly used methods are AWS PrivateLink and VPC Peering. Both provide private network connectivity, but they serve different use cases.

In this blog, we’ll break down AWS PrivateLink and VPC Peering, highlight their differences, advantages, and limitations, and help you decide when to use each with real-world examples with terraform implementation too.?

1. Understanding VPC Peering

VPC Peering enables direct communication between two VPCs using AWS’s internal network. The traffic stays within AWS, reducing latency and improving security.

? Key Features:

  • Low-latency, high-speed connection (AWS backbone).
  • Supports bidirectional communication between instances in both VPCs.
  • Works across regions (Inter-Region VPC Peering).
  • Uses private IPs (no need for public endpoints).


How VPC Peering Works (Example)

Imagine you have two VPCs:

  • VPC A (10.0.0.0/16) hosting an EC2-based API.
  • VPC B (192.168.0.0/16) running a web application.

To allow the web app in VPC B to communicate with the API in VPC A:

  1. Create a VPC Peering Connection between VPC A and VPC B.
  2. Update route tables in both VPCs: VPC A routes 192.168.0.0/16 to VPC Peering. VPC B routes 10.0.0.0/16 to VPC Peering.
  3. Now, instances in both VPCs can directly communicate using private IPs.


Limitations of VPC Peering

? Not Scalable – You must manually set up peering for each new VPC (N-to-N relationship). ? No Transitive Routing – If you peer VPC A ? VPC B and VPC B ? VPC C, A cannot talk to C. ? Increased Complexity – Managing multiple peering connections becomes difficult as VPC count increases.

?

VPC Peering Implementation in Terraform

Scenario: You need to enable bidirectional private communication between two VPCs.

Terraform Code: VPC Peering Between Two VPCs

provider "aws" {

  region = "us-east-1"

}

 

# Create VPC A

resource "aws_vpc" "vpc_a" {

  cidr_block = "10.0.0.0/16"

  tags = { Name = "VPC-A" }

}

 

# Create VPC B

resource "aws_vpc" "vpc_b" {

  cidr_block = "192.168.0.0/16"

  tags = { Name = "VPC-B" }

}

 

# Create a VPC Peering Connection

resource "aws_vpc_peering_connection" "peer_vpcs" {

  vpc_id      = aws_vpc.vpc_a.id

  peer_vpc_id = aws_vpc.vpc_b.id

  auto_accept = true

}

 

# Update route table for VPC A

resource "aws_route_table" "vpc_a_rt" {

  vpc_id = aws_vpc.vpc_a.id

}

 

resource "aws_route" "vpc_a_to_b" {

  route_table_id         = aws_route_table.vpc_a_rt.id

  destination_cidr_block = aws_vpc.vpc_b.cidr_block

  vpc_peering_connection_id = aws_vpc_peering_connection.peer_vpcs.id

}

 

resource "aws_route_table_association" "vpc_a_assoc" {

  subnet_id      = aws_subnet.subnet_a.id

  route_table_id = aws_route_table.vpc_a_rt.id

}

 

# Update route table for VPC B

resource "aws_route_table" "vpc_b_rt" {

  vpc_id = aws_vpc.vpc_b.id

}

 

resource "aws_route" "vpc_b_to_a" {

  route_table_id         = aws_route_table.vpc_b_rt.id

  destination_cidr_block = aws_vpc.vpc_a.cidr_block

  vpc_peering_connection_id = aws_vpc_peering_connection.peer_vpcs.id

}

 

resource "aws_route_table_association" "vpc_b_assoc" {

  subnet_id      = aws_subnet.subnet_b.id

  route_table_id = aws_route_table.vpc_b_rt.id

}

 

# Create Subnets for VPC A and VPC B

resource "aws_subnet" "subnet_a" {

  vpc_id                  = aws_vpc.vpc_a.id

  cidr_block              = "10.0.1.0/24"

}

 

resource "aws_subnet" "subnet_b" {

  vpc_id                  = aws_vpc.vpc_b.id

  cidr_block              = "192.168.1.0/24"

}

 

# Launch EC2 instance in VPC A

resource "aws_instance" "instance_a" {

  ami           = "ami-0c55b159cbfafe1f0"

  instance_type = "t2.micro"

  subnet_id     = aws_subnet.subnet_a.id

  tags = { Name = "Instance-VPC-A" }

}

 

# Launch EC2 instance in VPC B

resource "aws_instance" "instance_b" {

  ami           = "ami-0c55b159cbfafe1f0"

  instance_type = "t2.micro"

  subnet_id     = aws_subnet.subnet_b.id

  tags = { Name = "Instance-VPC-B" }

}        

Deployment Steps

  1. Save this as vpc_peering.tf.
  2. Run:
  3. terraform init
  4. terraform apply -auto-approve
  5. The two instances can now communicate privately over AWS’s network.?

?

2. Understanding AWS PrivateLink

AWS PrivateLink allows services in one VPC to be securely accessed by other VPCs and AWS accounts via interface endpoints.

? Key Features:

  • One-way communication (Consumer connects to Provider).
  • Works across regions.
  • Fully managed and scalable – No need for route table modifications.
  • No need for public IPs, NAT, or VPN – Reduces attack surface.

?

How AWS PrivateLink Works (Example)

Imagine:

  • You run a payment processing API in VPC A.
  • Multiple third-party vendors (other AWS accounts) need to access it securely.

Instead of exposing an Internet-facing API, you:

  1. Create an AWS PrivateLink endpoint in VPC A.
  2. Vendors create interface VPC endpoints in their VPCs.
  3. Vendors access the API securely without internet exposure.

?

Limitations of AWS PrivateLink

? One-way access – Consumer can talk to Provider, but not vice versa. ? Only TCP-based services – No support for ICMP, UDP, or VPC-to-VPC full networking. ? Additional cost – PrivateLink endpoints are charged per hour + data transfer fees.

?

AWS PrivateLink Implementation in Terraform

Scenario: You want to expose an internal service in one VPC (Provider) and allow another VPC (Consumer) to access it securely via PrivateLink.

Terraform Code: AWS PrivateLink Between Two VPCs

provider "aws" {

  region = "us-east-1"

}

 

# Provider VPC

resource "aws_vpc" "provider_vpc" {

  cidr_block = "10.1.0.0/16"

  tags = { Name = "Provider-VPC" }

}

 

# Consumer VPC

resource "aws_vpc" "consumer_vpc" {

  cidr_block = "10.2.0.0/16"

  tags = { Name = "Consumer-VPC" }

}

 

# Create PrivateLink Endpoint Service (Provider Side)

resource "aws_security_group" "pl_sg" {

  vpc_id = aws_vpc.provider_vpc.id

}

 

resource "aws_network_interface" "pl_interface" {

  subnet_id   = aws_subnet.provider_subnet.id

}

 

resource "aws_vpc_endpoint_service" "pl_service" {

  acceptance_required        = false

  network_load_balancer_arns = [aws_lb.provider_nlb.arn]

}

 

# Consumer Endpoint (VPC Endpoint)

resource "aws_vpc_endpoint" "consumer_endpoint" {

  vpc_id              = aws_vpc.consumer_vpc.id

  service_name        = aws_vpc_endpoint_service.pl_service.service_name

  vpc_endpoint_type   = "Interface"

  security_group_ids  = [aws_security_group.pl_sg.id]

  subnet_ids          = [aws_subnet.consumer_subnet.id]

}

 

# Subnets

resource "aws_subnet" "provider_subnet" {

  vpc_id            = aws_vpc.provider_vpc.id

  cidr_block        = "10.1.1.0/24"

}

 

resource "aws_subnet" "consumer_subnet" {

  vpc_id            = aws_vpc.consumer_vpc.id

  cidr_block        = "10.2.1.0/24"

}

 

# Create EC2 in Provider VPC (Private Service)

resource "aws_instance" "provider_instance" {

  ami           = "ami-0c55b159cbfafe1f0"

  instance_type = "t2.micro"

  subnet_id     = aws_subnet.provider_subnet.id

  tags = { Name = "Private-API-Server" }

}

 

# Create EC2 in Consumer VPC (Accessing Service)

resource "aws_instance" "consumer_instance" {

  ami           = "ami-0c55b159cbfafe1f0"

  instance_type = "t2.micro"

  subnet_id     = aws_subnet.consumer_subnet.id

  tags = { Name = "Consumer-App" }

}

 

# Create a Network Load Balancer for PrivateLink

resource "aws_lb" "provider_nlb" {

  name               = "private-nlb"

  internal           = true

  load_balancer_type = "network"

  subnets            = [aws_subnet.provider_subnet.id]

}        

Deployment Steps

  1. Save this as aws_privatelink.tf.
  2. Run:
  3. terraform init
  4. terraform apply -auto-approve
  5. The consumer instance can now access the provider service privately via AWS PrivateLink.?

?

3. VPC Peering vs. AWS PrivateLink: Key Differences

?4. When to Use VPC Peering vs. PrivateLink?

? Use VPC Peering When:

?? You need full network access (e.g., EC2 instances communicating across VPCs).

?? Both VPCs belong to the same organization.

?? Low latency & high bandwidth are critical.

?? You don’t need multi-account access.

Example:

  • Connecting microservices hosted in different VPCs.
  • Allowing multiple EC2 instances to communicate privately across VPCs.

?

? Use AWS PrivateLink When:

?? You want to expose a service securely without Internet exposure.

?? You need multi-account or third-party access.

?? You want scalability without managing peering connections.

?? You’re connecting to AWS-managed services like S3, RDS, or Lambda privately.

Example:

  • Hosting a private API that other teams or external customers need to access.
  • Connecting to AWS services like Amazon S3, DynamoDB, or Secrets Manager via VPC endpoints.?

5. Real-World Scenarios

Scenario 1: Multi-Region Microservices

A company runs two microservices in two different regions and needs them to communicate securely.

Solution: ? Use Inter-Region VPC Peering for direct, low-latency connectivity.

?

Scenario 2: SaaS Provider Exposing a Private API

A fintech company offers a private payment API to multiple clients across different AWS accounts.

Solution: ? Use AWS PrivateLink to provide secure, scalable access without Internet exposure.

?

Scenario 3: Hybrid Cloud with On-Premises Connectivity

An enterprise wants on-prem servers to access EC2 instances in AWS securely.

Solution: ? Use AWS Direct Connect with PrivateLink for secure, private communication.

?

Final Thoughts: Which One Should You Choose?

  • If you need full network access, VPC Peering is the best option.
  • If you need to?share services across AWS accounts or teams securely, AWS PrivateLink is the right choice.

For most modern, multi-account, or SaaS architectures, AWS PrivateLink is the preferred solution due to its scalability, security, and ease of management.

Which method do you use in your AWS architecture? Let’s discuss in the comments! ??

?

?

要查看或添加评论,请登录

Manish Kumar的更多文章

社区洞察