← Back to list

Building a Production-Ready Advanced AWS VPC with Terraform

Building a Production-Ready AWS VPC with Terraform: Multi-AZ Design, NAT Gateways, VPC Endpoints, and Flow Logs

Manojkumar’s Tech Stack in AWS Tip · 2026-06-14 16:18 · 9 claps · 3.6 min read paywalled
#aws #aws-vpc #terraform #devops #aws-eks
Open on Medium ↗
Wiki topics: FT · Fine-tuning & Adaptation ☁️ · DevOps & Cloud

Building a Production-Ready Advanced AWS VPC with Terraform

Every cloud project starts with networking.

Whether you’re planning to deploy EC2 instances, containerized workloads, databases, or an Amazon EKS cluster, a well-designed Virtual Private Cloud (VPC) becomes the foundation that everything else depends on.

Over the years, I’ve seen many teams rush through VPC creation by manually clicking through the AWS console. It works initially, but as environments grow, maintaining consistency across development, staging, and production becomes difficult.

To avoid that problem, I recently built a reusable Terraform configuration that creates a production-ready AWS VPC foundation while remaining flexible enough for future workloads, including Kubernetes, ECS, databases, and shared services.

In this article, I’ll walk through the design decisions, architecture, and Terraform features that make this VPC both scalable and practical for real-world environments.

Architecture Overview

The Terraform configuration automatically selects three Availability Zones in the target AWS region.

The VPC is deployed with:

  • Public subnets across three AZs
  • Private subnets across three AZs
  • Internet Gateway
  • Optional NAT Gateways
  • Optional VPC Endpoints
  • Optional VPC Flow Logs
  • Centralized tagging strategy

The architecture looks like this:

This layout provides separation between internet-facing resources and internal workloads while maintaining high availability across multiple availability zones.

Automatic Subnet Allocation

One of the challenges with network design is subnet planning.

Instead of manually calculating CIDR ranges, Terraform automatically generates subnet CIDRs using the cidrsubnet() function.

The default VPC CIDR is:

10.0.0.0/16

Using:

subnet_newbits = 8

Terraform automatically creates /24 subnets.

For example:

Public Subnet 1    10.20.0.0/24
Public Subnet 2    10.20.1.0/24
Public Subnet 3    10.20.2.0/24

Private Subnet 1   10.20.3.0/24
Private Subnet 2   10.20.4.0/24
Private Subnet 3   10.20.5.0/24

This approach eliminates manual calculations and reduces the risk of overlapping subnet allocations.

Public and Private Subnet Strategy

Public subnets are configured with automatic public IP assignment and are intended for resources that require direct internet connectivity.

Examples include:

  • Load Balancers
  • Bastion Hosts
  • NAT Gateways

Private subnets do not assign public IP addresses and are intended for:

  • Application servers
  • Containers
  • Databases
  • Internal services

Keeping workloads in private subnets is one of the simplest ways to reduce exposure to the public internet.

Internet Access Design

Public internet connectivity is provided through an Internet Gateway.

The public route table contains:

0.0.0.0/0 -> Internet Gateway

Private workloads often require outbound internet access for:

  • Operating system updates
  • Package downloads
  • Container image pulls
  • External API communication

To support that requirement, NAT Gateway deployment is optional.

Choosing the Right NAT Gateway Strategy

One of the most common cost surprises in AWS networking comes from NAT Gateways.

This Terraform design supports two deployment models.

Single NAT Gateway

enable_nat_gateway = true
single_nat_gateway = true

Benefits:

  • Lower monthly cost
  • Easier management

Trade-offs:

  • Single point of failure
  • Cross-AZ traffic charges may occur

Ideal for:

  • Development
  • Testing
  • Smaller production environments

NAT Gateway Per Availability Zone

enable_nat_gateway = true
single_nat_gateway = false

Benefits:

  • Higher availability
  • Better fault tolerance
  • Reduced cross-AZ dependency

Trade-offs:

  • Increased monthly cost

Ideal for:

  • Production workloads
  • Mission-critical applications
  • Enterprise environments

For most production deployments, I strongly recommend one NAT Gateway per AZ.

Reducing NAT Costs with VPC Endpoints

Many workloads communicate primarily with AWS services rather than the public internet.

Examples include:

  • Amazon S3
  • Amazon ECR
  • AWS STS
  • CloudWatch Logs

Without VPC Endpoints, that traffic often flows through NAT Gateways.

To avoid unnecessary NAT costs, this configuration supports both Gateway and Interface VPC Endpoints.

Gateway Endpoint Example

gateway_vpc_endpoints = [
  "s3"
]

Traffic to S3 stays entirely within the AWS network.

Interface Endpoint Example

interface_vpc_endpoints = [
  "ecr.api",
  "ecr.dkr",
  "logs",
  "sts"
]

These endpoints are deployed in private subnets and secured using a dedicated security group.

For containerized workloads such as EKS, these endpoints can significantly reduce NAT Gateway traffic and improve security.

Network Visibility with VPC Flow Logs

Troubleshooting networking issues without logs can be frustrating.

This configuration includes optional VPC Flow Logs integration.

Enable flow logs using:

enable_flow_logs = true

Terraform automatically provisions:

  • CloudWatch Log Group
  • IAM Role
  • IAM Policy
  • VPC Flow Log

The default retention period is 90 days, which is a practical starting point for most environments.

Consistent Tagging Across Resources

As AWS environments grow, tagging becomes increasingly important.

This configuration applies default tags automatically:

Project     = var.name
Environment = var.environment
ManagedBy   = "terraform"
Terraform   = "true"

Additional tags can also be supplied:

additional_tags = {
  Owner      = "platform"
  CostCenter = "shared"
}

Built-In Safety Checks

One feature I always include in Terraform modules is validation.

This VPC configuration includes safeguards for common mistakes, including:

  • Invalid CIDR ranges
  • Excessive subnet counts
  • NAT Gateway deployment without public subnets
  • Missing private subnets for interface endpoints
  • Invalid flow log configuration

Catching errors during it terraform plan is significantly better than discovering them after deployment.

Preparing for Future Amazon EKS Deployments

Although this VPC is intentionally generic, it was designed with Kubernetes in mind.

Deployment

Clone Terraform Repo:

git clone https://github.com/GogineniManojkumar/cloudops.git

cd cloudops/Terraform/VPC

Initialize Terraform:

terraform init

Review the plan:

terraform plan

Deploy:

terraform apply

Remove resources when no longer needed:

terraform destroy

Final Thoughts

Networking decisions made early in a project tend to stay around for years.

Investing time in a reusable, well-structured Terraform VPC module pays dividends later by improving consistency, reducing operational effort, and making future platform initiatives significantly easier.

By combining multi-AZ networking, optional NAT strategies, VPC endpoints, flow logs, and built-in validation, this Terraform design provides a solid foundation for workloads ranging from traditional EC2 to large-scale Kubernetes environments.


메타데이터
post_id
829f34d644da
slug
building-a-production-ready-advanced-aws-vpc-with-terraform-829f34d644da
url
https://medium.com/@manojkumarcloud/building-a-production-ready-advanced-aws-vpc-with-terraform-829f34d644da
canonical_url
https://medium.com/@manojkumarcloud/building-a-production-ready-advanced-aws-vpc-with-terraform-829f34d644da
author_url
https://medium.com/@manojkumarcloud
status
ok
fetched_at
2026-06-24 23:31:39