AWS · AWS · AWS VPC
Production VPC (Multi-AZ)
Battle-tested multi-AZ VPC with public/private/database subnets, NAT, endpoints, and flow logs.
Compare Virtual Private Cloud (VPC) across clouds →
Verification
Live-testedReally deployed, verified, idempotent and destroyed in a cloud sandbox.
Conformance
- Static validation (fmt · validate · tflint)
- Security scan: findings disclosed (Checkov)
- Plan tests (mocked: validation rules · outputs)
Provenance
- SHA-256 checksum
- Signature (pending)
Functional
- Live-tested — applied, verified, destroyed
Last verified 2026-06-11 · how we verify
Details
- Type
- tf_module
- Provider / collection
- hashicorp/aws
- Target clouds
- aws
- Target OS
- —
- Version
- v1.0.0
- License
- LicenseRef-IaCBazaar-Commercial
$129.00
one-time · perpetual license + 12 months of updates
Included in the builder+ subscription.
Documentation
aws-vpc — Production VPC (Multi-AZ)
Battle-tested multi-AZ VPC with public/private/database subnets, NAT, endpoints,
and flow logs. Three subnet tiers (public, private-with-egress, fully isolated
database), a NAT strategy dial (none / single / per_az), free S3/DynamoDB
gateway endpoints attached to every route table, CloudWatch flow logs behind a
least-privilege IAM role, and a stripped default security group — secure
defaults you would otherwise assemble from a dozen resources by hand.
Works with Terraform and OpenTofu (>= 1.6), AWS provider >= 6.0, < 7.0.
Usage
module "vpc" {
source = "./aws-vpc"
name = "prod"
cidr_block = "10.0.0.0/16"
azs = ["eu-central-1a", "eu-central-1b", "eu-central-1c"]
public_subnet_cidrs = ["10.0.0.0/24", "10.0.1.0/24", "10.0.2.0/24"]
private_subnet_cidrs = ["10.0.16.0/20", "10.0.32.0/20", "10.0.48.0/20"]
database_subnet_cidrs = ["10.0.64.0/24", "10.0.65.0/24", "10.0.66.0/24"]
nat_gateway_mode = "per_az" # "single" to save money, "none" for air-gapped
tags = { Environment = "prod" }
}
All subnet CIDR lists are index-aligned to azs (entry i lands in AZ
i). Any tier can be omitted by leaving its list empty. Database subnets get a
route table with no routes at all — reachable only from inside the VPC.
Inputs
| Name | Type | Default | Description |
|---|---|---|---|
name | string | — | Name prefix for the VPC and all child resources (required) |
cidr_block | string | — | IPv4 CIDR of the VPC (required) |
azs | list(string) | — | ≥ 2 availability zone names (required) |
public_subnet_cidrs | list(string) | [] | Public subnet CIDRs, one per AZ |
private_subnet_cidrs | list(string) | [] | Private subnet CIDRs, one per AZ |
database_subnet_cidrs | list(string) | [] | Isolated database subnet CIDRs, one per AZ |
nat_gateway_mode | string | "single" | none, single, or per_az |
map_public_ip_on_launch | bool | false | Auto-assign public IPs in public subnets |
enable_dns_support | bool | true | VPC DNS resolution |
enable_dns_hostnames | bool | true | VPC DNS hostnames (needed for interface endpoints/EKS) |
instance_tenancy | string | "default" | default or dedicated |
gateway_vpc_endpoints | set(string) | ["s3"] | Free gateway endpoints: s3 and/or dynamodb |
enable_flow_log | bool | true | VPC flow log to a module-managed CloudWatch log group |
flow_log_traffic_type | string | "ALL" | ACCEPT, REJECT, or ALL |
flow_log_retention_days | number | 90 | Log group retention (CloudWatch-supported values) |
flow_log_max_aggregation_interval | number | 60 | 60 or 600 seconds |
flow_log_kms_key_arn | string | null | CMK for the flow-log log group |
manage_default_security_group | bool | true | Strip all rules from the VPC default SG |
public_subnet_tags | map(string) | {} | Extra tags for public subnets (e.g. kubernetes.io/role/elb) |
private_subnet_tags | map(string) | {} | Extra tags for private subnets |
database_subnet_tags | map(string) | {} | Extra tags for database subnets |
tags | map(string) | {} | Tags applied to all resources |
Outputs
| Name | Description |
|---|---|
vpc_id, vpc_arn, vpc_cidr_block | VPC identifiers |
public_subnet_ids, private_subnet_ids, database_subnet_ids | Subnet ID lists, AZ-ordered |
public_subnets_by_az, private_subnets_by_az, database_subnets_by_az | AZ => subnet ID maps |
internet_gateway_id | IGW ID (null without a public tier) |
nat_gateway_ids, nat_public_ips | AZ-keyed NAT gateway IDs / public IPs |
public_route_table_id, private_route_table_ids, database_route_table_id | Route table IDs |
gateway_vpc_endpoint_ids | Service => endpoint ID map |
flow_log_id, flow_log_group_name, flow_log_role_arn | Flow-log resources |
Cost notes
- NAT gateways bill hourly + per-GB.
singleis the budget option;per_azremoves the cross-AZ single point of failure. - Gateway endpoints (S3/DynamoDB) are free and on by default for S3 — they keep bulk traffic off the NAT data-processing meter.
Requirements
- Terraform or OpenTofu
>= 1.6 hashicorp/aws>= 6.0, < 7.0
Verification
Static-validated (fmt, validate, tflint). Live apply/destroy testing pending cloud sandbox availability — see catalog status.
License
Commercial — IaC Bazaar EULA. © IaC Bazaar. Original work (not derived from a third-party module).