This Terraform module creates a production-ready AWS VPC with a standardized architecture using a single /16 CIDR block. The module implements AWS best practices for network segmentation, high availability, and security.
- ✅ High Availability: Deploys across 2 availability zones for redundancy
- ✅ Network Segmentation: Separate public and private subnets per AZ
- ✅ NAT Gateways: One NAT Gateway per AZ for private subnet internet access
- ✅ DNS Support: Enabled DNS hostnames and support for AWS services
- ✅ Flow Logs: Optional VPC Flow Logs for network monitoring
- ✅ Consistent Tagging: Automatic tagging with customizable tags
- ✅ CIDR Validation: Enforces /16 CIDR blocks for consistent subnet allocation
The module creates a VPC with the following subnet allocation strategy:
| Subnet Type | CIDR Calculation | Size | Hosts per Subnet | Purpose |
|---|---|---|---|---|
| Public | cidrsubnet(vpc_cidr, 6, index) |
/22 | 1,019 | Load balancers, NAT Gateways, Bastion hosts |
| Private | cidrsubnet(vpc_cidr, 2, 1+index) |
/18 | 16,379 | Application servers, databases, internal services |
| Network Address | Subnet Type | Availability Zone | Available IPs |
|---|---|---|---|
| 10.0.0.0/22 | Public | AZ-1 | 1,019 |
| 10.0.4.0/22 | Public | AZ-2 | 1,019 |
| 10.0.64.0/18 | Private | AZ-1 | 16,379 |
| 10.0.128.0/18 | Private | AZ-2 | 16,379 |
Note: The IP space between 10.0.8.0 and 10.0.63.255 is intentionally left unallocated for future expansion or special requirements.
Internet → Internet Gateway → Public Subnet → NAT Gateway → Private Subnet
↓
Load Balancers
↓
Application Servers
(Private Subnet)
module "vpc" {
source = "git::https://github.com/helmcode/helmcode-vpc.git"
# or for a specific version:
# source = "git::https://github.com/helmcode/helmcode-vpc.git?ref=v1.0.0"
name = "production-vpc"
cidr_block = "10.0.0.0/16"
tags = {
Environment = "production"
Team = "platform"
}
}module "vpc" {
source = "git::https://github.com/helmcode/helmcode-vpc.git"
# or for a specific version:
# source = "git::https://github.com/helmcode/helmcode-vpc.git?ref=v1.0.0"
name = "production-vpc"
cidr_block = "10.0.0.0/16"
create_flow_log = true
# Additional tags for subnets
public_subnet_tags = {
"kubernetes.io/role/elb" = "1"
}
private_subnet_tags = {
"kubernetes.io/role/internal-elb" = "1"
}
tags = {
Environment = "production"
Team = "platform"
CostCenter = "engineering"
}
}
# Using outputs
resource "aws_instance" "app" {
subnet_id = module.vpc.private_subnet_ids[0]
# ... other configuration
}
resource "aws_lb" "main" {
subnets = module.vpc.public_subnet_ids
# ... other configuration
}| Name | Version |
|---|---|
| terraform | ~> 1.0 |
| aws | ~> 4.0 |
| Name | Version |
|---|---|
| aws | ~> 4.0 |
| random | n/a |
The module creates the following AWS resources:
| Resource | Purpose | Count |
|---|---|---|
aws_vpc |
Main VPC resource | 1 |
aws_internet_gateway |
Internet access for public subnets | 1 |
aws_subnet (public) |
Public subnets for external-facing resources | 2 |
aws_subnet (private) |
Private subnets for internal resources | 2 |
aws_eip |
Elastic IPs for NAT Gateways | 2 |
aws_nat_gateway |
NAT Gateways for private subnet internet access | 2 |
aws_route_table (public) |
Routing for public subnets | 1 |
aws_route_table (private) |
Routing for private subnets | 2 |
aws_route |
Route entries for internet access | 3 |
aws_route_table_association |
Subnet to route table associations | 4 |
aws_flow_log |
VPC Flow Logs (optional) | 0-1 |
aws_cloudwatch_log_group |
CloudWatch Logs for Flow Logs (optional) | 0-1 |
aws_iam_role |
IAM role for Flow Logs (optional) | 0-1 |
aws_iam_policy |
IAM policy for Flow Logs (optional) | 0-1 |
| Name | Description | Type | Default | Required |
|---|---|---|---|---|
| cidr_block | The IPv4 CIDR block of the VPC. Must be /16. | string |
n/a | yes |
| name | The name of the VPC. Used for resource naming. | string |
n/a | yes |
| tags | A map of tags to assign to all resources. | map(string) |
n/a | yes |
| create_flow_log | Whether to create VPC flow logs for network monitoring. | bool |
false |
no |
| private_subnet_tags | Additional tags to assign to all private subnets. | map(string) |
{} |
no |
| public_subnet_tags | Additional tags to assign to all public subnets. | map(string) |
{} |
no |
| Name | Description |
|---|---|
| vpc_id | The ID of the VPC |
| cidr_block | The CIDR block of the VPC |
| public_subnet_ids | List of IDs of public subnets |
| private_subnet_ids | List of IDs of private subnets |
| nat_gateway_public_ips | List of public Elastic IPs created for NAT Gateways |
- Minimal - Basic VPC configuration
- Complete (TODO) - Full configuration with all options
- Network Isolation: Private subnets have no direct internet access; all outbound traffic flows through NAT Gateways
- Flow Logs: Enable VPC Flow Logs in production for security monitoring and compliance
- Tagging: Consistent tagging helps with cost allocation and compliance tracking
- CIDR Planning: The /16 requirement ensures sufficient IP space for growth while maintaining consistency
The following resources incur hourly charges:
- NAT Gateways: ~$0.045/hour per gateway (2 gateways = ~$0.09/hour)
- Elastic IPs: Free when attached to running resources
- VPC Flow Logs: CloudWatch Logs storage charges apply
Monthly estimate: ~$65-70 (NAT Gateways only, excluding data transfer)
If you're migrating from an existing VPC:
- Plan your CIDR block to avoid conflicts
- Update security group rules to reference the new VPC
- Migrate resources gradually using blue-green deployment
- Update DNS entries after migration
- Delete old VPC resources after verification
-
CIDR Block Validation Error
- Ensure your CIDR block ends with
/16 - Example: ✅
10.0.0.0/16❌10.0.0.0/24
- Ensure your CIDR block ends with
-
Subnet Exhaustion
- The module uses fixed subnet calculations
- Cannot modify subnet sizes after creation
-
Resource Limits
- Check AWS service quotas for VPCs, subnets, and NAT Gateways
- Request limit increases if needed
Contributions are welcome! Please follow these guidelines:
- Update documentation for any new features
- Add examples for new functionality
- Run
terraform fmtbefore submitting - Update the README with any new variables or outputs
[Specify your license here]
- [Your Name/Organization]
This module implements AWS VPC best practices as recommended in:
Note: This module requires Terraform 1.0+ and AWS Provider 4.0+. For older versions, please use previous releases of this module.