Skip to content

Latest commit

 

History

History
206 lines (170 loc) · 14.4 KB

File metadata and controls

206 lines (170 loc) · 14.4 KB

Red Network

Red Network Module

Requirements:

  1. Terraform 1.14.6
  2. Trivy >= 0.68.2

Trivy can be installed via Homebrew on macOS with the command:

brew install aquasecurity/trivy/trivy

A practical AWS VPC module with first-class support for hub-and-spoke topologies and centralized NAT — share one NAT gateway across many VPCs via a Transit Gateway instead of paying for one per VPC.

Why this module

Most VPC modules stop at "make me a VPC." Red Network goes further: spoke VPCs can skip their own NAT gateway entirely and route outbound traffic through a hub VPC's shared NAT over a Transit Gateway. At roughly $32/month per NAT gateway, that difference adds up fast once you have more than one VPC.

Security posture

  • Public IP assignment is scoped to subnets you explicitly declare as type = "public"; private subnets never auto-assign
  • VPC Flow Logs are available opt-in via enable_flow_logs (CloudWatch, configurable retention and traffic type) — off by default to avoid imposing cost, on when you want the visibility
  • An S3 Gateway VPC Endpoint keeps S3 traffic off the public internet
  • Scanned with Trivy and gitleaks on every commit; integration-tested with Terratest across baseline, hub-and-spoke, and public-only topologies

Features

  • VPC with DNS hostnames and resolution
  • Flexible subnet layout via a single subnets map (public, private, or both)
  • Internet Gateway provisioned automatically when public subnets exist
  • NAT Gateway with Elastic IP for private subnet egress, or skip it entirely with create_nat_gateway = false for public-only VPCs (no NAT cost)
  • S3 Gateway VPC Endpoint with route table associations
  • Optional Transit Gateway creation for hub-and-spoke topologies
  • Optional Transit Gateway attachment with automatic private-subnet selection
  • Cross-VPC routing via configurable CIDR-based Transit Gateway routes
  • Centralized NAT — spoke VPCs route outbound traffic through a hub VPC's shared NAT via the Transit Gateway
  • Opt-in VPC Flow Logs to CloudWatch
  • Configurable tags with project and orchestrator metadata

Usage

A VPC with public and private subnets — see examples/complete:

provider "aws" {
  region = "us-east-1"
}

module "network" {
  source = "RussellGilmore/red-network/aws"

  project_name = "my-project"
  vpc_name     = "my-project-vpc"
  vpc_cidr     = "10.0.0.0/16"

  subnets = {
    public-1a = {
      name              = "public-1a"
      cidr_block        = "10.0.1.0/24"
      availability_zone = "us-east-1a"
      type              = "public"
    }
    private-1a = {
      name              = "private-1a"
      cidr_block        = "10.0.11.0/24"
      availability_zone = "us-east-1a"
      type              = "private"
    }
  }
}

Hub-and-spoke with centralized NAT

The hub owns the Transit Gateway and a NAT gateway; each spoke attaches to the hub's TGW and sets use_centralized_nat = true to route its private subnets' outbound traffic through the hub instead of provisioning its own NAT. See examples/hub-and-spoke for the full two-VPC configuration.

Public-only VPC (no NAT cost)

For bastion or build hosts that only need an Internet Gateway and no private egress, set create_nat_gateway = false to skip the NAT gateway entirely. See examples/public-only.

VPC Flow Logs

Set enable_flow_logs = true to capture flow logs to CloudWatch. The module creates the log group, IAM role, and flow log for you; retention (flow_logs_retention_days), traffic type (flow_logs_traffic_type), and log group name (flow_logs_log_group_name) are all configurable.

Requirements

Name Version
terraform >= 1.15.0
aws >= 6.47.0

Providers

Name Version
aws >= 6.47.0

Modules

No modules.

Resources

Name Type
aws_cloudwatch_log_group.flow_logs resource
aws_ec2_transit_gateway.main resource
aws_ec2_transit_gateway_vpc_attachment.main resource
aws_eip.nat resource
aws_flow_log.main resource
aws_iam_role.flow_logs resource
aws_iam_role_policy.flow_logs resource
aws_internet_gateway.main resource
aws_nat_gateway.main resource
aws_route.private_centralized_nat resource
aws_route.private_nat resource
aws_route.private_tgw resource
aws_route.public_internet resource
aws_route.public_tgw resource
aws_route_table.private resource
aws_route_table.public resource
aws_route_table_association.private resource
aws_route_table_association.public resource
aws_subnet.subnets resource
aws_vpc.main resource
aws_vpc_endpoint.s3 resource
aws_vpc_endpoint_route_table_association.s3_private resource
aws_vpc_endpoint_route_table_association.s3_public resource
aws_region.current data source

Inputs

Name Description Type Default Required
additional_tags Additional tags to apply to the resources map(string) {} no
attach_to_transit_gateway Whether to attach this VPC to a Transit Gateway bool false no
create_nat_gateway Whether to create a NAT gateway for private subnet outbound internet access. Defaults to true (created when public subnets exist). Set to false for public-only VPCs (e.g. bastion or build hosts) that have no private subnets needing egress, avoiding the NAT gateway hourly + data processing cost. Ignored when use_centralized_nat is true. bool true no
create_transit_gateway Whether to create a new Transit Gateway bool false no
enable_flow_logs Enable VPC Flow Logs to CloudWatch. When true, the module creates a CloudWatch log group, an IAM role, and the flow log itself. bool false no
flow_logs_log_group_name Name of the CloudWatch log group for VPC flow logs. When empty, defaults to /aws/vpc-flow-logs/<vpc_name>. Only used when enable_flow_logs is true. string "" no
flow_logs_retention_days Retention period in days for the flow logs CloudWatch log group. Only used when enable_flow_logs is true. number 30 no
flow_logs_traffic_type Type of traffic to capture in flow logs: ALL, ACCEPT, or REJECT. string "ALL" no
project_name Set the project name. string n/a yes
subnets Map of subnets to create. Each subnet should specify name, cidr_block, availability_zone, and type (public/private)
map(object({
name = string
cidr_block = string
availability_zone = string
type = string
}))
n/a yes
transit_gateway_asn Amazon side ASN for the Transit Gateway number 64512 no
transit_gateway_id ID of an existing Transit Gateway to attach to (required if attach_to_transit_gateway is true and create_transit_gateway is false) string "" no
transit_gateway_name Name for the Transit Gateway (only used if create_transit_gateway is true) string "" no
transit_gateway_routes List of CIDR blocks to route through the Transit Gateway (e.g., other VPC CIDRs) list(string) [] no
use_centralized_nat If true, this VPC will NOT create its own NAT gateway. Instead, a default route (0.0.0.0/0) on private subnets will point to the Transit Gateway, expecting a hub VPC to provide NAT. Only applies when attach_to_transit_gateway is true. bool false no
vpc_cidr CIDR block for the VPC string n/a yes
vpc_name Name of the VPC string n/a yes

Outputs

Name Description
has_public_subnets Boolean indicating if the VPC has any public subnets
internet_gateway_id ID of the Internet Gateway (if public subnets exist)
nat_gateway_id ID of the NAT Gateway (if created — not present when using centralized NAT)
nat_gateway_public_ip Public IP address of the NAT Gateway (if created — not present when using centralized NAT)
private_route_table_id ID of the private route table
private_subnet_ids List of private subnet IDs
public_route_table_id ID of the public route table (if public subnets exist)
public_subnet_ids List of public subnet IDs
s3_vpc_endpoint_id ID of the S3 VPC Endpoint
s3_vpc_endpoint_prefix_list_id Prefix list ID of the S3 VPC Endpoint (useful for security groups)
subnet_arns Map of subnet names to their ARNs
subnet_availability_zones Map of subnet names to their availability zones
subnet_cidrs Map of subnet names to their CIDR blocks
subnet_ids Map of subnet names to their IDs
transit_gateway_arn ARN of the Transit Gateway (if created)
transit_gateway_attachment_id ID of the Transit Gateway VPC Attachment (if attached)
transit_gateway_id ID of the Transit Gateway (if created)
using_centralized_nat Boolean indicating if this VPC uses centralized NAT via Transit Gateway
vpc_arn The ARN of the VPC
vpc_cidr The CIDR block of the VPC
vpc_id The ID of the VPC