Skip to main content

On This Page

Production-Ready AWS VPC Architecture: A 5-Tier Terraform Implementation Guide

3 min read
Share

These articles are AI-generated summaries. Please check the original sources for full details.

Building a Production-Ready AWS VPC with Terraform: Multi-Tier Subnets, NAT Gateways, and VPC Endpoints

Kehinde Ogunlowo’s production-grade VPC module implements a 5-tier subnet strategy to isolate application, data, and management layers. This architecture eliminates the security risks of default VPCs where public IP addresses are often incorrectly assigned to database instances.

Why This Matters

In technical reality, simple public/private subnet splits often fail to meet regulatory compliance or provide adequate blast radius reduction. Retrofitting network isolation into a running production system is a high-risk operational burden that can be avoided by implementing dedicated tiers for data and caching from the start. Proper IP spacing and VPC endpoints are critical for avoiding overlapping CIDRs and managing NAT gateway throughput limits of 45 Gbps.

Key Insights

  • A 5-tier strategy separates Public, Application, Data, Cache, and Management workloads into distinct subnets across three availability zones for isolation.
  • NAT Gateways cost roughly $32/month plus data charges, making single-NAT configurations ideal for dev environments while multi-NAT is required for production HA.
  • VPC Interface Endpoints cost approximately $7.20/month per service in us-east-1 but reduce NAT data processing charges for ECR and CloudWatch traffic.
  • Custom Flow Log formats enable granular visibility, allowing engineers to query rejected traffic patterns using Amazon Athena for security auditing.
  • Stateless Network ACLs serve as a second defense layer, restricting database subnet access to specific application tier CIDR blocks regardless of security group state.

Working Examples

Complete production VPC configuration using a 5-tier subnet strategy and high-availability NAT gateways.

module "vpc" {
  source = "github.com/kogunlowo123/terraform-aws-vpc-complete"
  vpc_name = "production"
  vpc_cidr = "10.0.0.0/16"
  azs = ["eu-west-1a", "eu-west-1b", "eu-west-1c"]
  public_subnets = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"]
  application_subnets = ["10.0.10.0/24", "10.0.11.0/24", "10.0.12.0/24"]
  data_subnets = ["10.0.20.0/24", "10.0.21.0/24", "10.0.22.0/24"]
  cache_subnets = ["10.0.30.0/24", "10.0.31.0/24", "10.0.32.0/24"]
  management_subnets = ["10.0.40.0/24", "10.0.41.0/24", "10.0.42.0/24"]
  enable_nat_gateway = true
  single_nat_gateway = false
  one_nat_gateway_per_az = true
  enable_s3_endpoint = true
  enable_dynamodb_endpoint = true
  enable_interface_endpoints = true
  interface_endpoints = ["ecr.api", "ecr.dkr", "logs", "monitoring", "ssm", "sts", "kms"]
}

Athena query to identify rejected traffic attempts targeting the data subnet tier.

SELECT srcaddr, dstaddr, dstport, protocol, action,
SUM(bytes) as total_bytes, COUNT(*) as flow_count
FROM vpc_flow_logs
WHERE action = 'REJECT'
AND dstaddr LIKE '10.0.2%'
AND date = '2026/03/06'
GROUP BY srcaddr, dstaddr, dstport, protocol, action
ORDER BY flow_count DESC
LIMIT 20;

Practical Applications

  • High-Availability Production: Deploying one NAT Gateway per AZ ensures that subnet traffic remains local to the zone, preventing cross-AZ failure dependencies.
  • Cost-Optimized Non-Prod: Using ‘single_nat_gateway = true’ for staging environments to save approximately $64/month in baseline NAT gateway costs.
  • Regulatory Compliance: Implementing dedicated data-tier NACLs and route tables with no internet gateway path to satisfy air-gapped data requirements.
  • Kubernetes Integration: Applying specific tags like ‘kubernetes.io/role/elb’ to public subnets for automated AWS Load Balancer Controller discovery.
  • Network Forensics: Utilizing dual-destination flow logs (CloudWatch for real-time alerts and S3 for long-term Athena analysis) to baseline normal traffic patterns.

References:

Continue reading

Next article

Deep Dive: Proxmox Cluster Synchronization via Corosync and pmxcfs Internals

Related Content