Supercharging Terraform with AWS Cloud WAN Modules — Reference Implementation (Part 1 of 2)
Part 1 of 2: A concise, production‑ready README for evolving from a single‑Region deployment to a segmented, multi‑Region AWS Cloud WAN using Terraform modules and Terraform Cloud workspaces.
Supercharging Terraform with AWS Cloud WAN Modules — Reference Implementation
This is Part 1 of 2. Continue with Part 2 — Advanced AWS Cloud WAN with Service Insertion.
A concise, production‑ready README for evolving from a single‑Region deployment to a segmented, multi‑Region AWS Cloud WAN using Terraform modules and Terraform Cloud workspaces. Adapted from “Beyond the Basics: My Playbook for Supercharging Terraform with AWS Cloud WAN Modules” by Vitale Mazo.
Table of Contents
- Overview
- Architecture
- Prerequisites
- Quick Start
- Repository Layout
- Core Components
- Core Network Policy
- Logical VPC Module
- Terraform Cloud Workspace Strategy
- Governance & Guardrails
- Advanced Design Considerations
- Rollout & Operations Checklist
- Troubleshooting
- FAQ
- Credits
Overview
This reference distills a proven approach to managing AWS Cloud WAN at enterprise scale with Terraform. It focuses on segment‑based routing, environment isolation, and a multi‑workspace strategy that limits blast radius while enabling application teams to self‑serve VPCs via a logical VPC module.
Figure 1: AWS Cloud WAN Global Network Architecture - Source: AWS Architecture Blog
Architecture
High‑level design (segments govern reachability; policies evolve by version):
flowchart LR
subgraph Global_Network
subgraph Core_Network
direction TB
SEG_PROD[Segment: prod]
SEG_DEV[Segment: dev]
SEG_SHARED[Segment: shared]
SEG_SB[Segment: sandbox (isolated)]
end
end
VPCp1[VPC: prod (us-east-1)] --> SEG_PROD
VPCt1[VPC: test (us-east-1)] --> SEG_PROD
VPCd1[VPC: dev (us-east-1)] --> SEG_DEV
VPCs1[VPC: shared (us-east-1)] --> SEG_SHARED
VPCp2[VPC: prod (us-west-2)] --> SEG_PROD
VPCd2[VPC: dev (us-west-2)] --> SEG_DEV
VPCs2[VPC: shared (us-west-2)] --> SEG_SHARED
VPCsb[VPC: sandbox (us-west-2)] --> SEG_SB
SEG_SHARED <--> SEG_PROD
SEG_SHARED <--> SEG_DEV
Key tenets:
- prod and test live in the
prod
segment; dev is isolated from prod/test. - All environments can reach shared; sandbox is fully isolated (no shares).
- Policy (JSON) is versioned and applied to the Core Network; attachments are mapped via tags on the attachment (not just the VPC).
Prerequisites
- Terraform CLI and access to Terraform Cloud (Business recommended for governance).
- AWS account(s) with permissions for Network Manager / Cloud WAN.
- Basic familiarity with HCL and Terraform workspaces.
Terraform Provider & Backend (Quick Scaffold)
Use Terraform Cloud workspaces as recommended. Minimal boilerplate:
terraform {
required_version = ">= 1.5.0"
required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 5.0"
}
}
cloud {
organization = "YOUR_ORG"
workspaces { name = "net-global-foundation" }
}
}
provider "aws" {
region = "us-east-1"
}
Quick Start
- Foundation workspace: create the Global Network and Core Network.
- Policy v1: apply a single‑Region policy with
prod
,dev
,shared
. - Policy v2: add
us-west-2
and an isolatedsandbox
segment. - VPCs via module: app teams consume a logical VPC module that:
- creates the VPC + subnets + routes,
- creates the Cloud WAN VPC attachment,
- tags the attachment with
Environment
so the policy maps it to the right segment.
Repository Layout
.
├── foundation/
│ ├── 01-global-network.tf
│ ├── 02-core-network.tf
│ ├── 03-policy-v1.tf
│ └── 04-policy-v2.tf
├── modules/
│ └── logical-vpc/
│ └── main.tf
└── apps/
├── app-payments-prod-us-east-1/
├── app-analytics-dev-us-west-2/
└── app-research-sandbox-us-west-2/
Core Components
Global Network
The Global Network is the top‑level container spanning cloud + on‑prem.
# foundation/01-global-network.tf
resource "aws_networkmanager_global_network" "main" {
description = "Vitale Mazo's Global Enterprise Network"
tags = {
Owner = "Platform.Engineering"
CostCenter = "12345"
}
}
Core Network
The Core Network hosts segments, edges, and route policy versions.
# foundation/02-core-network.tf
resource "aws_networkmanager_core_network" "main" {
description = "Enterprise Core Network"
global_network_id = aws_networkmanager_global_network.main.id
}
Core Network Policy
Tip: Use the official
aws_networkmanager_core_network_policy_document
data source to generate valid JSON (hyphen‑case keys) and apply with the policy attachment resource. Avoid hand‑crafting JSON.
Figure 2: AWS Cloud WAN Policy Enforcement and Tagging - Shows how VPCs are attached to network segments based on tags and attachment policies
Iteration 1 — Multi‑Environment, Single Region
Goals:
- Isolate dev from prod/test.
- Allow prod and test to interoperate.
- Grant shared reachability to all.
# foundation/03-policy-v1.tf
data "aws_networkmanager_core_network_policy_document" "v1" {
version = "2021.12"
core_network_configuration {
asn_ranges = ["64512-65534"]
edge_locations { location = "us-east-1" }
}
# Segments
segments { name = "prod" description = "Production and Test environments" }
segments { name = "dev" description = "Development environment" }
segments { name = "shared" description = "Shared infrastructure services" }
# shared <-> prod/dev (bidirectional advertisements)
segment_actions {
action = "share"
mode = "attachment-route"
segment = "shared"
share_with = ["prod", "dev"]
}
# Attachment mapping by TAGS ON THE ATTACHMENT
attachment_policies {
rule_number = 100
condition_logic = "or"
conditions { type = "tag-value", key = "Environment", operator = "equals", value = "production" }
conditions { type = "tag-value", key = "Environment", operator = "equals", value = "test" }
action { association_method = "constant", segment = "prod" }
}
attachment_policies {
rule_number = 200
conditions { type = "tag-value", key = "Environment", operator = "equals", value = "development" }
action { association_method = "constant", segment = "dev" }
}
attachment_policies {
rule_number = 300
conditions { type = "tag-value", key = "Environment", operator = "equals", value = "shared" }
action { association_method = "constant", segment = "shared" }
}
}
resource "aws_networkmanager_core_network_policy_attachment" "v1" {
core_network_id = aws_networkmanager_core_network.main.id
policy_document = data.aws_networkmanager_core_network_policy_document.v1.json
description = "Cloud WAN policy – Iteration 1"
}
Iteration 2 — Add Region + Isolated Sandbox
Add us‑west‑2 and a sandbox that is isolated (no shares, requires acceptance).
# foundation/04-policy-v2.tf
data "aws_networkmanager_core_network_policy_document" "v2" {
version = "2021.12"
core_network_configuration {
asn_ranges = ["64512-65534"]
edge_locations { location = "us-east-1" }
edge_locations { location = "us-west-2" } # new region
}
segments { name = "prod" }
segments { name = "dev" }
segments { name = "shared" }
# Isolated sandbox
segments {
name = "sandbox"
description = "Isolated sandbox for security testing"
require_attachment_acceptance = true
isolate_attachments = true
}
# Preserve v1 shares
segment_actions {
action = "share"
mode = "attachment-route"
segment = "shared"
share_with = ["prod", "dev"]
}
# Map sandbox attachments
attachment_policies {
rule_number = 50
conditions { type = "tag-value", key = "Environment", operator = "equals", value = "sandbox" }
action { association_method = "constant", segment = "sandbox" }
}
# (Reuse v1 mapping rules for prod/dev/shared)
}
resource "aws_networkmanager_core_network_policy_attachment" "v2" {
core_network_id = aws_networkmanager_core_network.main.id
policy_document = data.aws_networkmanager_core_network_policy_document.v2.json
description = "Cloud WAN policy – Iteration 2 (add us-west-2 + sandbox)"
}
Logical VPC Module
Application teams consume a logical VPC module that builds the VPC + subnets, creates a VPC attachment, tags the attachment (critical), and programs VPC routes to the Core Network ARN.
# modules/logical-vpc/main.tf (essentials)
variable "core_network_id" { type = string }
variable "core_network_arn" { type = string }
variable "environment" { type = string } # production | test | development | shared | sandbox
variable "cost_center" { type = string }
# ... aws_vpc, subnets, route tables, etc. ...
resource "aws_networkmanager_vpc_attachment" "this" {
core_network_id = var.core_network_id
vpc_arn = aws_vpc.this.arn
subnet_arns = [aws_subnet.private_a.arn, aws_subnet.private_b.arn]
# Tags evaluated by the ATTACHMENT policy:
tags = {
Environment = var.environment
CostCenter = var.cost_center
}
}
# Example route: send traffic to Cloud WAN
resource "aws_route" "to_core_network" {
route_table_id = aws_route_table.private.id
destination_cidr_block = "0.0.0.0/0" # or a specific CIDR
core_network_arn = var.core_network_arn
}
Important: Cloud WAN does not modify your VPC route tables. Your module must add routes targeting the core network attachment ARN.
Terraform Cloud Workspace Strategy
- Workspace 1 — Foundation (
net-global-foundation
):
Manages Global/Core Network + policy attachments; outputscore_network_id
,core_network_arn
, segment names. - Workspace 2 — Shared Services (per Region) (
svc-shared-us-east-1
,svc-shared-us-west-2
):
Consumes foundation outputs; deploys the logical VPC module. - Workspace 3+ — App Workspaces (
app-payments-prod-us-east-1
,app-analytics-dev-us-west-2
,app-research-sandbox-us-west-2
):
Owned by app teams; blast radius is limited to their stack. - Run Triggers: propagate foundation changes to dependent workspaces.
Governance & Guardrails
Use Sentinel/OPA to enforce:
- Every
aws_networkmanager_vpc_attachment
must haveEnvironment
andCostCenter
tags. - Block attempts to disable sandbox isolation or add shares to
sandbox
. - Fail plans that create attachments without a valid
Environment
value.
Advanced Design Considerations
Attachment types — include Connect (SD‑WAN):
resource "aws_networkmanager_connect_attachment" "sdwan" {
core_network_id = var.core_network_id
transport_attachment_id = aws_networkmanager_vpc_attachment.transport.id
edge_location = "us-east-1"
tags = { Environment = "branch-edge" }
}
Cross‑Account model via AWS RAM: share the Core Network from us-east-1
; recipient accounts must accept before creating attachments.
Policy lifecycle: each edit creates a new version; generate a change set, review impact, and keep prior versions for rollback. Expect propagation per Core Network Edge.
Attachment acceptance control: set require_attachment_acceptance
at segment level for sensitive segments (e.g., prod
).
ASN planning: define asn_ranges
; optionally allocate non‑overlapping, narrow ranges per Region.
Observability & events: use Network Manager for a global view and emit signals to EventBridge (policy applied, attachment state changes).
Inter‑segment inspection: insert an inspection VPC (firewall/IPS/GWLB); advertise only inspection prefixes and steer via segment shares + route tables.
Direct Connect fit: use DX/SiteLink for deterministic underlay into AWS; then attach into Cloud WAN for global policy and distribution.
Rollout & Operations Checklist
- Foundation workspace applied; Core Network ID/ARN exported.
- Policy v1 applied; verify
shared <-> prod/dev
reachability. - Policy v2 applied;
us-west-2
edge online;sandbox
isolated. - VPC module applied; attachment tags set (
Environment
,CostCenter
). - VPC route tables contain routes to Core Network ARN where needed.
- Run Triggers wired; downstream workspaces re‑planned.
- Guardrails active (Sentinel/OPA).
- EventBridge alerts configured (policy version changes, attachment state).
Troubleshooting
- Attachment isn’t in the expected segment → Confirm tags on the attachment, not just the VPC.
- No cross‑env reachability → Check segment shares (e.g.,
shared <-> prod/dev
) are present in the active policy version. - Sandbox leaking → Ensure
sandbox
has no share actions, andisolate_attachments = true
. - Blackhole routes → Verify VPC routes target
core_network_arn
; Cloud WAN won’t change VPC route tables. - Cross‑account failures → Confirm RAM share initiated in
us-east-1
and recipients accepted. - Policy change didn’t apply everywhere → Check change set and allow for per‑edge propagation; consider rollback to the prior version if needed.
FAQ
Why map environments with attachment tags instead of per‑workspace variables?
Because the policy engine evaluates tags on the attachment, giving centralized, declarative control over segment placement and safety rails across accounts.
Can test live with prod?
Yes—place test in the prod
segment if you need pre‑production validation, while keeping dev in its own segment.
Credits
Primary source and examples by Vitale Mazo — “Beyond the Basics: My Playbook for Supercharging Terraform with AWS Cloud WAN Modules.”
Save this file as
README.md
in the root of your repo.