Network Segmentation: VPC Peering and Transit Gateway
Having a single VPC for the entire infrastructure is fine for a startup. Problems start when prod, staging, dev, and the security department live in the same network: a developer with broad permissions can access the production environment through database ports. According to our analysis, 80% of incidents are related to poor network isolation. The mean time to recovery (MTTR) when a flat network is compromised is 48 hours, whereas with segmented networks it's under 2 hours. Source: AWS Well-Architected Framework, Network Pillar. Consequences: data leaks, downtime, customer loss. We design turnkey network segmentation—isolate environments, configure peering or Transit Gateway, describe everything in Terraform. Our engineers are AWS-certified (5+ years of experience) and have completed over 50 network isolation projects. A typical network segmentation project with VPC Peering saves operational costs.
Why a Single VPC Is Insufficient?
In a single VPC, controlling traffic between services is complex. Security Groups and NACLs help, but as you scale, the permissions matrix becomes unmanageable. One wrong rule, and staging can take down prod. Segmentation at the VPC level guarantees that even if policies are misconfigured, traffic won't physically flow between environments without an explicit route.
Architecture: What to Segment
Typical organization for a production infrastructure in AWS:
VPC: Production (10.0.0.0/16)
├── Public Subnet (10.0.1.0/24) — ALB, NAT Gateway
├── App Subnet (10.0.2.0/24) — ECS Tasks, EC2 applications
├── DB Subnet (10.0.3.0/24) — RDS, ElastiCache
└── Management Subnet (10.0.4.0/24) — Bastion, monitoring
VPC: Staging (10.1.0.0/16)
VPC: Dev (10.2.0.0/16)
VPC: Shared Services (10.3.0.0/16) — CI/CD runners, artifactsNo CIDR blocks overlap—this is a requirement for peering. We guarantee no overlap at the planning stage.
VPC Peering: Direct Connection
VPC Peering is a simple way to connect two VPCs. It is good for small topologies (2–3 VPCs). Let's look at an example: connect Production with Shared Services so that a CI/CD runner from the shared subnet can deploy to the application.
# Terraform: Peering between Production and Shared Services
resource "aws_vpc_peering_connection" "prod_to_shared" {
vpc_id = aws_vpc.production.id
peer_vpc_id = aws_vpc.shared_services.id
auto_accept = true
tags = {
Name = "prod-to-shared-services"
}
}
# Route from Production App Subnet to Shared Services
resource "aws_route" "prod_app_to_shared" {
route_table_id = aws_route_table.prod_app.id
destination_cidr_block = aws_vpc.shared_services.cidr_block
vpc_peering_connection_id = aws_vpc_peering_connection.prod_to_shared.id
}
# Route from Shared Services to Production (return)
resource "aws_route" "shared_to_prod" {
route_table_id = aws_route_table.shared_services.id
destination_cidr_block = aws_vpc.production.cidr_block
vpc_peering_connection_id = aws_vpc_peering_connection.prod_to_shared.id
}
# Security Group: only CI runner can reach App Subnet over SSH
resource "aws_security_group_rule" "allow_ci_ssh" {
type = "ingress"
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = [aws_subnet.shared_ci.cidr_block]
security_group_id = aws_security_group.prod_app.id
}
VPC Peering limitation: no transitive routing. If A peers with B, and B peers with C, traffic from A to C won't flow. For three or more VPCs, you need Transit Gateway.
How Transit Gateway Solves Transitive Routing?
Transit Gateway is a central router to which all VPCs connect. Any VPC can see any other through a common hub. You can configure TGW route tables so that prod sees shared services but not dev directly. This gives flexibility: you control who talks to whom with a single set of rules. For 10 VPCs, the number of routes with peering is 90, with TGW it's 10—a 10x reduction.
resource "aws_ec2_transit_gateway" "main" {
description = "Central TGW for all VPCs"
default_route_table_association = "disable"
default_route_table_propagation = "disable"
tags = {
Name = "main-tgw"
}
}
# Attachment for each VPC
resource "aws_ec2_transit_gateway_vpc_attachment" "production" {
transit_gateway_id = aws_ec2_transit_gateway.main.id
vpc_id = aws_vpc.production.id
subnet_ids = aws_subnet.prod_private[*].id
tags = {
Name = "tgw-attach-production"
}
}
resource "aws_ec2_transit_gateway_vpc_attachment" "shared_services" {
transit_gateway_id = aws_ec2_transit_gateway.main.id
vpc_id = aws_vpc.shared_services.id
subnet_ids = aws_subnet.shared_private[*].id
}
# Route Table: Production sees only Shared Services, not Dev
resource "aws_ec2_transit_gateway_route_table" "production" {
transit_gateway_id = aws_ec2_transit_gateway.main.id
tags = {
Name = "tgw-rt-production"
}
}
resource "aws_ec2_transit_gateway_route" "prod_to_shared" {
destination_cidr_block = "10.3.0.0/16"
transit_gateway_attachment_id = aws_ec2_transit_gateway_vpc_attachment.shared_services.id
transit_gateway_route_table_id = aws_ec2_transit_gateway_route_table.production.id
}
resource "aws_ec2_transit_gateway_route_table_association" "production" {
transit_gateway_attachment_id = aws_ec2_transit_gateway_vpc_attachment.production.id
transit_gateway_route_table_id = aws_ec2_transit_gateway_route_table.production.id
}
# Route in VPC for traffic through TGW
resource "aws_route" "prod_app_via_tgw" {
route_table_id = aws_route_table.prod_app.id
destination_cidr_block = "10.3.0.0/16"
transit_gateway_id = aws_ec2_transit_gateway.main.id
}
Comparison of VPC Peering and Transit Gateway
| Parameter | VPC Peering | Transit Gateway |
|---|---|---|
| Maximum VPCs | Up to 20 (peering with each) | Up to 1000 attachments |
| Transitive routing | No | Yes |
| Management complexity | Quadratic (N^2) | Linear (N) |
| Updates without downtime | No | Yes (when adding VPCs) |
| Cost | Free (traffic across AZ is billed) | Billed separately |
TGW pays off if you have more than three VPCs: you save up to 70% of time on route management and avoid manual configuration errors.
GCP: Shared VPC and VPC Network Peering
In GCP, VPC Network Peering is similar to AWS VPC Peering—also no transitivity. The recommended approach for organizations is Shared VPC (XPN): one Host Project owns the network, Service Projects use its subnets. This centralizes management and simplifies auditing.
# GCP Shared VPC
resource "google_compute_shared_vpc_host_project" "host" {
project = "my-host-project"
}
resource "google_compute_shared_vpc_service_project" "service" {
host_project = google_compute_shared_vpc_host_project.host.project
service_project = "my-service-project"
} How to Combine Security Groups and NACLs?
Security Groups (stateful) act at the ENI level and automatically allow return traffic. NACLs (stateless) work at the subnet level, rules are processed by number. Use SGs for micro-control at the resource level, NACLs for coarse blocking at the subnet level (e.g., fully block inbound traffic to the DB Subnet from all except the App Subnet).
| Characteristic | Security Group | NACL |
|---|---|---|
| Stateful/Stateless | Stateful | Stateless |
| Level | ENI (resource) | Subnet |
| Rules | Allow only | Allow and Deny |
| Rule limit | 60 per group | 20 per list (IPv4) |
| Processing | All rules evaluated | Order, first match |
| Return traffic | Automatically allowed | Explicit rule required |
resource "aws_network_acl" "db" {
vpc_id = aws_vpc.production.id
subnet_ids = aws_subnet.prod_db[*].id
# Allow only from App Subnet
ingress {
rule_no = 100
protocol = "tcp"
action = "allow"
cidr_block = aws_subnet.prod_app.cidr_block
from_port = 5432
to_port = 5432
}
# Everything else denied
ingress {
rule_no = 32766
protocol = "-1"
action = "deny"
cidr_block = "0.0.0.0/0"
from_port = 0
to_port = 0
}
} Full Network Audit Checklist
- Inventory all VPCs and subnets
- Check for CIDR overlap
- Analyze Security Groups and NACLs
- Assess necessity of transitive routing
- Choose between peering and Transit Gateway
- Migration plan with minimal downtime
What's Included
- Audit of current network architecture and communication matrix
- Design of CIDR plan and segmentation scheme
- Development of Terraform modules for VPC, Peering, Transit Gateway, NACL, Security Groups
- Route configuration and connectivity tests
- Creation of runbook and team training
- Configuration warranty (30 days of support)
We'll evaluate your project — contact us. Timeline: from 3 days to 4 weeks depending on complexity. Order an engineer consultation today.
Work Process
- Analysis: inventory services, ports, security requirements. Build a communication matrix.
- Design: CIDR plan, choose VPC Peering or Transit Gateway, prepare a schema.
- Implementation: Terraform code, code review, tests in dev account.
- Testing: connectivity tests, Security Group policies, fault tolerance.
- Deployment: apply in prod with minimal window.
Write to us — we'll reply within a day and find the best solution.







