Today, we successfully implemented VPC Peering using Terraform, a foundational skill for anyone managing complex cloud infrastructure. This mini-project demonstrated how to securely connect separate network environments across different regions.
What is VPC Peering?
VPC peering is a networking connection between two Virtual Private Clouds (VPCs) that enables instances in either VPC to communicate with each other privately. This is achieved as if the instances were on the same network.
Why is this necessary?
In enterprise environments, you often need to share resources or data securely between different departments, environments (like Dev and Prod), or even AWS accounts. For example, a web server located in one VPC might need to securely retrieve data from a backend database residing in a separate VPC.
Without VPC peering, that data connection would have to traverse the Internet Gateway, exposing the traffic to the public internet—a major security risk. VPC peering allows this communication to occur over a private AWS backbone, ensuring security and low latency.
The Non-Negotiable Rules of Peering
Before establishing any connection, two rules are critical:
1. Non-Overlapping CIDR Ranges: The IP address ranges (CIDRs) of the two VPCs must not overlap. For our project, we used 10.0.0.0/16 for the primary VPC and 10.1.0.0/16 for the secondary VPC.
2. Bidirectional Connection: VPC peering is not a single connection; it requires a bidirectional setup. You must initiate a connection from VPC A to VPC B, and then establish a corresponding connection from VPC B back to VPC A.
Terraform Implementation: Multi-Region Setup
Our project involved provisioning VPCs in different AWS regions (US East 1 and US West 2). To manage resources across these distinct regions in a single Terraform configuration, we utilized aliases in our provider definition:
# Define Primary Provider (US East 1)
provider "aws" {
region = var.primary_region
alias = "primary"
}
# Define Secondary Provider (US West 2)
provider "aws" {
region = var.secondary_region
alias = "secondary"
}
Establishing the Connection
We used the aws_vpc_peering_connection resource to create the connection request (A to B) and then set up a corresponding resource to accept the request (B to A, or the acceptor).
# VPC Peering Connection Request (Primary to Secondary)
resource "aws_vpc_peering_connection" "primary_to_secondary" {
provider = aws.primary
vpc_id = aws_vpc.primary_vpc.id
peer_vpc_id = aws_vpc.secondary_vpc.id
peer_region = var.secondary_region
auto_accept = false # The destination must explicitly accept
}
# VPC Peering Connection Acceptor (Secondary accepts Primary's request)
resource "aws_vpc_peering_connection_accepter" "secondary_acceptor" {
provider = aws.secondary
vpc_peering_connection_id = aws_vpc_peering_connection.primary_to_secondary.id
auto_accept = true # Auto-accept the incoming request
}
The Crucial Routing Step
Creating the peering connection is only half the battle. To allow traffic to flow, we must update the Route Tables in both VPCs. Each VPC's route table must be configured to send traffic destined for the peer VPC's CIDR range (e.g., 10.1.0.0/16) to the newly created VPC peering connection ID.
This crucial step, combined with correctly configured security groups (allowing ICMP/Ping traffic between the VPC CIDR blocks), ensures successful private connectivity.
Advanced Caveat: Transitive Peering
During the project, we encountered a vital architectural lesson: Transitive Peering does not work.
If you connect:
- VPC A to VPC B
- VPC B to VPC C
Traffic will not automatically flow from VPC A to VPC C. To enable A and C to communicate privately, you must create a dedicated VPC peering connection between A and C as well. This is a key consideration when designing larger, interconnected networks.
By successfully provisioning and configuring VPC peering, we established secure, private communication between two instances running in separate regions, a vital step toward building complex, enterprise-grade infrastructure with Terraform.

Top comments (0)