AWS Subnet Provisioning With Terraform For VPC Public And Private Architectures

Terraform enables repeatable definition of AWS networking components, with aws_subnet as the core resource for carving a VPC CIDR into isolated network segments. The reference implementations show how public subnets with internet-facing routing coexist with private subnets that rely on NAT gateways for outbound connectivity. Proper tagging, availability zone distribution, and CIDR planning are required for secure, highly available cloud networking.

Project Structure And Prerequisites For Terraform AWS Networking

The documented project layout separates configuration into discrete files for maintainability.

networking-terraform/ ├── main.tf ├── variables.tf ├── outputs.tf └── terraform.tfvars

Prerequisites before applying any subnet configuration are explicit. AWS CLI must be configured with appropriate permissions. Terraform version 1.0.0 or later is required. Basic understanding of AWS networking concepts and CIDR notation and IP addressing is assumed.

For server based workflows, the step by step guide starts with an EC2 instance named terraform-server using Amazon Linux AMI, with a security key selected and default options retained. Connection is via SSH or AWS CLI.

Terraform installation on Amazon Linux uses package manager commands:

bash sudo yum install -y yum-utils sudo yum-config-manager --add-repo https://rpm.releases.hashicorp.com/AmazonLinux/hashicorp.repo sudo yum -y install terraform

AWS CLI configuration on the server is performed with:

bash aws configure

This prompts for access key, secret key, region, and output format. An IAM user with desired permissions is created to generate the credentials.

VPC Foundation And Availability Zone Discovery

The provider block pins the AWS provider and region.

hcl terraform { required_providers { aws = { source = "hashicorp/aws" version = "~> 4.0" } } } provider "aws" { region = var.aws_region }

The VPC resource forms the network boundary.

hcl resource "aws_vpc" "main" { cidr_block = var.vpc_cidr enable_dns_hostnames = true enable_dns_support = true tags = { Name = "${var.project_name}-vpc" Environment = var.environment } }

Availability zones are discovered dynamically:

hcl data "aws_availability_zones" "available" { state = "available" }

Distributing subnets across multiple availability zones creates resilient AWS cloud networking architecture that withstands zone failures. Deploy both public and private subnets in at least two AZs, enabling cross-zone load balancing and database failover capabilities.

Public Subnet Definition With CIDR Calculation And Auto Assign

Public subnets require direct internet access via an Internet Gateway and auto assignment of public IP addresses.

hcl resource "aws_subnet" "public" { count = var.az_count vpc_id = aws_vpc.main.id cidr_block = cidrsubnet(var.vpc_cidr, 8, count.index) availability_zone = data.aws_availability_zones.available.names[count.index] map_public_ip_on_launch = true tags = { Name = "${var.project_name}-public-${count.index + 1}" Environment = var.environment Type = "Public" } }

Configure these subnets with an internet gateway route and enable auto-assign public IP addresses. Your Terraform AWS networking setup should define public subnets with appropriate CIDR blocks that don't overlap with private ranges, ensuring clean separation between internet-facing and internal resources.

The map_public_ip_on_launch = true setting is essential for public subnets. Terraform AWS networking configurations require precise VPC, subnet, and NAT Gateway definitions for secure, scalable infrastructure. Define VPC CIDR blocks using /16 ranges like 192.168.0.0/16 and associate public subnets with Internet Gateways for internet-facing resources.

Private Subnet Definition For Isolated Workloads

Private subnets host application servers and databases without direct internet exposure.

hcl resource "aws_subnet" "private" { count = var.az_count vpc_id = aws_vpc.main.id cidr_block = cidrsubnet(var.vpc_cidr, 8, count.index + var.az_count) }

Private subnets provide the secure backbone of your Terraform AWS infrastructure, hosting application servers and databases without direct internet exposure. Route traffic through NAT gateways for outbound connectivity while maintaining complete inbound isolation. Your AWS subnets configuration should implement strict network ACLs and security group rules, creating multiple layers of protection for sensitive workloads and ensuring compliance with security best practices.

Public Versus Private Subnet Attributes

Attribute Public Subnet Private Subnet
Internet Access Direct via Internet Gateway Via NAT Gateway
mappubliciponlaunch true false
Inbound Internet Allowed Blocked
Typical Workload Load balancers, NAT, bastion App servers, databases
Route Table 0.0.0.0/0 to IGW 0.0.0.0/0 to NAT Gateway

NAT Gateway And Elastic IP Integration

Outbound connectivity for private instances is provided by a NAT Gateway placed in a public subnet.

hcl resource "aws_subnet" "public_subnet" { vpc_id = aws_vpc.main.id cidr_block = "10.0.1.0/24" map_public_ip_on_launch = true availability_zone = "us-east-1a" }

hcl resource "aws_eip" "nat_eip" { vpc = true }

hcl resource "aws_nat_gateway" "nat_gateway" { subnet_id = aws_subnet.public_subnet.id allocation_id = aws_eip.nat_eip.id }

Implement NAT Gateways in public subnets with Elastic IPs managed via Terraform's aws_eip resource to enable outbound access for private instances.

To verify creation, the AWS CLI command is:

bash aws ec2 describe-nat-gateways --filter "Name=subnet-id,Values=10.0.1.0/24"

According to recent benchmarks from 2026, deployments using Terraform 1.6.x and AWS provider 5.36.x show a 20% improvement in provisioning speed and a 35% reduction in configuration drift compared to earlier versions. Use Terraform 1.6.2 with AWS provider 5.36.0 for enhanced validation and drift detection.

Data Sources And Tag-Based Subnet Lookups

When working with existing subnets, manual variable lists become clunky. Terraform provides built in Data Sources to look up VPC and subnet data which can then be filtered using Tags.

The philosophy is that subnets already exist as resources in the environment and to that end you shouldn't have to waste time looking up their IDs or CIDRs manually just to paste them in to your code when the whole point of Terraform is to do this stuff dynamically.

It is essential that your subnets are suitably tagged. Tag based lookups reduce hard coding and support environments with complicated networks.

Route Table Configuration And Verification

Private subnets must have their route tables configured to direct internet-bound traffic through the NAT Gateway. This is done by adding a route to the NAT Gateway's IP address.

For a production-ready setup, it is important to ensure that the subnet is configured with a route to an Internet Gateway or a NAT Gateway itself. In Terraform, this is achieved by defining a public subnet and associating it with a NAT Gateway resource.

Evaluate subnet layouts and route tables based on workload requirements, ensuring map_public_ip_on_launch is enabled for public subnets.

Best Practices For High Availability And Security Isolation

  • Spread subnets across multiple availability zones for high availability. The guide recommends deploying both public and private subnets in at least two AZs.
  • Use strict network ACLs and security group rules for private subnets to create multiple layers of protection.
  • Keep CIDR blocks non-overlapping between public and private ranges for clean separation.
  • Enable DNS hostnames and DNS support on the VPC for proper name resolution.
  • Tag subnets consistently with Name, Environment, and Type to enable data source filtering.

Conclusion

Managing AWS networking with Terraform centers on precise aws_subnet definitions paired with correct routing, tagging, and availability zone distribution. Public subnets with map_public_ip_on_launch and Internet Gateway routes support ingress, while private subnets behind NAT Gateways with Elastic IPs provide secure outbound access. Tag-driven data sources reduce maintenance overhead as networks scale. With Terraform 1.6.x and AWS provider 5.36.x delivering improved provisioning speed and drift reduction, the current best practice combines CIDR planning, multi-AZ placement, and automated lookups for resilient, compliant infrastructure.

Sources

  1. Managing AWS Networking With Terraform
  2. AWS VPC Public Private Subnets Terraform
  3. Managing AWS Networking With Terraform VPC Subnets Security Groups Explained
  4. Terraform Tricks Working With AWS Subnets
  5. Terraform AWS Networking VPC Subnets NAT Gateway

Related Posts