
Architecting Networks
- 55 installs
- 426 repo stars
- Updated December 11, 2025
- ancoleman/ai-design-components
Architecting Networks is a Claude Code skill that provides VPC, subnet, NAT, and zero-trust decision frameworks for designing cloud network architectures.
About
Architecting Networks is a Claude Code skill for designing secure, scalable cloud network architectures across AWS, GCP, and Azure. It provides decision frameworks for VPC topology, subnet strategy, NAT Gateway placement, zero trust implementation, and hybrid connectivity. A developer uses it when planning VPC/VNet topology, implementing network segmentation, or connecting multiple VPCs or on-premises networks.
- Five VPC patterns (flat, multi-VPC, hub-and-spoke, full mesh, hybrid) with selection framework
- Three-tier subnet strategy, CIDR planning, and NAT Gateway cost/resilience decisions
- Zero trust principles and security-group guidance across AWS, GCP, and Azure
Architecting Networks by the numbers
- 55 all-time installs (skills.sh)
- Ranked #699 of 1,039 Cloud & Infrastructure skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
architecting-networks capabilities & compatibility
- Capabilities
- administering linux · architecting security · architecting data
- Works with
- aws · gcp · azure
- Use cases
- devops · security audit · research
What architecting-networks says it does
Design cloud network architectures with VPC patterns, subnet strategies, zero trust principles, and hybrid connectivity.
Design secure, scalable cloud network architectures using proven patterns across AWS, GCP, and Azure.
npx skills add https://github.com/ancoleman/ai-design-components --skill architecting-networksAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 55 |
|---|---|
| repo stars | ★ 426 |
| Last updated | December 11, 2025 |
| Repository | ancoleman/ai-design-components ↗ |
What it does
Design cloud VPC topology, subnet tiers, NAT strategy, and segmentation across AWS, GCP, and Azure.
Who is it for?
Cloud and platform engineers planning VPC topology and network segmentation.
Skip if: Application-level code or non-cloud on-premises-only networking.
When should I use this skill?
You are designing VPC/VNet topology, segmentation, or multi-VPC/hybrid connectivity.
What you get
A selected VPC pattern, subnet tiering, NAT strategy, and segmentation model for the workload.
By the numbers
- 5 core network architecture patterns
- 3-tier subnet design (public, private, database)
Files
Network Architecture
Design secure, scalable cloud network architectures using proven patterns across AWS, GCP, and Azure. This skill provides decision frameworks for VPC design, subnet strategy, zero trust implementation, and hybrid connectivity.
When to Use This Skill
Invoke this skill when:
- Designing VPC/VNet topology for new cloud environments
- Implementing network segmentation and security controls
- Planning multi-VPC or multi-cloud connectivity
- Establishing hybrid cloud connectivity (on-premises to cloud)
- Migrating from flat network to sophisticated architecture
- Implementing zero trust network principles
- Optimizing network costs and performance
Core Network Architecture Patterns
Pattern 1: Flat (Single VPC) Architecture
Use When: Small applications, single environment, simple security requirements, team < 10 engineers
Characteristics:
- All resources in one VPC with subnet-level segmentation
- Public, private, and database subnet tiers
- Simplest to understand and manage
- No inter-VPC routing complexity
Tradeoffs:
- ✓ Lowest cost, fastest to set up
- ✗ Poor isolation, difficult to scale, entire VPC is blast radius
Pattern 2: Multi-VPC (Isolated) Architecture
Use When: Multiple environments (dev/staging/prod), strong isolation requirements, compliance mandates separation
Characteristics:
- Separate VPCs per environment or workload
- No direct connectivity without explicit setup
- Independent CIDR ranges
Tradeoffs:
- ✓ Strong blast radius containment, clear security boundaries
- ✗ Management overhead, duplicate infrastructure, higher costs
Pattern 3: Hub-and-Spoke (Transit Gateway) Architecture
Use When: 5+ VPCs need communication, centralized security inspection required, hybrid connectivity, multi-account setup
Characteristics:
- Central hub VPC/Transit Gateway
- Spoke VPCs connect to hub
- All inter-VPC traffic routes through hub
Tradeoffs:
- ✓ Simplified routing, centralized security, scales easily (100+ VPCs)
- ✗ Transit Gateway costs (~$0.05/hour + $0.02/GB), increased latency (hub hop)
Pattern 4: Full Mesh (VPC Peering) Architecture
Use When: Small number of VPCs (< 5), low latency critical, no centralized inspection needed
Characteristics:
- Every VPC directly connected via peering
- Direct VPC-to-VPC communication
Tradeoffs:
- ✓ Lowest latency, no Transit Gateway costs
- ✗ Management complexity scales as O(n²), doesn't scale beyond ~10 VPCs
Pattern 5: Hybrid (Multi-Pattern) Architecture
Use When: Large enterprise with diverse requirements, balancing cost/performance/security
Characteristics:
- Hub-spoke for most VPCs + direct peering for latency-sensitive pairs
- Combination based on workload requirements
Tradeoffs:
- ✓ Optimized for specific needs
- ✗ More complex to design and manage
Pattern Selection Framework
Number of VPCs?
│
├─► 1 VPC → Flat (Single VPC)
├─► 2-4 VPCs + No inter-VPC communication → Multi-VPC (Isolated)
├─► 2-5 VPCs + Low latency critical → Full Mesh (VPC Peering)
├─► 5+ VPCs + Centralized inspection → Hub-and-Spoke (Transit Gateway)
└─► 10+ VPCs + Mixed requirements → Hybrid (Multi-Pattern)
Additional Considerations:
├─► Hybrid connectivity required? → Hub-and-Spoke preferred
├─► Centralized egress/inspection? → Hub-and-Spoke with Inspection VPC
├─► Multi-account environment? → Hub-and-Spoke with AWS RAM sharing
└─► Cost optimization priority? → Flat or Multi-VPC (avoid TGW fees)Subnet Strategy
Standard Three-Tier Design
Public Subnets:
- Route to Internet Gateway
- Use for load balancers, bastion hosts, NAT Gateways
- CIDR: /24 to /27 (256 to 32 IPs)
Private Subnets:
- Route to NAT Gateway for outbound
- Use for application servers, containers, compute workloads
- CIDR: /20 to /22 (4,096 to 1,024 IPs)
Database Subnets:
- No direct internet route
- Use for RDS, ElastiCache, managed databases
- CIDR: /24 to /26 (256 to 64 IPs)
Multi-AZ Distribution
Production: Distribute each tier across 3 Availability Zones minimum Dev/Test: 1-2 AZs acceptable for cost savings
CIDR Block Planning
VPC Sizing:
- /16 (65,536 IPs) - Large production environments
- /20 (4,096 IPs) - Medium environments
- /24 (256 IPs) - Small/dev environments
Critical Rules:
- Non-overlapping CIDR ranges across VPCs
- Coordinate with on-premises network team for hybrid connectivity
- Reserve address space for future expansion
For detailed subnet planning, see references/subnet-strategy.md
NAT Gateway Strategy
Decision Framework
Cost vs Resilience?
│
├─► Cost Priority (Dev/Test)
│ └─► Single NAT Gateway (~$32/month)
│ └─► Risk: Single point of failure
│
├─► Balanced (Most Production)
│ └─► One NAT Gateway per AZ (~$96/month for 3 AZs)
│ └─► Resilience: AZ failure doesn't break connectivity
│
└─► Maximum Resilience
└─► Multiple NAT Gateways per AZ + monitoring
└─► Critical workloads, SLA-dependent
Alternative: Centralized Egress Pattern
└─► Hub-and-Spoke: Single egress VPC with NAT
└─► Reduces NAT Gateway count, centralized loggingNo Outbound Internet Needed?
- Skip NAT Gateway entirely (cost savings)
- Use VPC Endpoints for AWS service access
Security Controls
Security Groups (Recommended)
Characteristics:
- Stateful (return traffic auto-allowed)
- Instance-level control
- Allow rules only (implicit deny)
- Can reference other security groups
Use For:
- Service-to-service communication
- Instance-level security
- Most common use case
Best Practices:
- Use descriptive names (app-alb-sg, app-backend-sg)
- Reference other security groups instead of CIDR blocks
- Keep rules minimal and specific
Network ACLs (Optional)
Characteristics:
- Stateless (must allow both request and response)
- Subnet-level control
- Allow and deny rules
- Processes rules in order (lowest number first)
Use For:
- Explicit deny rules (block specific IPs)
- Compliance requirements (defense in depth)
- Additional layer beyond security groups
Best Practices:
- Use sparingly (complex to manage)
- Remember to allow ephemeral ports (1024-65535)
- Test thoroughly (stateless nature causes issues)
For security group architecture patterns, see references/security-controls.md
Zero Trust Principles
Core Tenets
1. Never Trust, Always Verify
- Authenticate every request regardless of source
- No implicit trust based on network location
2. Least Privilege Access
- Grant minimum necessary permissions
- Time-bound access (just-in-time)
3. Assume Breach
- Segment network aggressively
- Monitor all traffic
- Rapid detection and response
Implementation Patterns
Microsegmentation:
- Isolate every workload with granular security group rules
- Service-to-service communication only between specific services
- Reduce blast radius
Identity-Based Access:
- Use IAM roles instead of IP addresses for authorization
- VPC Endpoints with IAM policies
- Service-to-service identity verification
Continuous Verification:
- VPC Flow Logs for traffic analysis
- Monitor rejected connections
- Alert on anomalies
For zero trust architecture patterns, see references/zero-trust-networking.md
Hybrid Connectivity
VPN (Virtual Private Network)
Use When: Dev/test environments, backup connectivity, temporary connections
Characteristics:
- Encrypted tunnel over public internet
- Throughput: ~1.25 Gbps per tunnel
- Latency: Variable (internet-dependent)
- Cost: Low (~$0.05/hour + data transfer)
- Setup: Quick (no contracts)
Direct Connect / ExpressRoute / Cloud Interconnect
Use When: Production workloads, large data transfers, real-time applications
Characteristics:
- Dedicated network connection (bypasses public internet)
- Throughput: Up to 100 Gbps
- Latency: Low and consistent
- Cost: Higher (port fees + data transfer)
- Setup: Slower (contracts, coordination)
Transit Gateway + Direct Connect
Use When: Multiple VPCs need on-premises connectivity
Benefits:
- Single Direct Connect connection → Transit Gateway → Multiple VPCs
- Cost efficient and scalable
- Centralized hybrid connectivity
For hybrid connectivity patterns and examples, see references/hybrid-connectivity.md
Multi-Cloud Networking
Unified Concepts Across Providers
| Concept | AWS | GCP | Azure |
|---|---|---|---|
| Virtual Network | VPC | VPC | Virtual Network (VNet) |
| Subnets | Subnets (AZ-scoped) | Subnets (Regional) | Subnets |
| NAT | NAT Gateway | Cloud NAT | NAT Gateway |
| Peering | VPC Peering | VPC Peering | VNet Peering |
| Hub-Spoke | Transit Gateway | Cloud Router | Virtual WAN |
| Private Endpoints | PrivateLink | Private Service Connect | Private Link |
| Hybrid VPN | VPN | Cloud VPN | VPN Gateway |
| Hybrid Dedicated | Direct Connect | Cloud Interconnect | ExpressRoute |
Provider-Specific Best Practices
AWS:
- Multi-AZ baseline for production
- Prefer Transit Gateway for 5+ VPCs
- Use VPC Endpoints to avoid NAT charges
GCP:
- Custom mode VPC (not auto-mode)
- Start with single VPC, use Shared VPC for multi-project
- Grant network user role at subnet level
Azure:
- Hub-and-spoke network topology as standard
- Few large VNets vs many small VNets
- Private endpoints for Azure services
For multi-cloud implementations, see references/multi-cloud-networking.md
Network Observability
VPC Flow Logs
Enable Flow Logs for:
- Traffic analysis and troubleshooting
- Security monitoring (detect unauthorized access)
- Cost attribution by network path
- Compliance requirements
Configuration:
- Traffic type: ALL (capture accepted and rejected)
- Aggregation interval: 1-10 minutes
- Destination: CloudWatch Logs or S3
Monitoring Patterns
Monitor:
- Rejected connections (security anomalies)
- Traffic volume spikes
- Cross-VPC communication patterns
- NAT Gateway utilization
Alert On:
- Spike in rejected connections
- Unusual traffic patterns
- High data transfer costs
- Network errors
For observability patterns and flow log analysis, see references/network-observability.md
Cost Optimization
Common Cost Drivers
1. NAT Gateway: $0.045/hour + $0.045/GB data processed 2. Transit Gateway: $0.05/hour/attachment + $0.02/GB 3. Data Transfer: Egress charges vary by destination 4. VPN/Direct Connect: Port fees + data transfer
Optimization Strategies
Reduce NAT Gateway Costs:
- Use VPC Endpoints for AWS services (S3, DynamoDB)
- Centralized egress VPC pattern
- Single NAT Gateway for dev/test (accept availability risk)
Reduce Data Transfer Costs:
- Keep traffic within same region
- Use VPC Endpoints instead of public internet
- Private connectivity for high-volume transfers
Avoid Transit Gateway Costs:
- Use VPC Peering for small number of VPCs (< 5)
- Direct peering for latency-sensitive pairs
For detailed cost optimization strategies, see references/cost-optimization.md
Implementation Workflow
Step 1: Analyze Requirements
- How many VPCs/environments needed?
- Hybrid connectivity required?
- Latency requirements?
- Security/compliance requirements?
- Budget constraints?
Step 2: Select Pattern
Use pattern selection framework above to choose:
- Flat, Multi-VPC, Hub-Spoke, Mesh, or Hybrid
Step 3: Design Subnets
- Calculate CIDR blocks (non-overlapping)
- Plan multi-AZ distribution
- Determine public/private/database tiers
Step 4: Configure Security
- Design security group architecture
- Plan microsegmentation
- Configure Network ACLs if needed
Step 5: Implement with IaC
Use infrastructure-as-code skill to implement with Terraform/Pulumi
Step 6: Enable Observability
- Configure VPC Flow Logs
- Set up monitoring and alerting
- Cost tracking
Quick Reference
VPC Pattern Selection
| Requirement | Recommended Pattern |
|---|---|
| Single environment | Flat (Single VPC) |
| Multiple isolated environments | Multi-VPC (Isolated) |
| 2-5 VPCs, low latency | Full Mesh (Peering) |
| 5+ VPCs, centralized security | Hub-and-Spoke (TGW) |
| Hybrid connectivity | Hub-and-Spoke (TGW) |
| Cost optimization | Flat or Multi-VPC |
NAT Gateway Configuration
| Scenario | Configuration | Monthly Cost (3 AZs) |
|---|---|---|
| Dev/Test | Single NAT | ~$32 |
| Production | NAT per AZ | ~$96 |
| Centralized Egress | Hub VPC NAT | ~$32-96 |
Hybrid Connectivity
| Requirement | Solution | Throughput | Latency |
|---|---|---|---|
| Dev/Test | VPN | ~1.25 Gbps | Variable |
| Production | Direct Connect | Up to 100 Gbps | Low, consistent |
| Backup | VPN (backup to DX) | ~1.25 Gbps | Variable |
Reference Documentation
Detailed Guides:
references/vpc-design-patterns.md- Comprehensive pattern descriptions with diagramsreferences/subnet-strategy.md- CIDR planning, IPAM, multi-AZ best practicesreferences/zero-trust-networking.md- Microsegmentation, IAM integration, continuous verificationreferences/hybrid-connectivity.md- VPN, Direct Connect, Transit Gateway patternsreferences/multi-cloud-networking.md- AWS, GCP, Azure implementationsreferences/security-controls.md- Security groups, NACLs, firewall patternsreferences/private-networking.md- VPC Endpoints, PrivateLink, Private Service Connectreferences/multi-region-networking.md- Cross-region peering, global load balancingreferences/network-observability.md- Flow logs, monitoring, troubleshootingreferences/cost-optimization.md- Egress reduction, NAT strategies
Code Examples:
examples/aws/- AWS VPC patterns (flat, hub-spoke, peering, VPN, Direct Connect)examples/gcp/- GCP VPC patterns (custom VPC, Shared VPC, Cloud Interconnect)examples/azure/- Azure VNet patterns (hub-spoke, peering, ExpressRoute)examples/multi-cloud/- Cross-cloud connectivity examples
Utility Scripts:
scripts/cidr-calculator.py- Calculate CIDR blocks and plan IP addressingscripts/cost-estimator.sh- Estimate network infrastructure costsscripts/validate-sg-rules.py- Validate security group rule configurationsscripts/flow-log-analyzer.py- Analyze VPC flow logs for security and cost
Integration with Other Skills
Use `infrastructure-as-code` skill to:
- Implement network architectures with Terraform/Pulumi
- Version control network configurations
- Automate network provisioning
Use `kubernetes-operations` skill to:
- Configure Kubernetes networking (CNI) on top of VPC design
- Implement pod networking and service meshes
Use `security-hardening` skill to:
- Implement firewall rules and WAF configurations
- Configure network-level DDoS protection
- Set up intrusion detection systems
Use `observability` skill to:
- Implement comprehensive network monitoring
- Set up distributed tracing across network boundaries
- Configure performance dashboards
Use `disaster-recovery` skill to:
- Design multi-region failover networking
- Implement cross-region backup connectivity
- Plan network recovery procedures
/**
* Flat (Single VPC) Architecture Example - AWS
*
* Demonstrates: Basic three-tier VPC with public, private, and database subnets
*
* Use Case: Small applications, single environment, simple security requirements
*
* Prerequisites:
* - Terraform >= 1.0
* - AWS provider configured
*
* Usage:
* terraform init
* terraform plan
* terraform apply
*/
terraform {
required_version = ">= 1.0"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
provider "aws" {
region = var.aws_region
}
variable "aws_region" {
description = "AWS region"
type = string
default = "us-east-1"
}
variable "environment" {
description = "Environment name"
type = string
default = "dev"
}
# VPC Module
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "~> 5.0"
name = "${var.environment}-vpc"
cidr = "10.0.0.0/16"
# Availability Zones
azs = ["${var.aws_region}a", "${var.aws_region}b", "${var.aws_region}c"]
# Public Subnets (for ALB, NAT Gateways)
public_subnets = [
"10.0.1.0/24", # us-east-1a
"10.0.2.0/24", # us-east-1b
"10.0.3.0/24" # us-east-1c
]
# Private Subnets (for application workloads)
private_subnets = [
"10.0.10.0/24", # us-east-1a
"10.0.11.0/24", # us-east-1b
"10.0.12.0/24" # us-east-1c
]
# Database Subnets (for RDS)
database_subnets = [
"10.0.20.0/24", # us-east-1a
"10.0.21.0/24", # us-east-1b
"10.0.22.0/24" # us-east-1c
]
# NAT Gateway Configuration
# For production: one_nat_gateway_per_az = true (resilient, higher cost)
# For dev/test: single_nat_gateway = true (cost-optimized, single point of failure)
enable_nat_gateway = true
single_nat_gateway = false # NAT per AZ for resilience
one_nat_gateway_per_az = true
# DNS Configuration
enable_dns_hostnames = true
enable_dns_support = true
# VPC Endpoints for cost optimization (avoid NAT charges)
enable_s3_endpoint = true # Gateway endpoint (free)
enable_dynamodb_endpoint = true # Gateway endpoint (free)
# Create database subnet group
create_database_subnet_group = true
# Tags
tags = {
Terraform = "true"
Environment = var.environment
Pattern = "flat-vpc"
}
public_subnet_tags = {
Tier = "public"
}
private_subnet_tags = {
Tier = "private"
}
database_subnet_tags = {
Tier = "database"
}
}
# VPC Flow Logs
resource "aws_cloudwatch_log_group" "vpc_flow_log" {
name = "/aws/vpc/${module.vpc.vpc_id}/flow-logs"
retention_in_days = 7 # 7 days for dev, 30+ for production
tags = {
Name = "${var.environment}-vpc-flow-logs"
Environment = var.environment
}
}
resource "aws_iam_role" "vpc_flow_log" {
name = "${var.environment}-vpc-flow-log-role"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Principal = {
Service = "vpc-flow-logs.amazonaws.com"
}
Action = "sts:AssumeRole"
}
]
})
tags = {
Name = "${var.environment}-vpc-flow-log-role"
}
}
resource "aws_iam_role_policy" "vpc_flow_log" {
name = "${var.environment}-vpc-flow-log-policy"
role = aws_iam_role.vpc_flow_log.id
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Action = [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents",
"logs:DescribeLogGroups",
"logs:DescribeLogStreams"
]
Resource = "*"
}
]
})
}
resource "aws_flow_log" "vpc" {
iam_role_arn = aws_iam_role.vpc_flow_log.arn
log_destination = aws_cloudwatch_log_group.vpc_flow_log.arn
traffic_type = "ALL" # Capture both accepted and rejected traffic
vpc_id = module.vpc.vpc_id
tags = {
Name = "${var.environment}-vpc-flow-log"
Environment = var.environment
}
}
# Security Groups
resource "aws_security_group" "alb" {
name = "${var.environment}-alb-sg"
description = "Security group for Application Load Balancer"
vpc_id = module.vpc.vpc_id
# Inbound HTTPS from internet
ingress {
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
description = "HTTPS from internet"
}
# Inbound HTTP from internet (redirect to HTTPS)
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
description = "HTTP from internet"
}
# Outbound to backend
egress {
from_port = 8080
to_port = 8080
protocol = "tcp"
security_groups = [aws_security_group.backend.id]
description = "To backend service"
}
tags = {
Name = "${var.environment}-alb-sg"
Environment = var.environment
}
}
resource "aws_security_group" "backend" {
name = "${var.environment}-backend-sg"
description = "Security group for backend application"
vpc_id = module.vpc.vpc_id
# Inbound from ALB only
ingress {
from_port = 8080
to_port = 8080
protocol = "tcp"
security_groups = [aws_security_group.alb.id]
description = "From ALB only"
}
# Outbound to database
egress {
from_port = 5432
to_port = 5432
protocol = "tcp"
security_groups = [aws_security_group.database.id]
description = "To PostgreSQL database"
}
# Outbound to internet (for package updates, API calls)
egress {
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
description = "HTTPS to internet"
}
tags = {
Name = "${var.environment}-backend-sg"
Environment = var.environment
}
}
resource "aws_security_group" "database" {
name = "${var.environment}-database-sg"
description = "Security group for database"
vpc_id = module.vpc.vpc_id
# Inbound from backend only
ingress {
from_port = 5432
to_port = 5432
protocol = "tcp"
security_groups = [aws_security_group.backend.id]
description = "From backend only"
}
# No egress rules needed (database doesn't initiate connections)
# Some egress required for AWS health checks
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
description = "Required for AWS health checks"
}
tags = {
Name = "${var.environment}-database-sg"
Environment = var.environment
}
}
# Outputs
output "vpc_id" {
description = "VPC ID"
value = module.vpc.vpc_id
}
output "vpc_cidr" {
description = "VPC CIDR block"
value = module.vpc.vpc_cidr_block
}
output "public_subnets" {
description = "Public subnet IDs"
value = module.vpc.public_subnets
}
output "private_subnets" {
description = "Private subnet IDs"
value = module.vpc.private_subnets
}
output "database_subnets" {
description = "Database subnet IDs"
value = module.vpc.database_subnets
}
output "nat_gateway_ids" {
description = "NAT Gateway IDs"
value = module.vpc.natgw_ids
}
output "alb_security_group_id" {
description = "ALB Security Group ID"
value = aws_security_group.alb.id
}
output "backend_security_group_id" {
description = "Backend Security Group ID"
value = aws_security_group.backend.id
}
output "database_security_group_id" {
description = "Database Security Group ID"
value = aws_security_group.database.id
}
/**
* Hub-and-Spoke (Transit Gateway) Architecture Example - AWS
*
* Demonstrates: Transit Gateway connecting multiple VPCs
*
* Use Case: 5+ VPCs need communication, centralized security, hybrid connectivity
*
* Prerequisites:
* - Terraform >= 1.0
* - AWS provider configured
*
* Usage:
* terraform init
* terraform plan
* terraform apply
*/
terraform {
required_version = ">= 1.0"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
provider "aws" {
region = var.aws_region
}
variable "aws_region" {
description = "AWS region"
type = string
default = "us-east-1"
}
# Transit Gateway (Hub)
resource "aws_ec2_transit_gateway" "main" {
description = "Main Transit Gateway for hub-spoke"
amazon_side_asn = 64512
default_route_table_association = "disable" # Use custom route tables
default_route_table_propagation = "disable"
dns_support = "enable"
vpn_ecmp_support = "enable"
tags = {
Name = "main-tgw"
Pattern = "hub-spoke"
}
}
# Production VPC (Spoke)
module "vpc_prod" {
source = "terraform-aws-modules/vpc/aws"
version = "~> 5.0"
name = "prod-vpc"
cidr = "10.0.0.0/16"
azs = ["${var.aws_region}a", "${var.aws_region}b", "${var.aws_region}c"]
private_subnets = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"]
enable_nat_gateway = true
one_nat_gateway_per_az = true
enable_dns_hostnames = true
tags = {
Environment = "production"
Role = "spoke"
}
}
# Development VPC (Spoke)
module "vpc_dev" {
source = "terraform-aws-modules/vpc/aws"
version = "~> 5.0"
name = "dev-vpc"
cidr = "10.1.0.0/16"
azs = ["${var.aws_region}a", "${var.aws_region}b"]
private_subnets = ["10.1.1.0/24", "10.1.2.0/24"]
enable_nat_gateway = true
single_nat_gateway = true # Cost optimization for dev
enable_dns_hostnames = true
tags = {
Environment = "development"
Role = "spoke"
}
}
# Shared Services VPC (Spoke)
module "vpc_shared" {
source = "terraform-aws-modules/vpc/aws"
version = "~> 5.0"
name = "shared-services-vpc"
cidr = "10.2.0.0/16"
azs = ["${var.aws_region}a", "${var.aws_region}b", "${var.aws_region}c"]
private_subnets = ["10.2.1.0/24", "10.2.2.0/24", "10.2.3.0/24"]
enable_nat_gateway = true
one_nat_gateway_per_az = true
enable_dns_hostnames = true
tags = {
Environment = "shared"
Role = "spoke"
}
}
# TGW Attachment: Production VPC
resource "aws_ec2_transit_gateway_vpc_attachment" "prod" {
transit_gateway_id = aws_ec2_transit_gateway.main.id
vpc_id = module.vpc_prod.vpc_id
subnet_ids = module.vpc_prod.private_subnets
dns_support = "enable"
transit_gateway_default_route_table_association = false
transit_gateway_default_route_table_propagation = false
tags = {
Name = "prod-tgw-attachment"
}
}
# TGW Attachment: Development VPC
resource "aws_ec2_transit_gateway_vpc_attachment" "dev" {
transit_gateway_id = aws_ec2_transit_gateway.main.id
vpc_id = module.vpc_dev.vpc_id
subnet_ids = module.vpc_dev.private_subnets
dns_support = "enable"
transit_gateway_default_route_table_association = false
transit_gateway_default_route_table_propagation = false
tags = {
Name = "dev-tgw-attachment"
}
}
# TGW Attachment: Shared Services VPC
resource "aws_ec2_transit_gateway_vpc_attachment" "shared" {
transit_gateway_id = aws_ec2_transit_gateway.main.id
vpc_id = module.vpc_shared.vpc_id
subnet_ids = module.vpc_shared.private_subnets
dns_support = "enable"
transit_gateway_default_route_table_association = false
transit_gateway_default_route_table_propagation = false
tags = {
Name = "shared-tgw-attachment"
}
}
# TGW Route Table: Production
resource "aws_ec2_transit_gateway_route_table" "prod" {
transit_gateway_id = aws_ec2_transit_gateway.main.id
tags = {
Name = "prod-tgw-rt"
}
}
# TGW Route Table: Development
resource "aws_ec2_transit_gateway_route_table" "dev" {
transit_gateway_id = aws_ec2_transit_gateway.main.id
tags = {
Name = "dev-tgw-rt"
}
}
# TGW Route Table: Shared Services
resource "aws_ec2_transit_gateway_route_table" "shared" {
transit_gateway_id = aws_ec2_transit_gateway.main.id
tags = {
Name = "shared-tgw-rt"
}
}
# Associate Production VPC with its route table
resource "aws_ec2_transit_gateway_route_table_association" "prod" {
transit_gateway_attachment_id = aws_ec2_transit_gateway_vpc_attachment.prod.id
transit_gateway_route_table_id = aws_ec2_transit_gateway_route_table.prod.id
}
# Associate Development VPC with its route table
resource "aws_ec2_transit_gateway_route_table_association" "dev" {
transit_gateway_attachment_id = aws_ec2_transit_gateway_vpc_attachment.dev.id
transit_gateway_route_table_id = aws_ec2_transit_gateway_route_table.dev.id
}
# Associate Shared Services VPC with its route table
resource "aws_ec2_transit_gateway_route_table_association" "shared" {
transit_gateway_attachment_id = aws_ec2_transit_gateway_vpc_attachment.shared.id
transit_gateway_route_table_id = aws_ec2_transit_gateway_route_table.shared.id
}
# Route: Production can reach Shared Services
resource "aws_ec2_transit_gateway_route" "prod_to_shared" {
destination_cidr_block = module.vpc_shared.vpc_cidr_block
transit_gateway_attachment_id = aws_ec2_transit_gateway_vpc_attachment.shared.id
transit_gateway_route_table_id = aws_ec2_transit_gateway_route_table.prod.id
}
# Route: Development can reach Shared Services
resource "aws_ec2_transit_gateway_route" "dev_to_shared" {
destination_cidr_block = module.vpc_shared.vpc_cidr_block
transit_gateway_attachment_id = aws_ec2_transit_gateway_vpc_attachment.shared.id
transit_gateway_route_table_id = aws_ec2_transit_gateway_route_table.dev.id
}
# Route: Shared Services can reach Production
resource "aws_ec2_transit_gateway_route" "shared_to_prod" {
destination_cidr_block = module.vpc_prod.vpc_cidr_block
transit_gateway_attachment_id = aws_ec2_transit_gateway_vpc_attachment.prod.id
transit_gateway_route_table_id = aws_ec2_transit_gateway_route_table.shared.id
}
# Route: Shared Services can reach Development
resource "aws_ec2_transit_gateway_route" "shared_to_dev" {
destination_cidr_block = module.vpc_dev.vpc_cidr_block
transit_gateway_attachment_id = aws_ec2_transit_gateway_vpc_attachment.dev.id
transit_gateway_route_table_id = aws_ec2_transit_gateway_route_table.shared.id
}
# VPC Routes: Production private subnets to TGW
resource "aws_route" "prod_private_to_tgw" {
count = length(module.vpc_prod.private_route_table_ids)
route_table_id = module.vpc_prod.private_route_table_ids[count.index]
destination_cidr_block = "10.0.0.0/8" # All RFC1918 10.x traffic to TGW
transit_gateway_id = aws_ec2_transit_gateway.main.id
}
# VPC Routes: Development private subnets to TGW
resource "aws_route" "dev_private_to_tgw" {
count = length(module.vpc_dev.private_route_table_ids)
route_table_id = module.vpc_dev.private_route_table_ids[count.index]
destination_cidr_block = "10.0.0.0/8"
transit_gateway_id = aws_ec2_transit_gateway.main.id
}
# VPC Routes: Shared Services private subnets to TGW
resource "aws_route" "shared_private_to_tgw" {
count = length(module.vpc_shared.private_route_table_ids)
route_table_id = module.vpc_shared.private_route_table_ids[count.index]
destination_cidr_block = "10.0.0.0/8"
transit_gateway_id = aws_ec2_transit_gateway.main.id
}
# Outputs
output "transit_gateway_id" {
description = "Transit Gateway ID"
value = aws_ec2_transit_gateway.main.id
}
output "prod_vpc_id" {
description = "Production VPC ID"
value = module.vpc_prod.vpc_id
}
output "dev_vpc_id" {
description = "Development VPC ID"
value = module.vpc_dev.vpc_id
}
output "shared_vpc_id" {
description = "Shared Services VPC ID"
value = module.vpc_shared.vpc_id
}
output "routing_summary" {
description = "Routing summary"
value = {
prod_to_shared = "10.0.0.0/16 → TGW → 10.2.0.0/16"
dev_to_shared = "10.1.0.0/16 → TGW → 10.2.0.0/16"
shared_to_prod = "10.2.0.0/16 → TGW → 10.0.0.0/16"
shared_to_dev = "10.2.0.0/16 → TGW → 10.1.0.0/16"
prod_to_dev_blocked = "No direct route (security isolation)"
}
}
skill: "architecting-networks"
version: "1.0"
domain: "infrastructure"
base_outputs:
# Network architecture design document
- path: "docs/network-architecture.md"
must_contain: ["VPC", "subnet", "CIDR"]
description: "Network architecture design document describing VPC topology, subnet strategy, and connectivity patterns"
# CIDR block planning
- path: "docs/cidr-plan.md"
must_contain: ["CIDR", "subnet", "IP"]
description: "CIDR block allocation plan showing IP addressing scheme and subnet distribution"
# Security group architecture
- path: "docs/security-groups.md"
must_contain: ["security group", "ingress", "egress"]
description: "Security group design showing service-to-service access patterns"
conditional_outputs:
maturity:
starter:
# Single VPC flat architecture
- path: "infrastructure/network/vpc.tf"
must_contain: ["resource \"aws_vpc\"", "public_subnet", "private_subnet"]
description: "Basic flat VPC with public/private subnet tiers"
- path: "infrastructure/network/security-groups.tf"
must_contain: ["resource \"aws_security_group\""]
description: "Basic security group definitions"
intermediate:
# Multi-VPC or hub-spoke architecture
- path: "infrastructure/network/vpc-*.tf"
description: "Multiple VPC configurations (e.g., vpc-prod.tf, vpc-dev.tf)"
- path: "infrastructure/network/peering.tf"
must_contain: ["aws_vpc_peering_connection|google_compute_network_peering|azurerm_virtual_network_peering"]
description: "VPC peering or Transit Gateway configuration"
- path: "infrastructure/network/nat-gateway.tf"
must_contain: ["nat_gateway|nat", "elastic_ip"]
description: "NAT Gateway configuration for outbound connectivity"
- path: "infrastructure/network/flow-logs.tf"
must_contain: ["flow_log"]
description: "VPC Flow Logs configuration for observability"
advanced:
# Hub-spoke with Transit Gateway
- path: "infrastructure/network/transit-gateway.tf"
must_contain: ["transit_gateway|cloud_router|virtual_wan"]
description: "Transit Gateway/Cloud Router/Virtual WAN configuration"
- path: "infrastructure/network/transit-gateway-attachments.tf"
must_contain: ["attachment"]
description: "Transit Gateway attachments to VPCs"
- path: "infrastructure/network/hybrid-connectivity.tf"
must_contain: ["vpn|direct_connect|interconnect|expressroute"]
description: "Hybrid connectivity (VPN or Direct Connect/Interconnect/ExpressRoute)"
- path: "infrastructure/network/private-endpoints.tf"
must_contain: ["endpoint|privatelink"]
description: "VPC Endpoints/PrivateLink for AWS services"
- path: "infrastructure/network/network-firewall.tf"
description: "Network firewall or inspection VPC configuration"
- path: "docs/zero-trust-design.md"
must_contain: ["zero trust", "microsegmentation"]
description: "Zero trust network architecture design"
- path: "docs/disaster-recovery-network.md"
must_contain: ["failover", "multi-region"]
description: "Multi-region network failover plan"
cloud_provider:
aws:
- path: "infrastructure/network/vpc.tf"
must_contain: ["resource \"aws_vpc\"", "aws_subnet"]
description: "AWS VPC configuration"
- path: "infrastructure/network/security-groups.tf"
must_contain: ["resource \"aws_security_group\""]
description: "AWS security groups"
- path: "infrastructure/network/route-tables.tf"
must_contain: ["aws_route_table"]
description: "AWS route table configuration"
- path: "infrastructure/network/internet-gateway.tf"
must_contain: ["aws_internet_gateway"]
description: "AWS Internet Gateway configuration"
gcp:
- path: "infrastructure/network/vpc.tf"
must_contain: ["resource \"google_compute_network\"", "google_compute_subnetwork"]
description: "GCP VPC configuration (custom mode)"
- path: "infrastructure/network/firewall-rules.tf"
must_contain: ["google_compute_firewall"]
description: "GCP firewall rules"
- path: "infrastructure/network/cloud-nat.tf"
must_contain: ["google_compute_router_nat"]
description: "GCP Cloud NAT configuration"
azure:
- path: "infrastructure/network/vnet.tf"
must_contain: ["resource \"azurerm_virtual_network\"", "azurerm_subnet"]
description: "Azure Virtual Network configuration"
- path: "infrastructure/network/nsg.tf"
must_contain: ["azurerm_network_security_group"]
description: "Azure Network Security Groups"
- path: "infrastructure/network/nat-gateway.tf"
must_contain: ["azurerm_nat_gateway"]
description: "Azure NAT Gateway configuration"
iac_tool:
terraform:
- path: "infrastructure/network/main.tf"
must_contain: ["terraform", "provider"]
description: "Terraform configuration with provider setup"
- path: "infrastructure/network/variables.tf"
must_contain: ["variable"]
description: "Terraform variables for network configuration"
- path: "infrastructure/network/outputs.tf"
must_contain: ["output"]
description: "Terraform outputs exposing network IDs and values"
- path: "infrastructure/network/versions.tf"
must_contain: ["required_version", "required_providers"]
description: "Terraform version constraints"
pulumi:
- path: "infrastructure/network/__main__.py"
must_contain: ["import pulumi", "vpc|network"]
description: "Pulumi network stack (Python)"
- path: "infrastructure/network/Pulumi.yaml"
must_contain: ["name:", "runtime:"]
description: "Pulumi project configuration"
- path: "infrastructure/network/requirements.txt"
must_contain: ["pulumi"]
description: "Python dependencies for Pulumi"
cloudformation:
- path: "infrastructure/network/vpc.yaml"
must_contain: ["Resources:", "AWS::EC2::VPC"]
description: "CloudFormation VPC template"
- path: "infrastructure/network/parameters.yaml"
must_contain: ["Parameters:"]
description: "CloudFormation parameters file"
scaffolding:
- path: "infrastructure/network/"
reason: "Directory for network infrastructure code (should contain VPC/VNet definitions)"
- path: "docs/diagrams/"
reason: "Directory for network architecture diagrams (can be generated with tools like draw.io or Lucidchart)"
- path: "scripts/network-validation/"
reason: "Directory for network testing and validation scripts"
metadata:
primary_blueprints: ["cloud", "infrastructure", "k8s"]
contributes_to:
- "Network architecture design"
- "VPC/VNet topology and configuration"
- "Subnet planning and CIDR allocation"
- "Security group and firewall rule definitions"
- "NAT Gateway configuration"
- "VPC peering and Transit Gateway setup"
- "Hybrid connectivity (VPN, Direct Connect)"
- "Network observability (Flow Logs)"
- "Zero trust network implementation"
- "Multi-region network failover"
- "Private endpoints and PrivateLink"
- "Cost-optimized network architecture"
Cost Optimization
Strategies for reducing cloud network infrastructure costs.
Common Cost Drivers
1. NAT Gateway
- Cost: $0.045/hour + $0.045/GB data processed
- Annual (3 AZs): ~$1,150 (base) + data processing
Optimization:
- Use VPC Endpoints for AWS services (S3, DynamoDB)
- Single NAT Gateway for dev/test (accept availability risk)
- Centralized egress VPC pattern
2. Transit Gateway
- Cost: $0.05/hour/attachment + $0.02/GB
- Annual (5 VPCs): ~$2,190 (base) + data transfer
Optimization:
- Use VPC Peering for small number of VPCs (< 5)
- Direct peering for latency-sensitive pairs
- Avoid unnecessary Transit Gateway attachments
3. Data Transfer
- Egress Costs: Vary by destination
- Same region: Free
- Cross-region: $0.02/GB
- To internet: $0.09/GB
Optimization:
- Keep traffic within same region
- Use VPC Endpoints instead of public internet
- Private connectivity for high-volume transfers
4. VPN / Direct Connect
- VPN: $0.05/hour + data transfer
- Direct Connect: Port fee + lower data transfer ($0.02/GB)
Break-even: Direct Connect cheaper if > 8 TB/month
Cost Comparison Examples
NAT Gateway Configuration (3 AZs)
| Pattern | Monthly Cost | Resilience |
|---|---|---|
| Single NAT | ~$32 | Low |
| NAT per AZ | ~$96 | High |
| Centralized Egress | ~$32-96 | Medium-High |
VPN vs Direct Connect (10 TB/month)
| Solution | Monthly Cost |
|---|---|
| VPN | ~$957 |
| Direct Connect 1 Gbps | ~$420 |
Optimization Checklist
- [ ] Use VPC Endpoints for AWS services
- [ ] Right-size NAT Gateways (dev: single, prod: per AZ)
- [ ] Minimize cross-region traffic
- [ ] Use Transit Gateway only when needed (5+ VPCs)
- [ ] Monitor and alert on data transfer costs
- [ ] Review and remove unused resources monthly
Hybrid Connectivity
Comprehensive guide to connecting on-premises datacenters to cloud environments using VPN, Direct Connect, ExpressRoute, and Cloud Interconnect.
Table of Contents
1. VPN Connectivity 2. Dedicated Connectivity 3. Transit Gateway Patterns 4. High Availability Patterns 5. Cost Optimization
---
VPN Connectivity
Use Cases
Ideal For:
- Development and test environments
- Temporary connections
- Backup connectivity to dedicated link
- Low-cost hybrid requirements
- Quick setup needed (no contracts)
Not Suitable For:
- High-throughput production workloads (> 1.25 Gbps)
- Low-latency requirements
- Large data transfers
- Mission-critical applications
Architecture Pattern (AWS)
On-Premises Datacenter AWS VPC
┌─────────────────────┐ ┌─────────────────────┐
│ │ │ │
│ ┌──────────────┐ │ │ ┌──────────────┐ │
│ │ Dev │ │ IPsec VPN │ │ Dev │ │
│ │ Servers │ │ ◄────────────► │ │ Workloads │ │
│ └──────────────┘ │ (Encrypted) │ └──────────────┘ │
│ │ │ │
│ Customer Gateway │ │ Virtual Private │
│ (On-Prem Device) │ │ Gateway (AWS) │
└─────────────────────┘ └─────────────────────┘
Throughput: ~1.25 Gbps per tunnel (2 tunnels for HA)
Latency: Variable (internet-dependent)
Cost: Low (~$0.05/hour + data transfer)Implementation (AWS)
# Virtual Private Gateway
resource "aws_vpn_gateway" "main" {
vpc_id = module.vpc.vpc_id
tags = {
Name = "main-vpn-gateway"
}
}
# Customer Gateway (on-premises side)
resource "aws_customer_gateway" "onprem" {
bgp_asn = 65000
ip_address = "203.0.113.10" # Public IP of on-prem VPN device
type = "ipsec.1"
tags = {
Name = "onprem-customer-gateway"
}
}
# VPN Connection (creates 2 tunnels for HA)
resource "aws_vpn_connection" "main" {
vpn_gateway_id = aws_vpn_gateway.main.id
customer_gateway_id = aws_customer_gateway.onprem.id
type = "ipsec.1"
static_routes_only = false # Use BGP for dynamic routing
tags = {
Name = "main-vpn-connection"
}
}
# Route Propagation (automatic BGP routes)
resource "aws_vpn_gateway_route_propagation" "private" {
count = length(module.vpc.private_route_table_ids)
vpn_gateway_id = aws_vpn_gateway.main.id
route_table_id = module.vpc.private_route_table_ids[count.index]
}VPN Configuration
Tunnel 1:
- Outside IP: 203.0.113.10
- Inside IP: 169.254.10.1/30
- BGP ASN: 65000
- Pre-shared key: (generated)
Tunnel 2:
- Outside IP: 203.0.113.11
- Inside IP: 169.254.10.5/30
- BGP ASN: 65000
- Pre-shared key: (generated)
Accelerated VPN (AWS)
Use When: Internet connectivity is unreliable
resource "aws_vpn_connection" "accelerated" {
vpn_gateway_id = aws_vpn_gateway.main.id
customer_gateway_id = aws_customer_gateway.onprem.id
type = "ipsec.1"
enable_acceleration = true # Use AWS Global Accelerator
tags = {
Name = "accelerated-vpn"
}
}Benefits:
- Routes over AWS global network (not public internet)
- More stable performance
- Reduced latency variability
Costs:
- Additional $0.05/hour per tunnel
- Accelerated data transfer charges
---
Dedicated Connectivity
AWS Direct Connect
Use Cases
Ideal For:
- Production workloads
- Large data transfers (TB+)
- Real-time applications
- Predictable network performance
- Hybrid cloud at scale
Architecture:
On-Premises DX Location AWS
┌────────────┐ ┌──────────┐ ┌─────────────────────┐
│ │ │ │ │ │
│ ┌──────┐ │ Dark │ ┌────┐ │ Priv │ ┌──────────────┐ │
│ │ Prod │ │ Fiber │ │ DX │ │ VIF │ │ Prod │ │
│ │Servers├──┼───────┤ │Port├──┼───────┤──►│ VPC │ │
│ └──────┘ │ │ └────┘ │ │ └──────────────┘ │
│ │ │ │ │ │
│ Router │ │ AWS │ │ Virtual Private │
│ │ │ Cage │ │ Gateway │
└────────────┘ └──────────┘ └─────────────────────┘
Throughput: Up to 100 Gbps (dedicated connection)
Latency: Low and consistent (<5ms typical)
Cost: Port fee ($0.30/hour for 1 Gbps) + data transfer ($0.02/GB)
Setup: 2-4 weeks (contracts, cross-connect)Implementation (AWS)
# Direct Connect Gateway (for multi-VPC connectivity)
resource "aws_dx_gateway" "main" {
name = "main-dx-gateway"
amazon_side_asn = "64512"
}
# Virtual Private Gateway
resource "aws_vpn_gateway" "main" {
vpc_id = module.vpc.vpc_id
amazon_side_asn = 64513
tags = {
Name = "prod-vgw"
}
}
# DX Gateway Association with VGW
resource "aws_dx_gateway_association" "prod" {
dx_gateway_id = aws_dx_gateway.main.id
associated_gateway_id = aws_vpn_gateway.main.id
allowed_prefixes = [
module.vpc.vpc_cidr_block
]
}
# Private Virtual Interface (on DX connection)
# Note: DX connection itself is physical, created via AWS Console
resource "aws_dx_private_virtual_interface" "prod" {
connection_id = "dxcon-fg5678gh" # Your DX connection ID
name = "prod-vif"
vlan = 100
address_family = "ipv4"
bgp_asn = 65000 # On-prem BGP ASN
dx_gateway_id = aws_dx_gateway.main.id
}Direct Connect Capacity Options
| Port Speed | Monthly Cost | Use Case |
|---|---|---|
| 50 Mbps (Hosted) | ~$36 | Small workloads |
| 100 Mbps (Hosted) | ~$72 | Dev/test |
| 500 Mbps (Hosted) | ~$360 | Medium workloads |
| 1 Gbps | ~$220 | Production |
| 10 Gbps | ~$1,700 | High-volume |
| 100 Gbps | ~$17,000 | Enterprise-scale |
Azure ExpressRoute
Architecture
On-Premises ExpressRoute Location Azure
┌────────────┐ ┌──────────────────┐ ┌─────────────────┐
│ │ │ │ │ │
│ ┌──────┐ │ │ ┌────────────┐ │ │ ┌─────────┐ │
│ │ Prod │ │ │ │ExpressRoute│ │ │ │ VNet │ │
│ │Servers├──┼───────┤ │ Circuit ├──┼───────┤──►│ │ │
│ └──────┘ │ │ └────────────┘ │ │ └─────────┘ │
│ │ │ │ │ │
│ Router │ │ Connectivity │ │ Virtual │
│ │ │ Provider │ │ Network │
└────────────┘ └──────────────────┘ └─────────────────┘Implementation (Azure)
# ExpressRoute Circuit
resource "azurerm_express_route_circuit" "main" {
name = "prod-expressroute"
resource_group_name = azurerm_resource_group.main.name
location = azurerm_resource_group.main.location
service_provider_name = "Equinix"
peering_location = "Silicon Valley"
bandwidth_in_mbps = 1000
sku {
tier = "Standard"
family = "MeteredData"
}
tags = {
Environment = "Production"
}
}
# Private Peering
resource "azurerm_express_route_circuit_peering" "private" {
peering_type = "AzurePrivatePeering"
express_route_circuit_name = azurerm_express_route_circuit.main.name
resource_group_name = azurerm_resource_group.main.name
peer_asn = 65000
primary_peer_address_prefix = "192.168.1.0/30"
secondary_peer_address_prefix = "192.168.2.0/30"
vlan_id = 100
}
# VNet Gateway Connection
resource "azurerm_virtual_network_gateway_connection" "expressroute" {
name = "expressroute-connection"
location = azurerm_resource_group.main.location
resource_group_name = azurerm_resource_group.main.name
type = "ExpressRoute"
virtual_network_gateway_id = azurerm_virtual_network_gateway.main.id
express_route_circuit_id = azurerm_express_route_circuit.main.id
connection_protocol = "IKEv2"
}GCP Cloud Interconnect
Dedicated Interconnect
On-Premises Colocation GCP
┌────────────┐ ┌────────────┐ ┌─────────────────┐
│ │ │ │ │ │
│ ┌──────┐ │ │ ┌──────┐ │ │ ┌─────────┐ │
│ │ Prod │ │ │ │ GCP │ │ │ │ VPC │ │
│ │Servers├──┼───────┤ │Cage ├──┼───────┤──►│ │ │
│ └──────┘ │ │ └──────┘ │ │ └─────────┘ │
│ │ │ │ │ │
│ Router │ │ Cross- │ │ Cloud │
│ │ │ Connect │ │ Router │
└────────────┘ └────────────┘ └─────────────────┘Implementation (GCP)
# Cloud Router
resource "google_compute_router" "main" {
name = "main-router"
region = "us-central1"
network = google_compute_network.main.id
bgp {
asn = 64514
advertise_mode = "CUSTOM"
advertised_groups = ["ALL_SUBNETS"]
}
}
# Interconnect Attachment (VLAN)
resource "google_compute_interconnect_attachment" "main" {
name = "main-vlan"
interconnect = "https://www.googleapis.com/compute/v1/projects/${var.project}/global/interconnects/${var.interconnect_name}"
router = google_compute_router.main.id
region = "us-central1"
type = "DEDICATED"
bandwidth = "BPS_10G"
admin_enabled = true
vlan_tag8021q = 100
candidate_subnets = ["169.254.100.0/29"]
}
# Router Interface
resource "google_compute_router_interface" "main" {
name = "main-interface"
router = google_compute_router.main.name
region = google_compute_router.main.region
ip_range = "169.254.100.1/29"
vpn_tunnel = google_compute_interconnect_attachment.main.self_link
}
# BGP Peer
resource "google_compute_router_peer" "main" {
name = "main-peer"
router = google_compute_router.main.name
region = google_compute_router.main.region
interface = google_compute_router_interface.main.name
peer_ip_address = "169.254.100.2"
peer_asn = 65000
advertised_route_priority = 100
}---
Transit Gateway Patterns
Pattern: Hybrid with Transit Gateway + Direct Connect
Use Case: Multiple VPCs need on-premises connectivity via single DX connection
Architecture:
On-Premises DX Location AWS
┌────────────┐ ┌──────┐ ┌────────────────────┐
│ │ │ │ │ Transit Gateway │
│ Datacenter│◄──────┤ DX ├───────┤ │
│ │ │ │ └────────────────────┘
└────────────┘ └──────┘ │
├──► VPC-Prod
├──► VPC-Dev
└──► VPC-Shared
Single DX connection → TGW → Multiple VPCs
Cost Efficient + ScalableImplementation:
# Transit Gateway
resource "aws_ec2_transit_gateway" "main" {
description = "Main TGW for hybrid"
amazon_side_asn = 64512
default_route_table_association = "enable"
default_route_table_propagation = "enable"
tags = {
Name = "main-tgw"
}
}
# Direct Connect Gateway
resource "aws_dx_gateway" "main" {
name = "main-dx-gateway"
amazon_side_asn = "64512"
}
# Associate DX Gateway with Transit Gateway
resource "aws_dx_gateway_association" "tgw" {
dx_gateway_id = aws_dx_gateway.main.id
associated_gateway_id = aws_ec2_transit_gateway.main.id
allowed_prefixes = [
"10.0.0.0/8" # Allow all RFC1918 10.x traffic
]
}
# Attach VPCs to Transit Gateway
resource "aws_ec2_transit_gateway_vpc_attachment" "prod" {
transit_gateway_id = aws_ec2_transit_gateway.main.id
vpc_id = module.vpc_prod.vpc_id
subnet_ids = module.vpc_prod.private_subnets
tags = {
Name = "prod-tgw-attachment"
}
}
# Private VIF connects to DX Gateway
resource "aws_dx_private_virtual_interface" "main" {
connection_id = "dxcon-fg5678gh"
name = "main-vif"
vlan = 100
address_family = "ipv4"
bgp_asn = 65000
dx_gateway_id = aws_dx_gateway.main.id
}---
High Availability Patterns
Pattern 1: VPN Backup to Direct Connect
Architecture:
Primary Path
On-Prem ────────► Direct Connect ────────► AWS VPC
│ ▲
│ Backup Path (failover) │
└───────────► VPN ──────────────────────────┘
If DX fails, traffic automatically routes through VPNImplementation:
# Direct Connect (Primary)
resource "aws_dx_private_virtual_interface" "primary" {
connection_id = "dxcon-fg5678gh"
# ... DX config
}
# VPN (Backup)
resource "aws_vpn_connection" "backup" {
vpn_gateway_id = aws_vpn_gateway.main.id
customer_gateway_id = aws_customer_gateway.onprem.id
type = "ipsec.1"
tags = {
Name = "backup-vpn"
Role = "Backup to Direct Connect"
}
}BGP Configuration:
- Direct Connect: Local preference 200 (preferred)
- VPN: Local preference 100 (backup)
- Automatic failover via BGP
Pattern 2: Dual Direct Connect
Architecture:
On-Prem ────► DX Connection 1 (Primary) ────► AWS VPC
│ ▲
└──────────► DX Connection 2 (Secondary) ──────┘
Two Direct Connect connections for redundancyResilience:
- Different physical paths
- Different colocation facilities
- Active-active or active-passive
Cost:
- Double the Direct Connect port fees
- Highest availability
---
Cost Optimization
VPN vs Direct Connect Cost Comparison
Scenario: 1 Gbps bandwidth, 10 TB/month data transfer
| Solution | Setup | Monthly | Data Transfer | Total Monthly |
|---|---|---|---|---|
| VPN | Free | ~$37 (2 tunnels) | $920 ($0.09/GB) | ~$957 |
| Direct Connect 1 Gbps | $0-2000 (one-time) | ~$220 (port) | $200 ($0.02/GB) | ~$420 |
Break-even: Direct Connect cheaper if > 8 TB/month or need consistent performance
Optimization Strategies
1. Use VPN for Dev/Test
- Direct Connect for production only
- Reduces costs 50%+
2. Right-size Direct Connect
- Start with 1 Gbps, upgrade if needed
- Monitor utilization
3. Centralized Hybrid Connection
- Single Direct Connect + Transit Gateway
- Multiple VPCs share one connection
4. Hosted Connections for Smaller Needs
- 50 Mbps to 500 Mbps options
- Lower cost than dedicated
Multi-Cloud Networking
Unified networking concepts and implementations across AWS, GCP, and Azure.
Unified Concepts
| Concept | AWS | GCP | Azure |
|---|---|---|---|
| Virtual Network | VPC | VPC | Virtual Network (VNet) |
| Subnets | Subnets (AZ-scoped) | Subnets (Regional) | Subnets |
| NAT | NAT Gateway | Cloud NAT | NAT Gateway |
| Peering | VPC Peering | VPC Peering | VNet Peering |
| Hub-Spoke | Transit Gateway | Cloud Router | Virtual WAN |
| Private Endpoints | PrivateLink | Private Service Connect | Private Link |
| Hybrid VPN | VPN | Cloud VPN | VPN Gateway |
| Hybrid Dedicated | Direct Connect | Cloud Interconnect | ExpressRoute |
Provider Best Practices
AWS
- Multi-AZ baseline for production
- Prefer Transit Gateway for 5+ VPCs
- Use VPC Endpoints to avoid NAT charges
GCP
- Custom mode VPC (not auto-mode)
- Start with single VPC, use Shared VPC for multi-project
- Grant network user role at subnet level
Azure
- Hub-and-spoke network topology as standard
- Few large VNets vs many small VNets
- Private endpoints for Azure services
For detailed implementation examples, see examples/aws/, examples/gcp/, and examples/azure/ directories.
Multi-Region Networking
Cross-region connectivity patterns for disaster recovery and global applications.
Table of Contents
1. Use Cases 2. Cross-Region VPC Peering 3. Global Load Balancing 4. Multi-Region Architecture Pattern
---
Use Cases
1. Disaster Recovery
- Failover to secondary region
- Data replication across regions
2. Global Applications
- Serve users worldwide with low latency
- Geo-distributed workloads
3. Data Residency
- Compliance with regional data laws
- Data sovereignty requirements
Cross-Region VPC Peering
AWS
Setup:
# Peering connection between regions
resource "aws_vpc_peering_connection" "us_to_eu" {
vpc_id = aws_vpc.us_east.id
peer_vpc_id = aws_vpc.eu_west.id
peer_region = "eu-west-1"
auto_accept = false # Requires acceptance in peer region
tags = {
Name = "us-east-to-eu-west-peering"
}
}
# Accept peering in peer region
resource "aws_vpc_peering_connection_accepter" "eu_accept" {
provider = aws.eu_west
vpc_peering_connection_id = aws_vpc_peering_connection.us_to_eu.id
auto_accept = true
}Data Transfer Costs:
- Cross-region: $0.02/GB
GCP
VPC is global by default
- Subnets are regional
- No cross-region peering needed within single VPC
- Multi-region by design
Azure
VNet Peering:
- Cross-region peering supported
- Data transfer: $0.01/GB
Global Load Balancing
AWS Global Accelerator
Use When:
- Need static anycast IPs
- Improve availability and performance globally
- Instant regional failover
Cost: $0.025/hour + $0.015/GB
GCP Cloud Load Balancing
Use When:
- Global HTTP(S) load balancing
- Anycast IP addresses
- Cross-region failover
Azure Traffic Manager
Use When:
- DNS-based global load balancing
- Geographic routing
- Priority-based failover
Cost: $0.54/million queries
Multi-Region Architecture Pattern
Global Load Balancer
│
┌───────┴────────┐
│ │
us-east-1 eu-west-1
(Primary) (DR/Active)
│ │
┌───────┐ ┌───────┐
│ VPC │◄───────┤ VPC │
│ │ Peering│ │
└───────┘ └───────┘Benefits:
- Low latency for global users
- High availability (multi-region failover)
- Disaster recovery
Network Observability
Monitoring, logging, and troubleshooting cloud network architectures.
VPC Flow Logs
Enable Flow Logs
Configure flow logs to capture network traffic:
Traffic Type:
- ALL (recommended) - Capture accepted and rejected traffic
- ACCEPT - Only accepted traffic
- REJECT - Only rejected traffic
Aggregation Interval:
- 1 minute - Real-time monitoring (higher cost)
- 10 minutes - Standard (balance cost/latency)
Destination:
- CloudWatch Logs - Real-time analysis, alerting
- S3 - Long-term storage, cost-effective
Monitoring Patterns
Key Metrics:
- Rejected connections (security anomalies)
- Traffic volume spikes
- Cross-VPC communication patterns
- NAT Gateway utilization
- Data transfer costs
Alert On:
- Spike in rejected connections (> 100 in 5 minutes)
- Unusual traffic patterns
- High data transfer costs
- Network errors
Common Flow Log Queries
Top Talkers (Most Traffic):
SELECT srcaddr, dstaddr, SUM(bytes) as total_bytes
FROM vpc_flow_logs
WHERE action = 'ACCEPT'
GROUP BY srcaddr, dstaddr
ORDER BY total_bytes DESC
LIMIT 20Rejected Connections by Source:
SELECT srcaddr, COUNT(*) as rejected_count
FROM vpc_flow_logs
WHERE action = 'REJECT'
GROUP BY srcaddr
ORDER BY rejected_count DESC
LIMIT 20Troubleshooting
Common Issues
1. Connection Timeout
- Check security group rules
- Verify route tables
- Check network ACLs
- Verify NAT Gateway status
2. Slow Performance
- Check NAT Gateway metrics
- Review cross-region traffic
- Analyze flow logs for bottlenecks
3. High Costs
- Review data transfer patterns
- Check NAT Gateway usage
- Analyze cross-AZ traffic
- Optimize VPC Endpoints usage
Private Networking
Private connectivity to cloud services without traversing the public internet.
VPC Endpoints (AWS)
Gateway Endpoints (Free)
Supported Services:
- S3
- DynamoDB
Use When:
- Accessing S3 or DynamoDB from private subnets
- Avoiding NAT Gateway data processing charges
Interface Endpoints (AWS PrivateLink)
Cost: $0.01/hour/endpoint + $0.01/GB
Supported Services:
- Most AWS services (EC2, ECS, SNS, SQS, etc.)
- Third-party SaaS applications
Use When:
- Accessing AWS services from private subnets
- Security requirement: No public internet access
- Cost optimization: High-volume S3/DynamoDB access
Private Service Connect (GCP)
Purpose: Private access to Google APIs and services
Use When:
- Accessing Google services without external IP
- Compliance requires private connectivity
Private Link (Azure)
Purpose: Private access to Azure services over private IP
Supported Services:
- Azure Storage
- Azure SQL
- Azure Cosmos DB
- Custom private endpoints
Implementation Pattern
Before (via NAT Gateway):
Private Instance → NAT Gateway → Internet → S3
Cost: NAT Gateway charges ($0.045/GB)After (via VPC Endpoint):
Private Instance → VPC Endpoint → S3
Cost: Gateway endpoint (free), Interface endpoint ($0.01/GB)Cost Savings Example
Scenario: 100 TB/month S3 access from private subnets
Via NAT Gateway:
- NAT processing: 100 TB × $0.045/GB = $4,608
Via Gateway Endpoint:
- Endpoint: $0
- Savings: $4,608/month
Security Controls
Network security control mechanisms for cloud environments.
Security Groups vs Network ACLs
Security Groups (Recommended)
Characteristics:
- Stateful (return traffic automatically allowed)
- Instance-level control
- Allow rules only (implicit deny)
- Can reference other security groups
Best Practices:
- Use descriptive names
- Reference other SGs instead of CIDR blocks
- Keep rules minimal and specific
- One security group per service
Network ACLs
Characteristics:
- Stateless (must allow both request and response)
- Subnet-level control
- Allow and deny rules
- Rules processed in order
When to Use:
- Explicit deny rules (block specific IPs)
- Compliance requirements
- Additional layer beyond security groups
Important:
- Remember ephemeral ports (1024-65535)
- Test thoroughly (stateless nature causes issues)
Decision Matrix
| Requirement | Security Group | Network ACL |
|---|---|---|
| Block specific IP | No | Yes (deny rule) |
| Instance-level control | Yes | No |
| Stateful filtering | Yes | No |
| Reference other SGs | Yes | No |
| Default recommendation | Yes | Only if needed |
Subnet Strategy
Comprehensive guide to subnet design, CIDR planning, IP address management (IPAM), and multi-AZ distribution for cloud networks.
Table of Contents
1. Subnet Tier Design 2. CIDR Block Planning 3. IP Address Management (IPAM) 4. Multi-AZ Distribution 5. Reserved Address Space 6. Subnet Sizing Calculator
---
Subnet Tier Design
Standard Three-Tier Architecture
Public Subnets
Purpose: Resources that need direct internet access
Routes:
- Default route (0.0.0.0/0) points to Internet Gateway
Use For:
- Application Load Balancers (ALB)
- Network Load Balancers (NLB)
- NAT Gateways
- Bastion hosts
- Public-facing web servers
CIDR Sizing:
- Small: /27 (32 IPs) - For load balancers only
- Medium: /26 (64 IPs) - Load balancers + NAT
- Large: /24 (256 IPs) - Public-facing workloads
Example (3 AZs):
10.0.1.0/26 - us-east-1a (64 IPs)
10.0.1.64/26 - us-east-1b (64 IPs)
10.0.1.128/26 - us-east-1c (64 IPs)Private Subnets
Purpose: Application workloads with outbound internet access
Routes:
- Default route (0.0.0.0/0) points to NAT Gateway
Use For:
- EC2 instances
- ECS/EKS containers
- Lambda functions in VPC
- Application servers
- Kubernetes worker nodes
CIDR Sizing:
- Small: /22 (1,024 IPs) - Small workloads
- Medium: /21 (2,048 IPs) - Medium workloads
- Large: /20 (4,096 IPs) - Large workloads, Kubernetes
Example (3 AZs):
10.0.16.0/20 - us-east-1a (4,096 IPs)
10.0.32.0/20 - us-east-1b (4,096 IPs)
10.0.48.0/20 - us-east-1c (4,096 IPs)Database Subnets
Purpose: Database and cache layers with no direct internet
Routes:
- No default route to internet
- Routes to VPC CIDR only
Use For:
- RDS databases
- Aurora clusters
- ElastiCache
- Redshift
- Self-managed databases
CIDR Sizing:
- Small: /26 (64 IPs) - Few databases
- Medium: /25 (128 IPs) - Multiple databases
- Large: /24 (256 IPs) - Many databases, read replicas
Example (3 AZs):
10.0.64.0/24 - us-east-1a (256 IPs)
10.0.65.0/24 - us-east-1b (256 IPs)
10.0.66.0/24 - us-east-1c (256 IPs)Advanced: Specialized Subnet Tiers
Isolated Subnets (Intra)
Purpose: Resources with no internet access at all
Routes:
- Only VPC-local routes
- No NAT Gateway
Use For:
- VPC Endpoints (Interface endpoints)
- Highly sensitive workloads
- Compliance-isolated resources
CIDR Sizing: /24 (256 IPs)
Service-Specific Subnets
ElastiCache Subnets:
10.0.80.0/24 - us-east-1a
10.0.81.0/24 - us-east-1b
10.0.82.0/24 - us-east-1cRedshift Subnets:
10.0.90.0/24 - us-east-1a
10.0.91.0/24 - us-east-1b
10.0.92.0/24 - us-east-1cKubernetes Pod Subnets (GCP):
# Secondary IP range for pods
10.1.0.0/16 (65,536 IPs)
# Secondary IP range for services
10.2.0.0/20 (4,096 IPs)---
CIDR Block Planning
VPC CIDR Sizing Guidelines
| Environment | VPC CIDR | Total IPs | Use Case |
|---|---|---|---|
| Large Production | /16 | 65,536 | Large-scale production, Kubernetes |
| Medium Production | /18 | 16,384 | Medium production workloads |
| Small Production | /20 | 4,096 | Small production, limited services |
| Development | /20 | 4,096 | Dev/test environments |
| POC/Sandbox | /24 | 256 | Proof of concept, experimentation |
CIDR Allocation Examples
Example 1: Production VPC (10.0.0.0/16)
VPC: 10.0.0.0/16 (65,536 IPs)
Public Subnets (3 AZs, 192 IPs total):
├─ 10.0.1.0/26 (64 IPs) - us-east-1a
├─ 10.0.1.64/26 (64 IPs) - us-east-1b
└─ 10.0.1.128/26 (64 IPs) - us-east-1c
Private Subnets (3 AZs, 12,288 IPs total):
├─ 10.0.16.0/20 (4,096 IPs) - us-east-1a
├─ 10.0.32.0/20 (4,096 IPs) - us-east-1b
└─ 10.0.48.0/20 (4,096 IPs) - us-east-1c
Database Subnets (3 AZs, 768 IPs total):
├─ 10.0.64.0/24 (256 IPs) - us-east-1a
├─ 10.0.65.0/24 (256 IPs) - us-east-1b
└─ 10.0.66.0/24 (256 IPs) - us-east-1c
ElastiCache Subnets (3 AZs, 768 IPs total):
├─ 10.0.80.0/24 (256 IPs) - us-east-1a
├─ 10.0.81.0/24 (256 IPs) - us-east-1b
└─ 10.0.82.0/24 (256 IPs) - us-east-1c
Isolated Subnets (3 AZs, 768 IPs total):
├─ 10.0.100.0/24 (256 IPs) - us-east-1a
├─ 10.0.101.0/24 (256 IPs) - us-east-1b
└─ 10.0.102.0/24 (256 IPs) - us-east-1c
Reserved for Future (32,768 IPs):
└─ 10.0.128.0/17 - Reserved expansionExample 2: Development VPC (10.1.0.0/20)
VPC: 10.1.0.0/20 (4,096 IPs)
Public Subnets (2 AZs, 128 IPs total):
├─ 10.1.1.0/26 (64 IPs) - us-east-1a
└─ 10.1.1.64/26 (64 IPs) - us-east-1b
Private Subnets (2 AZs, 2,048 IPs total):
├─ 10.1.4.0/21 (1,024 IPs) - us-east-1a
└─ 10.1.8.0/21 (1,024 IPs) - us-east-1b
Database Subnets (2 AZs, 512 IPs total):
├─ 10.1.12.0/24 (256 IPs) - us-east-1a
└─ 10.1.13.0/24 (256 IPs) - us-east-1b
Reserved (1,408 IPs):
└─ 10.1.14.0/23 - Future expansionCIDR Planning Rules
1. Non-Overlapping CIDRs Across VPCs
Production VPC: 10.0.0.0/16
Staging VPC: 10.1.0.0/16
Development VPC: 10.2.0.0/16
Shared Services: 10.3.0.0/162. Coordinate with On-Premises
- Avoid overlapping with on-premises CIDR ranges
- Example: If on-prem uses 172.16.0.0/12, use 10.0.0.0/8 for cloud
3. Reserve Address Space
- Always reserve at least 20% for future growth
- Use larger CIDR than immediately needed
4. AWS Reserved Addresses
- First 4 IPs and last IP in each subnet are reserved
- Example: In 10.0.1.0/24:
- 10.0.1.0 - Network address
- 10.0.1.1 - VPC router
- 10.0.1.2 - DNS server
- 10.0.1.3 - Reserved for future use
- 10.0.1.255 - Broadcast address
---
IP Address Management (IPAM)
IPAM Best Practices
1. Centralized IPAM Tool
AWS:
- Use Amazon VPC IP Address Manager (IPAM)
- Automated CIDR allocation
- Prevent overlapping ranges
Azure:
- Azure Virtual Network Manager
- Centralized IP planning
GCP:
- Manual tracking or third-party tools
- IP address utilization dashboard
2. CIDR Allocation Strategy
Hierarchical Allocation:
10.0.0.0/8 - Entire cloud organization
├─ 10.0.0.0/12 - AWS
│ ├─ 10.0.0.0/13 - Production
│ │ ├─ 10.0.0.0/16 - Prod VPC 1
│ │ ├─ 10.1.0.0/16 - Prod VPC 2
│ │ └─ 10.2.0.0/16 - Prod VPC 3
│ └─ 10.8.0.0/13 - Non-Production
│ ├─ 10.8.0.0/16 - Staging
│ └─ 10.9.0.0/16 - Development
│
└─ 10.16.0.0/12 - GCP
└─ (similar structure)3. Documentation
Maintain IPAM Registry:
| VPC Name | CIDR | Cloud | Region | Environment |
|----------|------|-------|--------|-------------|
| prod-vpc-1 | 10.0.0.0/16 | AWS | us-east-1 | Production |
| prod-vpc-2 | 10.1.0.0/16 | AWS | us-west-2 | Production |
| dev-vpc-1 | 10.8.0.0/16 | AWS | us-east-1 | Development |Avoiding CIDR Conflicts
Common Pitfalls: 1. Overlapping VPC CIDRs (prevents peering) 2. Overlapping with on-premises 3. Overlapping with VPN client pools 4. Not reserving enough space for growth
Resolution Strategy:
- Plan CIDR allocation before creating VPCs
- Use IPAM tools to prevent overlaps
- Document all allocations
- Communicate with network team
---
Multi-AZ Distribution
Production Requirements
Minimum: 3 Availability Zones
- Survives single AZ failure
- Meets most SLA requirements
- AWS best practice for production
Configuration:
azs = ["us-east-1a", "us-east-1b", "us-east-1c"]
public_subnets = [
"10.0.1.0/24", # AZ-a
"10.0.2.0/24", # AZ-b
"10.0.3.0/24" # AZ-c
]
private_subnets = [
"10.0.10.0/24", # AZ-a
"10.0.11.0/24", # AZ-b
"10.0.12.0/24" # AZ-c
]Non-Production Flexibility
Cost-Optimized: 2 Availability Zones
azs = ["us-east-1a", "us-east-1b"]
public_subnets = [
"10.0.1.0/24", # AZ-a
"10.0.2.0/24" # AZ-b
]
private_subnets = [
"10.0.10.0/24", # AZ-a
"10.0.11.0/24" # AZ-b
]Extreme Cost-Optimization: 1 Availability Zone
- Only for dev/test
- No resilience
- Not recommended
Multi-Region Considerations
Regional CIDR Planning:
us-east-1 Production: 10.0.0.0/16
us-west-2 Production: 10.1.0.0/16
eu-west-1 Production: 10.2.0.0/16Cross-Region Peering Requirements:
- Non-overlapping CIDRs mandatory
- Plan global CIDR strategy early
---
Reserved Address Space
Why Reserve Space
1. Future Growth: Add new subnet tiers without redesigning 2. Service Expansion: New AWS services may require dedicated subnets 3. Unforeseen Requirements: Compliance, security, or business needs
Reservation Strategy
Allocate 30-50% for Future Use:
VPC: 10.0.0.0/16 (65,536 IPs)
Active Allocation: 32,768 IPs (50%)
├─ Public, Private, Database, etc.
Reserved: 32,768 IPs (50%)
└─ 10.0.128.0/17 - Reserved for futureUse Larger VPC CIDR Than Needed:
- Planning for 1,000 IPs? Use /20 (4,096 IPs)
- Planning for 4,000 IPs? Use /18 (16,384 IPs)
- Planning for 16,000 IPs? Use /16 (65,536 IPs)
---
Subnet Sizing Calculator
Quick Reference Table
| CIDR | Subnet Mask | Total IPs | Usable IPs (AWS) | Use Case |
|---|---|---|---|---|
| /28 | 255.255.255.240 | 16 | 11 | Very small (< 10 resources) |
| /27 | 255.255.255.224 | 32 | 27 | Small (ALB only) |
| /26 | 255.255.255.192 | 64 | 59 | Public subnets |
| /25 | 255.255.255.128 | 128 | 123 | Small private subnets |
| /24 | 255.255.255.0 | 256 | 251 | Database subnets |
| /23 | 255.255.254.0 | 512 | 507 | Medium private subnets |
| /22 | 255.255.252.0 | 1,024 | 1,019 | Large private subnets |
| /21 | 255.255.248.0 | 2,048 | 2,043 | Large private subnets |
| /20 | 255.255.240.0 | 4,096 | 4,091 | Large private subnets, Kubernetes |
| /19 | 255.255.224.0 | 8,192 | 8,187 | Very large private subnets |
| /18 | 255.255.192.0 | 16,384 | 16,379 | Medium VPC |
| /17 | 255.255.128.0 | 32,768 | 32,763 | Large VPC segment |
| /16 | 255.255.0.0 | 65,536 | 65,531 | Standard VPC size |
Sizing Formula
Calculate Required CIDR:
Required IPs = (Current IPs × Growth Factor) + Buffer
Growth Factor: 2x to 3x for production
Buffer: 20-30% additional for unforeseen needs
Example:
Current: 500 IPs
Growth: 2x = 1,000 IPs
Buffer: 30% = 300 IPs
Total: 1,300 IPs → Use /21 (2,048 IPs)Kubernetes-Specific Sizing
EKS/GKE Pod Networking:
Private Subnet for Nodes: /20 (4,096 IPs)
Secondary Range for Pods: /16 (65,536 IPs)
Secondary Range for Services: /20 (4,096 IPs)Calculation:
- 100 nodes × 30 pods/node = 3,000 pods
- Use /16 for pod range (65,536 IPs)
VPC Design Patterns
Comprehensive guide to cloud network architecture patterns with implementation details, use cases, and decision criteria.
Table of Contents
1. Pattern 1: Flat (Single VPC) Architecture 2. Pattern 2: Multi-VPC (Isolated) Architecture 3. Pattern 3: Hub-and-Spoke (Transit Gateway) Architecture 4. Pattern 4: Full Mesh (VPC Peering) Architecture 5. Pattern 5: Hybrid (Multi-Pattern) Architecture 6. Pattern Comparison Matrix 7. Migration Paths
---
Pattern 1: Flat (Single VPC) Architecture
Description
All resources deployed in a single VPC with subnet-level segmentation. This is the simplest network architecture pattern.
Architecture Diagram
┌─────────────────────────────────────────────────────┐
│ VPC 10.0.0.0/16 │
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────┐ │
│ │ Public │ │ Private │ │ Database │ │
│ │ Subnet │ │ Subnet │ │ Subnet │ │
│ │ 10.0.1.0/24 │ │ 10.0.10.0/24 │ │10.0.20./24│ │
│ │ │ │ │ │ │ │
│ │ ┌─────────┐ │ │ ┌─────────┐ │ │ ┌──────┐ │ │
│ │ │ ALB │ │ │ │ ECS │ │ │ │ RDS │ │ │
│ │ └─────────┘ │ │ └─────────┘ │ │ └──────┘ │ │
│ └──────────────┘ └──────────────┘ └──────────┘ │
│ │
│ Internet Gateway NAT Gateway │
└─────────────────────────────────────────────────────┘Use Cases
Ideal For:
- Startups and small applications
- Single environment (dev OR staging OR prod, not multiple)
- Proof of concept projects
- Teams < 10 engineers
- Simple security requirements
- Low complexity tolerance
Not Suitable For:
- Multiple environments requiring isolation
- Large teams with different access requirements
- Compliance requiring network-level separation
- Applications requiring strong blast radius containment
Pros and Cons
Advantages:
- ✓ Simplest to understand and manage
- ✓ No inter-VPC routing complexity
- ✓ Lowest cost (no Transit Gateway fees)
- ✓ Fastest to set up
- ✓ Easy to troubleshoot network issues
Disadvantages:
- ✗ Poor isolation between workloads
- ✗ Difficult to enforce least privilege
- ✗ CIDR exhaustion risks
- ✗ Hard to scale as organization grows
- ✗ Blast radius is entire VPC
- ✗ Security group rules become complex at scale
Implementation Example (AWS)
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
name = "app-vpc"
cidr = "10.0.0.0/16"
azs = ["us-east-1a", "us-east-1b", "us-east-1c"]
public_subnets = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"]
private_subnets = ["10.0.10.0/24", "10.0.11.0/24", "10.0.12.0/24"]
database_subnets = ["10.0.20.0/24", "10.0.21.0/24", "10.0.22.0/24"]
enable_nat_gateway = true
single_nat_gateway = false # NAT per AZ for resilience
enable_dns_hostnames = true
tags = {
Architecture = "flat"
Environment = "dev"
}
}---
Pattern 2: Multi-VPC (Isolated) Architecture
Description
Separate VPCs per environment or workload with no direct connectivity. Each VPC is completely isolated.
Architecture Diagram
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Dev VPC │ │ Staging VPC │ │ Prod VPC │
│ 10.0.0.0/16 │ │ 10.1.0.0/16 │ │ 10.2.0.0/16 │
│ │ │ │ │ │
│ ┌───────────┐ │ │ ┌───────────┐ │ │ ┌───────────┐ │
│ │ Subnets │ │ │ │ Subnets │ │ │ │ Subnets │ │
│ │ + Apps │ │ │ │ + Apps │ │ │ │ + Apps │ │
│ └───────────┘ │ │ └───────────┘ │ │ └───────────┘ │
│ │ │ │ │ │
│ IGW + NAT │ │ IGW + NAT │ │ IGW + NAT │
└─────────────────┘ └─────────────────┘ └─────────────────┘
│ │ │
└────────────────────┴────────────────────┘
Internet
No direct connectivity between VPCsUse Cases
Ideal For:
- Multiple environments (dev, staging, prod)
- Strong isolation requirements
- Different teams managing different VPCs
- Compliance requiring network-level separation
- Independent security boundaries
- Different cost centers
Not Suitable For:
- Workloads requiring frequent inter-VPC communication
- Shared services needed across environments
- Cost-sensitive environments (duplicate infrastructure)
Pros and Cons
Advantages:
- ✓ Strong blast radius containment
- ✓ Independent CIDR ranges (no overlap concerns)
- ✓ Clear security boundaries
- ✓ Easy cost allocation per VPC
- ✓ Different teams can manage different VPCs independently
- ✓ Compliance-friendly
Disadvantages:
- ✗ No cross-VPC communication without explicit setup
- ✗ Management overhead (multiple VPCs)
- ✗ Duplicate infrastructure (NAT, endpoints)
- ✗ Higher costs
- ✗ Shared services require duplication
---
Pattern 3: Hub-and-Spoke (Transit Gateway) Architecture
Description
Central hub VPC/Transit Gateway with spoke VPCs connecting to it. All inter-VPC traffic routes through the hub.
Architecture Diagram
On-Premises
│
VPN / DX
│
▼
┌─────────────────────┐
│ Transit Gateway │
│ (Hub) │
└─────────────────────┘
│ │ │
┌────────┘ │ └────────┐
│ │ │
▼ ▼ ▼
┌───────────┐ ┌───────────┐ ┌───────────┐
│ Prod VPC │ │ Dev VPC │ │ Shared │
│ (Spoke) │ │ (Spoke) │ │ Services │
│ │ │ │ │ (Spoke) │
└───────────┘ └───────────┘ └───────────┘Use Cases
Ideal For:
- 5+ VPCs need to communicate
- Centralized security inspection required
- Hybrid connectivity (on-premises to multiple VPCs)
- Multi-account AWS Organizations setup
- Need for network-level segmentation and policy
- Shared services VPC (Active Directory, monitoring, etc.)
Not Suitable For:
- Small number of VPCs (< 5) where peering is sufficient
- Ultra-low latency requirements (hub hop adds latency)
- Cost-sensitive projects (Transit Gateway fees)
Routing Patterns
Spoke-to-Spoke:
VPC-A → Transit Gateway → VPC-BSpoke-to-On-Premises:
VPC-A → Transit Gateway → VPN/Direct Connect → On-PremisesCentralized Egress:
VPC-A → Transit Gateway → Egress VPC → InternetPros and Cons
Advantages:
- ✓ Simplified routing (spokes only connect to hub)
- ✓ Centralized security inspection (firewall in hub)
- ✓ Scales easily (add spokes without redesigning)
- ✓ Works with AWS Resource Access Manager (RAM) for multi-account
- ✓ Centralized hybrid connectivity
- ✓ Reduces VPN/Direct Connect connections
Disadvantages:
- ✗ Transit Gateway costs (~$0.05/hour + $0.02/GB)
- ✗ Increased latency (traffic hairpins through hub)
- ✗ Hub becomes potential bottleneck
- ✗ More complex than simple peering
Implementation Example (AWS)
# Transit Gateway
resource "aws_ec2_transit_gateway" "main" {
description = "Main TGW for hub-spoke"
amazon_side_asn = 64512
default_route_table_association = "enable"
default_route_table_propagation = "enable"
dns_support = "enable"
vpn_ecmp_support = "enable"
tags = {
Name = "main-tgw"
}
}
# Spoke VPC Attachment
resource "aws_ec2_transit_gateway_vpc_attachment" "spoke_prod" {
transit_gateway_id = aws_ec2_transit_gateway.main.id
vpc_id = module.vpc_prod.vpc_id
subnet_ids = module.vpc_prod.private_subnets
dns_support = "enable"
tags = {
Name = "prod-vpc-attachment"
}
}
# Route: Spoke to Spoke
resource "aws_ec2_transit_gateway_route" "spoke_to_spoke" {
destination_cidr_block = "10.1.0.0/16"
transit_gateway_attachment_id = aws_ec2_transit_gateway_vpc_attachment.spoke_prod.id
transit_gateway_route_table_id = aws_ec2_transit_gateway_route_table.main.id
}Advanced: Inspection VPC Pattern
┌─────────────────────┐
│ Transit Gateway │
└─────────────────────┘
│ │ │
┌────────┘ │ └────────┐
│ │ │
▼ ▼ ▼
┌───────────┐ ┌───────────┐ ┌───────────┐
│ Prod VPC │ │Inspection │ │ Dev VPC │
│ │ │ VPC │ │ │
│ │ │ ┌──────┐ │ │ │
│ │ │ │Firewall│ │ │
│ │ │ └──────┘ │ │ │
└───────────┘ └───────────┘ └───────────┘
All spoke-to-spoke traffic routed through Inspection VPC firewall---
Pattern 4: Full Mesh (VPC Peering) Architecture
Description
Every VPC directly connected to every other VPC via VPC peering connections.
Architecture Diagram
┌───────────┐
│ VPC-A │
└───────────┘
/ | \
/ | \
/ | \
/ | \
┌─────┐ ┌─────┐ ┌─────┐
│VPC-B│──│VPC-C│──│VPC-D│
└─────┘ └─────┘ └─────┘
│ │ │
└────────┼────────┘
│
┌─────────┐
│ VPC-E │
└─────────┘
For 5 VPCs: 10 peering connections requiredScaling Challenge
Management complexity scales as O(n²):
| Number of VPCs | Peering Connections Required |
|---|---|
| 3 VPCs | 3 connections |
| 5 VPCs | 10 connections |
| 10 VPCs | 45 connections |
| 20 VPCs | 190 connections |
Use Cases
Ideal For:
- Small number of VPCs (2-5)
- Low latency requirements (no hub hop)
- No centralized inspection needed
- Cost optimization (avoid Transit Gateway fees)
- Simple connectivity needs
Not Suitable For:
- More than ~10 VPCs
- Centralized security inspection required
- Frequent topology changes (adding/removing VPCs)
Pros and Cons
Advantages:
- ✓ Lowest latency (direct VPC-to-VPC)
- ✓ No Transit Gateway costs
- ✓ Simple for small number of VPCs
- ✓ No single point of failure
Disadvantages:
- ✗ Management complexity scales as O(n²)
- ✗ No centralized security inspection
- ✗ Difficult to add new VPCs
- ✗ Route table management becomes unwieldy
- ✗ Does not scale beyond ~10 VPCs
Implementation Example (AWS)
# VPC Peering Connection
resource "aws_vpc_peering_connection" "prod_to_dev" {
vpc_id = module.vpc_prod.vpc_id
peer_vpc_id = module.vpc_dev.vpc_id
auto_accept = true
tags = {
Name = "prod-to-dev-peering"
}
}
# Routes in Prod VPC to reach Dev VPC
resource "aws_route" "prod_to_dev" {
count = length(module.vpc_prod.private_route_table_ids)
route_table_id = module.vpc_prod.private_route_table_ids[count.index]
destination_cidr_block = module.vpc_dev.vpc_cidr_block
vpc_peering_connection_id = aws_vpc_peering_connection.prod_to_dev.id
}
# Routes in Dev VPC to reach Prod VPC
resource "aws_route" "dev_to_prod" {
count = length(module.vpc_dev.private_route_table_ids)
route_table_id = module.vpc_dev.private_route_table_ids[count.index]
destination_cidr_block = module.vpc_prod.vpc_cidr_block
vpc_peering_connection_id = aws_vpc_peering_connection.prod_to_dev.id
}---
Pattern 5: Hybrid (Multi-Pattern) Architecture
Description
Combination of patterns based on workload requirements. Most common: Hub-spoke for most VPCs + direct peering for latency-sensitive pairs.
Architecture Diagram
┌─────────────────────┐
│ Transit Gateway │
│ (Hub) │
└─────────────────────┘
│ │ │
┌────────┘ │ └────────┐
│ │ │
▼ ▼ ▼
┌───────────┐ ┌───────────┐ ┌───────────┐
│ Prod VPC │◄──┤ Dev VPC │ │ Shared │
│ │ │ │ │ Services │
└───────────┘ └───────────┘ └───────────┘
▲ │
│ VPC Peering │
└─────────────────────────────────┘
(Low-latency path for specific traffic)Use Cases
Ideal For:
- Large enterprise with diverse requirements
- Some workloads need low latency (direct peering)
- Other workloads need centralized inspection (hub-spoke)
- Balancing cost, performance, and security
- Complex multi-environment architectures
Traffic Routing Examples
Prod ↔ Shared Services:
- Low-latency direct VPC peering
- No hub hop for time-sensitive operations
Dev → Prod:
- Routed through Transit Gateway for inspection
- Security team can audit cross-environment traffic
All → On-Premises:
- Routed through Transit Gateway
- Single hybrid connection point
---
Pattern Comparison Matrix
| Criterion | Flat | Multi-VPC | Hub-Spoke | Mesh | Hybrid |
|---|---|---|---|---|---|
| Complexity | Very Low | Low | Medium | High | High |
| Isolation | Low | High | Medium | Medium | High |
| Scalability | Poor | Medium | Excellent | Poor | Excellent |
| Latency | Lowest | N/A | Medium | Lowest | Mixed |
| Cost | Lowest | Medium | Medium-High | Low | Medium-High |
| Management | Easy | Medium | Medium | Difficult | Difficult |
| Hybrid Connectivity | Simple | Duplicate | Centralized | Duplicate | Centralized |
| Security Inspection | No | No | Yes | No | Yes |
| Max VPCs | 1 | Unlimited | 100+ | ~10 | 100+ |
---
Migration Paths
Migrating from Flat to Hub-Spoke
Step 1: Create Transit Gateway Step 2: Create separate VPCs for environments Step 3: Migrate workloads incrementally Step 4: Attach new VPCs to Transit Gateway Step 5: Decommission flat VPC
Downtime: Can be zero with proper planning
Migrating from Mesh to Hub-Spoke
Step 1: Create Transit Gateway Step 2: Attach all existing VPCs Step 3: Update route tables to use TGW Step 4: Remove VPC peering connections Step 5: Validate connectivity
Downtime: Minimal (during route table updates)
Migrating from Multi-VPC to Hub-Spoke
Step 1: Create Transit Gateway Step 2: Attach VPCs that need communication Step 3: Configure routing policies Step 4: Test connectivity
Downtime: None (VPCs remain functional during migration)
Zero Trust Networking
Comprehensive guide to implementing zero trust network architecture principles in cloud environments.
Table of Contents
1. Zero Trust Principles 2. Microsegmentation 3. Identity-Based Access 4. Continuous Verification 5. Implementation Roadmap
---
Zero Trust Principles
Core Tenets (2025)
1. Never Trust, Always Verify
Traditional Approach:
Inside Network = Trusted
Outside Network = UntrustedZero Trust Approach:
Every Request = Verify
Every User = Authenticate
Every Device = ValidateImplementation:
- Authenticate every request regardless of source
- Verify identity AND device health
- No implicit trust based on network location
2. Least Privilege Access
Traditional Approach:
VPC = Full Access
Subnet = Full Access within subnetZero Trust Approach:
Service A → Service B: Port 8080 only
Service C → Database: Port 5432 onlyImplementation:
- Grant minimum necessary permissions
- Time-bound access (just-in-time)
- Continuous authorization
- Revoke unused permissions
3. Assume Breach
Traditional Approach:
Perimeter = Secure
Inside = TrustedZero Trust Approach:
Attackers Inside = Assume
Lateral Movement = Block
Segment Everything = RequiredImplementation:
- Segment network aggressively
- Monitor all traffic
- Rapid detection and response
- Limit blast radius
---
Microsegmentation
Traditional Network vs Zero Trust
Traditional (Large Blast Radius)
┌────────────────────────────────────────────────┐
│ DMZ (0.0.0.0/0 allowed) │
│ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ │
│ │ App1│ │ App2│ │ App3│ │ App4│ │ App5│ │
│ └─────┘ └─────┘ └─────┘ └─────┘ └─────┘ │
│ All apps can talk to each other │
└────────────────────────────────────────────────┘
Problem: If one app compromised, all apps at riskZero Trust (Microsegmentation)
┌────────────────────────────────────────────────┐
│ Microsegmented Environment │
│ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ │
│ │App1 │──►│App2 │ │App3 │──►│App4 │ │
│ │[SG1]│ │[SG2]│ │[SG3]│ │[SG4]│ │
│ └─────┘ └─────┘ └─────┘ └─────┘ │
│ Only App1→App2 and App3→App4 allowed │
└────────────────────────────────────────────────┘
Benefit: Compromise of App1 doesn't affect App3/App4Implementing Microsegmentation with Security Groups
Pattern 1: Service-to-Service Security Groups
Architecture:
┌───────────────────────────────────────────────────┐
│ VPC │
│ │
│ ┌─────────────────────────────────────────┐ │
│ │ ALB Security Group (alb-sg) │ │
│ │ Ingress: 0.0.0.0/0:443 (HTTPS) │ │
│ └─────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────┐ │
│ │ Backend Security Group (backend-sg) │ │
│ │ Ingress: [alb-sg]:8080 (from ALB only) │ │
│ └─────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────┐ │
│ │ Database Security Group (db-sg) │ │
│ │ Ingress: [backend-sg]:5432 (from BE) │ │
│ └─────────────────────────────────────────┘ │
│ │
└───────────────────────────────────────────────────┘Implementation (AWS):
# ALB Security Group
resource "aws_security_group" "alb" {
name = "alb-sg"
description = "ALB security group"
vpc_id = module.vpc.vpc_id
# Public HTTPS access
ingress {
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
description = "HTTPS from internet"
}
# Outbound to backend only
egress {
from_port = 8080
to_port = 8080
protocol = "tcp"
security_groups = [aws_security_group.backend.id]
description = "To backend service"
}
tags = {
Name = "alb-sg"
ZeroTrust = "true"
}
}
# Backend Service Security Group
resource "aws_security_group" "backend" {
name = "backend-sg"
description = "Backend service security group"
vpc_id = module.vpc.vpc_id
# Only accept traffic from ALB
ingress {
from_port = 8080
to_port = 8080
protocol = "tcp"
security_groups = [aws_security_group.alb.id]
description = "From ALB only"
}
# Only send traffic to database
egress {
from_port = 5432
to_port = 5432
protocol = "tcp"
security_groups = [aws_security_group.database.id]
description = "To database only"
}
tags = {
Name = "backend-sg"
ZeroTrust = "true"
}
}
# Database Security Group
resource "aws_security_group" "database" {
name = "database-sg"
description = "Database security group"
vpc_id = module.vpc.vpc_id
# Only accept traffic from backend
ingress {
from_port = 5432
to_port = 5432
protocol = "tcp"
security_groups = [aws_security_group.backend.id]
description = "From backend only"
}
# No outbound (database doesn't initiate)
# Note: Some egress required for health checks
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
description = "Required for AWS health checks"
}
tags = {
Name = "database-sg"
ZeroTrust = "true"
}
}Pattern 2: Microservices Segmentation
Scenario: Multiple microservices with specific dependencies
# Auth Service
resource "aws_security_group" "auth_service" {
name = "auth-service-sg"
vpc_id = module.vpc.vpc_id
# Accept from API Gateway
ingress {
from_port = 8081
to_port = 8081
protocol = "tcp"
security_groups = [aws_security_group.api_gateway.id]
}
# Can talk to user database
egress {
from_port = 5432
to_port = 5432
protocol = "tcp"
security_groups = [aws_security_group.user_db.id]
}
tags = {
Service = "auth"
}
}
# Order Service
resource "aws_security_group" "order_service" {
name = "order-service-sg"
vpc_id = module.vpc.vpc_id
# Accept from API Gateway
ingress {
from_port = 8082
to_port = 8082
protocol = "tcp"
security_groups = [aws_security_group.api_gateway.id]
}
# Can talk to order database
egress {
from_port = 5432
to_port = 5432
protocol = "tcp"
security_groups = [aws_security_group.order_db.id]
}
# Can talk to payment service
egress {
from_port = 8083
to_port = 8083
protocol = "tcp"
security_groups = [aws_security_group.payment_service.id]
}
tags = {
Service = "order"
}
}Microsegmentation Best Practices
1. One Security Group Per Service
- Don't reuse security groups across services
- Makes dependency tracking clear
2. Reference Other Security Groups
- Use security group IDs instead of CIDR blocks
- Example:
source_security_group_id = aws_security_group.backend.id
3. Explicit Deny Not Needed
- Security groups are deny-by-default
- Only create allow rules
4. Document Dependencies
# Dependency: Frontend → Backend → Database
# Frontend can only talk to Backend
# Backend can only talk to Database5. Use Tags for Organization
tags = {
Service = "backend"
Environment = "production"
ZeroTrust = "true"
Owner = "platform-team"
}---
Identity-Based Access
Concept: Identity Over IP Address
Traditional Approach:
Allow: 10.0.1.0/24 (subnet) → S3
Problem: Any compromised instance in subnet can access S3Zero Trust Approach:
Allow: IAM Role "app-role" → S3 bucket "app-bucket"
Benefit: Only instances with specific role can accessImplementation Patterns
Pattern 1: VPC Endpoints with IAM Policies
S3 VPC Endpoint with Role-Based Access:
# S3 VPC Endpoint with IAM Policy
resource "aws_vpc_endpoint" "s3" {
vpc_id = module.vpc.vpc_id
service_name = "com.amazonaws.us-east-1.s3"
vpc_endpoint_type = "Gateway"
route_table_ids = module.vpc.private_route_table_ids
# Only specific IAM role can use this endpoint
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Principal = {
AWS = aws_iam_role.app.arn
}
Action = [
"s3:GetObject",
"s3:PutObject"
]
Resource = "${aws_s3_bucket.app.arn}/*"
}
]
})
}
# Application IAM Role
resource "aws_iam_role" "app" {
name = "app-role"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Principal = {
Service = "ecs-tasks.amazonaws.com"
}
Action = "sts:AssumeRole"
Condition = {
StringEquals = {
"ecs:cluster" = aws_ecs_cluster.main.arn
}
}
}
]
})
}Pattern 2: Service Control Policies (SCPs)
Prevent Public S3 Buckets:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Deny",
"Action": [
"s3:PutBucketPublicAccessBlock",
"s3:PutAccountPublicAccessBlock"
],
"Resource": "*",
"Condition": {
"StringNotEquals": {
"s3:x-amz-acl": "private"
}
}
}
]
}Pattern 3: Attribute-Based Access Control (ABAC)
Tag-Based Access:
# IAM Policy using tags
resource "aws_iam_policy" "tag_based_access" {
name = "tag-based-access"
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Action = "ec2:*"
Resource = "*"
Condition = {
StringEquals = {
"ec2:ResourceTag/Environment" = "$${aws:PrincipalTag/Environment}"
}
}
}
]
})
}---
Continuous Verification
VPC Flow Logs for Traffic Analysis
Enable Flow Logs
# VPC Flow Logs to CloudWatch
resource "aws_flow_log" "vpc" {
iam_role_arn = aws_iam_role.flow_log.arn
log_destination = aws_cloudwatch_log_group.flow_log.arn
traffic_type = "ALL" # Capture accepted and rejected
vpc_id = module.vpc.vpc_id
max_aggregation_interval = 60 # 1 minute
tags = {
Name = "vpc-flow-logs"
ZeroTrust = "true"
}
}
# CloudWatch Log Group
resource "aws_cloudwatch_log_group" "flow_log" {
name = "/aws/vpc/flow-logs"
retention_in_days = 30
tags = {
Purpose = "Security monitoring"
}
}
# IAM Role for Flow Logs
resource "aws_iam_role" "flow_log" {
name = "vpc-flow-log-role"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Principal = {
Service = "vpc-flow-logs.amazonaws.com"
}
Action = "sts:AssumeRole"
}
]
})
}Monitoring Rejected Connections
CloudWatch Metric Filter
# Detect rejected connections (potential attacks)
resource "aws_cloudwatch_log_metric_filter" "rejected_connections" {
name = "rejected-connections"
log_group_name = aws_cloudwatch_log_group.flow_log.name
# Flow log format: action="REJECT"
pattern = "[version, account, eni, source, destination, srcport, destport, protocol, packets, bytes, windowstart, windowend, action=\"REJECT\", flowlogstatus]"
metric_transformation {
name = "RejectedConnectionCount"
namespace = "VPC/FlowLogs"
value = "1"
}
}
# Alert on spike in rejected connections
resource "aws_cloudwatch_metric_alarm" "rejected_connections_spike" {
alarm_name = "rejected-connections-spike"
comparison_operator = "GreaterThanThreshold"
evaluation_periods = "2"
metric_name = "RejectedConnectionCount"
namespace = "VPC/FlowLogs"
period = "300" # 5 minutes
statistic = "Sum"
threshold = "100" # Alert if >100 rejections in 5 min
alarm_description = "Potential attack: High rejected connection count"
alarm_actions = [aws_sns_topic.security_alerts.arn]
tags = {
Severity = "High"
Type = "Security"
}
}Analyzing Flow Logs
Common Queries
1. Top Talkers (Most Traffic):
SELECT srcaddr, dstaddr, SUM(bytes) as total_bytes
FROM vpc_flow_logs
WHERE action = 'ACCEPT'
GROUP BY srcaddr, dstaddr
ORDER BY total_bytes DESC
LIMIT 202. Rejected Connections by Source:
SELECT srcaddr, COUNT(*) as rejected_count
FROM vpc_flow_logs
WHERE action = 'REJECT'
GROUP BY srcaddr
ORDER BY rejected_count DESC
LIMIT 203. Unusual Ports:
SELECT dstport, COUNT(*) as count
FROM vpc_flow_logs
WHERE dstport NOT IN (80, 443, 22, 3306, 5432)
GROUP BY dstport
ORDER BY count DESC---
Implementation Roadmap
Phase 1: Assessment (Weeks 1-2)
Activities:
- [ ] Document current network architecture
- [ ] Inventory all services and dependencies
- [ ] Map data flows between services
- [ ] Identify sensitive data paths
- [ ] Assess current security posture
Deliverables:
- Network architecture diagram
- Service dependency map
- Risk assessment report
Phase 2: Design (Weeks 3-4)
Activities:
- [ ] Design microsegmentation strategy
- [ ] Plan security group architecture
- [ ] Define IAM roles and policies
- [ ] Design monitoring and logging strategy
- [ ] Plan phased rollout
Deliverables:
- Zero trust architecture design
- Security group matrix
- IAM policy documents
- Monitoring plan
Phase 3: Pilot (Weeks 5-6)
Activities:
- [ ] Implement in non-production environment
- [ ] Test microsegmentation rules
- [ ] Validate IAM policies
- [ ] Enable VPC flow logs
- [ ] Test monitoring and alerting
Deliverables:
- Working pilot environment
- Test results
- Lessons learned
Phase 4: Production Rollout (Weeks 7-12)
Activities:
- [ ] Implement microsegmentation in production
- [ ] Enable VPC flow logs
- [ ] Configure CloudWatch alarms
- [ ] Train operations team
- [ ] Document procedures
Phased Approach: 1. Week 7-8: Implement security groups (audit mode) 2. Week 9-10: Enforce security group rules 3. Week 11-12: Continuous monitoring and tuning
Phase 5: Continuous Improvement (Ongoing)
Activities:
- [ ] Review flow logs weekly
- [ ] Audit security group rules monthly
- [ ] Update microsegmentation as services change
- [ ] Conduct quarterly security reviews
- [ ] Respond to security incidents
Metrics to Track:
- Number of rejected connections
- Security group rule count
- IAM policy complexity
- Time to detect threats
- Time to remediate incidents
#!/usr/bin/env python3
"""
CIDR Calculator for Network Architecture Planning
Calculate subnet details, available IPs, and plan CIDR blocks for VPC design.
Usage:
python cidr-calculator.py --cidr 10.0.0.0/16
python cidr-calculator.py --cidr 10.0.0.0/16 --subnets 3
"""
import ipaddress
import argparse
import sys
from typing import List, Dict
def calculate_cidr_details(cidr: str) -> Dict:
"""Calculate details for a given CIDR block"""
try:
network = ipaddress.ip_network(cidr, strict=False)
# AWS reserves 5 IPs per subnet (first 4 and last 1)
aws_reserved = 5
usable_ips = network.num_addresses - aws_reserved if network.num_addresses > 5 else 0
return {
'cidr': str(network),
'network_address': str(network.network_address),
'broadcast_address': str(network.broadcast_address),
'netmask': str(network.netmask),
'prefix_length': network.prefixlen,
'total_ips': network.num_addresses,
'usable_ips_aws': usable_ips,
'first_usable': str(network.network_address + 1),
'last_usable': str(network.broadcast_address - 1),
'aws_reserved_ips': [
f"{network.network_address} (network address)",
f"{network.network_address + 1} (VPC router)",
f"{network.network_address + 2} (DNS server)",
f"{network.network_address + 3} (reserved for future use)",
f"{network.broadcast_address} (broadcast address)"
]
}
except ValueError as e:
print(f"Error: Invalid CIDR notation - {e}", file=sys.stderr)
sys.exit(1)
def suggest_subnet_sizes(total_ips: int) -> List[Dict]:
"""Suggest appropriate subnet sizes based on total IPs needed"""
suggestions = []
# Common subnet sizes
sizes = {
'/28': 16,
'/27': 32,
'/26': 64,
'/25': 128,
'/24': 256,
'/23': 512,
'/22': 1024,
'/21': 2048,
'/20': 4096,
'/19': 8192,
'/18': 16384,
'/17': 32768,
'/16': 65536
}
for prefix, ips in sizes.items():
if ips >= total_ips:
usable_aws = ips - 5
suggestions.append({
'prefix': prefix,
'total_ips': ips,
'usable_ips_aws': usable_aws,
'capacity_utilization': f"{(total_ips / usable_aws * 100):.1f}%"
})
return suggestions
def split_cidr_into_subnets(cidr: str, num_subnets: int) -> List[str]:
"""Split a CIDR block into equal-sized subnets"""
try:
network = ipaddress.ip_network(cidr, strict=False)
# Calculate new prefix length
import math
additional_bits = math.ceil(math.log2(num_subnets))
new_prefix = network.prefixlen + additional_bits
if new_prefix > 32:
print(f"Error: Cannot split {cidr} into {num_subnets} subnets (would require /{new_prefix})",
file=sys.stderr)
sys.exit(1)
# Generate subnets
subnets = list(network.subnets(new_prefix=new_prefix))
return [str(subnet) for subnet in subnets[:num_subnets]]
except ValueError as e:
print(f"Error: {e}", file=sys.stderr)
sys.exit(1)
def print_cidr_details(details: Dict):
"""Print formatted CIDR details"""
print("\n" + "=" * 60)
print("CIDR Block Details")
print("=" * 60)
print(f"CIDR: {details['cidr']}")
print(f"Network Address: {details['network_address']}")
print(f"Broadcast Address: {details['broadcast_address']}")
print(f"Netmask: {details['netmask']}")
print(f"Prefix Length: /{details['prefix_length']}")
print(f"Total IPs: {details['total_ips']:,}")
print(f"Usable IPs (AWS): {details['usable_ips_aws']:,}")
print(f"First Usable: {details['first_usable']}")
print(f"Last Usable: {details['last_usable']}")
print("\nAWS Reserved IPs:")
for reserved in details['aws_reserved_ips']:
print(f" - {reserved}")
def print_subnet_suggestions(ips_needed: int):
"""Print subnet size suggestions"""
suggestions = suggest_subnet_sizes(ips_needed)
if not suggestions:
print(f"\nNo suitable subnet size for {ips_needed} IPs")
return
print("\n" + "=" * 60)
print(f"Subnet Size Suggestions for {ips_needed} IPs")
print("=" * 60)
print(f"{'Prefix':<10} {'Total IPs':<12} {'Usable (AWS)':<15} {'Utilization':<15}")
print("-" * 60)
for s in suggestions[:5]: # Show top 5 suggestions
print(f"{s['prefix']:<10} {s['total_ips']:<12,} {s['usable_ips_aws']:<15,} {s['capacity_utilization']:<15}")
def print_subnet_split(cidr: str, subnets: List[str]):
"""Print subnet split results"""
print("\n" + "=" * 60)
print(f"Splitting {cidr} into {len(subnets)} subnets")
print("=" * 60)
for i, subnet in enumerate(subnets, 1):
details = calculate_cidr_details(subnet)
print(f"\nSubnet {i}: {subnet}")
print(f" - Usable IPs (AWS): {details['usable_ips_aws']:,}")
print(f" - Range: {details['network_address']} - {details['broadcast_address']}")
def main():
parser = argparse.ArgumentParser(
description='CIDR Calculator for Network Architecture Planning',
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog='''
Examples:
Calculate details for a CIDR block:
%(prog)s --cidr 10.0.0.0/16
Split CIDR into subnets:
%(prog)s --cidr 10.0.0.0/16 --subnets 3
Suggest subnet sizes for required IPs:
%(prog)s --suggest 1000
'''
)
parser.add_argument('--cidr', type=str, help='CIDR block to analyze (e.g., 10.0.0.0/16)')
parser.add_argument('--subnets', type=int, help='Number of equal-sized subnets to create')
parser.add_argument('--suggest', type=int, help='Suggest subnet sizes for N IPs needed')
args = parser.parse_args()
if not any([args.cidr, args.suggest]):
parser.print_help()
sys.exit(1)
# Calculate CIDR details
if args.cidr:
details = calculate_cidr_details(args.cidr)
print_cidr_details(details)
# Split into subnets if requested
if args.subnets:
subnets = split_cidr_into_subnets(args.cidr, args.subnets)
print_subnet_split(args.cidr, subnets)
# Suggest subnet sizes
if args.suggest:
print_subnet_suggestions(args.suggest)
print("\n")
if __name__ == '__main__':
main()
Related skills
FAQ
When should I use hub-and-spoke?
When 5+ VPCs need communication, centralized security inspection is required, or you need hybrid connectivity.
How many AZs for production subnets?
Distribute each tier across at least 3 Availability Zones for production.