Overview
The VPC module creates a complete AWS VPC infrastructure with public and private subnets across multiple availability zones, NAT gateways for outbound internet access, and optional VPC endpoints for S3 and DynamoDB.Features
Multi-AZ Support
Deploy subnets across multiple availability zones for high availability
Public & Private Subnets
Separate public subnets with internet access and private subnets with NAT
NAT Gateway Options
Single or multiple NAT gateways for cost vs. availability tradeoff
VPC Endpoints
Optional S3 and DynamoDB endpoints to reduce NAT costs
Flow Logs
Optional VPC flow logs for network monitoring and troubleshooting
EKS Integration
Automatic subnet tagging for AWS Load Balancer Controller
Architecture
Multi-AZ with High Availability
Usage Examples
Basic Configuration
Development Environment (Cost-Optimized)
Production Environment (High Availability)
EKS-Ready VPC
Automatically tag subnets for AWS Load Balancer Controller:When
eks_cluster_name is set, the module adds:kubernetes.io/cluster/<name> = sharedto all subnetskubernetes.io/role/elb = 1to public subnetskubernetes.io/role/internal-elb = 1to private subnets
Minimal Configuration (Public Only)
For simple use cases without private subnets:Inputs
| Name | Description | Type | Default | Required |
|---|---|---|---|---|
vpc_name | Name to be used on all the resources as identifier | string | n/a | yes |
vpc_cidr | The CIDR block for the VPC | string | n/a | yes |
aws_region | AWS region where resources will be created | string | n/a | yes |
availability_zones | List of availability zones in which to create subnets | list(string) | n/a | yes |
public_subnet_cidrs | List of CIDR blocks for public subnets | list(string) | [] | no |
private_subnet_cidrs | List of CIDR blocks for private subnets | list(string) | [] | no |
eks_cluster_name | Optional EKS cluster name used to tag subnets for Kubernetes load balancers | string | null | no |
enable_dns_hostnames | Should be true to enable DNS hostnames in the VPC | bool | true | no |
enable_dns_support | Should be true to enable DNS support in the VPC | bool | true | no |
create_igw | Controls if an Internet Gateway is created for public subnets | bool | true | no |
map_public_ip_on_launch | Should be true to auto-assign public IP on launch | bool | true | no |
enable_nat_gateway | Should be true if you want to provision NAT Gateways for private subnets | bool | true | no |
single_nat_gateway | Should be true if you want to provision a single shared NAT Gateway | bool | false | no |
enable_flow_logs | Whether to enable VPC Flow Logs | bool | false | no |
flow_logs_destination_type | Type of flow log destination (cloud-watch-logs or s3) | string | "cloud-watch-logs" | no |
flow_logs_destination_arn | ARN of the destination for VPC Flow Logs | string | "" | no |
flow_logs_iam_role_arn | ARN of the IAM role for VPC Flow Logs | string | "" | no |
flow_logs_traffic_type | Type of traffic to capture (ACCEPT, REJECT, ALL) | string | "ALL" | no |
manage_default_security_group | Should be true to adopt and manage the default security group | bool | true | no |
enable_s3_endpoint | Should be true if you want to provision an S3 VPC endpoint | bool | false | no |
enable_dynamodb_endpoint | Should be true if you want to provision a DynamoDB VPC endpoint | bool | false | no |
tags | A map of tags to add to all resources | map(string) | {} | no |
Outputs
| Name | Description |
|---|---|
vpc_id | The ID of the VPC |
vpc_arn | The ARN of the VPC |
vpc_cidr_block | The CIDR block of the VPC |
internet_gateway_id | The ID of the Internet Gateway |
public_subnet_ids | List of IDs of public subnets |
public_subnet_arns | List of ARNs of public subnets |
public_subnet_cidr_blocks | List of CIDR blocks of public subnets |
private_subnet_ids | List of IDs of private subnets |
private_subnet_arns | List of ARNs of private subnets |
private_subnet_cidr_blocks | List of CIDR blocks of private subnets |
nat_gateway_ids | List of NAT Gateway IDs |
nat_eip_public_ips | List of public Elastic IPs created for NAT Gateways |
public_route_table_ids | List of IDs of public route tables |
private_route_table_ids | List of IDs of private route tables |
vpc_flow_log_id | The ID of the VPC Flow Log |
default_security_group_id | The ID of the default security group |
vpc_endpoint_s3_id | The ID of the S3 VPC endpoint |
vpc_endpoint_dynamodb_id | The ID of the DynamoDB VPC endpoint |
availability_zones | List of availability zones used |
Cost Considerations
NAT Gateway Costs
NAT Gateway Costs
Hourly Charges:
- Each NAT Gateway: ~32/month)
- Data processing: $0.045/GB
- Development: Use
single_nat_gateway = true - Production: Use one NAT per AZ for HA
- Consider VPC endpoints to reduce NAT data transfer
VPC Endpoints
VPC Endpoints
Gateway Endpoints (Free):
- S3 and DynamoDB endpoints have no hourly charge
- Saves NAT data processing costs
- Enable in production to reduce costs
- Not included in this module
- ~7/month per endpoint)
Elastic IPs
Elastic IPs
- NAT gateways include EIP allocation
- No charge while attached to running NAT gateway
- Small charge for unattached EIPs
Flow Logs
Flow Logs
- CloudWatch Logs: Storage + ingestion costs
- S3: Storage costs only
- Consider retention policies to manage costs
Best Practices
CIDR Planning
Use a VPC CIDR that allows for growth. A /16 (65,536 IPs) is recommended for most use cases.
Multi-AZ
Always use at least 2 AZs for development and 3 AZs for production workloads.
Subnet Sizing
Public subnets can be smaller (/24 = 256 IPs). Private subnets should be larger for pod IP addresses.
NAT Strategy
Development: Single NAT. Production: One NAT per AZ for resilience.
VPC Endpoints
Enable S3 and DynamoDB endpoints in production to save on NAT costs.
Flow Logs
Enable flow logs in production for security monitoring and troubleshooting.
Troubleshooting
Subnet CIDR Conflicts
Error:NAT Gateway Attachment Issues
Error:EKS Subnet Discovery
If EKS can’t discover subnets:- Verify
eks_cluster_namematches your cluster name exactly - Check that tags are present on subnets:
- Ensure both public and private subnets have appropriate role tags
Flow Logs Not Working
Common issues:- IAM role missing permissions
- CloudWatch Log Group doesn’t exist
- IAM role trust policy incorrect
Related Documentation
EKS Module
Deploy EKS cluster in this VPC
RDS Module
Create RDS instances in private subnets
EC2 Module
Launch EC2 instances in subnets
Usage Guide
Common patterns and best practices