Last active
December 26, 2024 09:08
-
-
Save huynhbaoan/5db277e74ef8cfa664ff2defe177eb47 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Below is an illustrative example of how you can structure and write the Terraform code for CloudWAN resources using modules. This is a sample layout and code—adjust names, variables, and values to fit your actual environment and CIDR blocks. | |
Note: | |
• The code below uses placeholder values. You will need to replace these with your actual values (VPC IDs, segment names, etc.). | |
• The CloudWAN functionality and resources used are based on current AWS provider capabilities (as of AWS provider v4.x). | |
• Policies and segment relationships must be defined carefully in the JSON documents. The policy code example is a starting point; you will need to customize it to reflect your routing rules. | |
• This code assumes you have already created VPCs and their subnets. The VPC attachments here will reference existing VPC IDs and subnets. | |
• The firewall code snippet is a placeholder to create a firewall VPC attachment and related resources. Actual firewall logic (like configuring AWS Network Firewall or third-party firewall appliances) would be handled separately. | |
Directory Structure | |
CloudWAN/ | |
├── main.tf | |
├── variables.tf | |
├── outputs.tf | |
├── modules/ | |
│ ├── cloudwan_core/ | |
│ │ ├── main.tf | |
│ │ ├── variables.tf | |
│ │ └── outputs.tf | |
│ ├── cloudwan_segment/ | |
│ │ ├── main.tf | |
│ │ ├── variables.tf | |
│ │ └── outputs.tf | |
│ ├── cloudwan_vpc_attachment/ | |
│ │ ├── main.tf | |
│ │ ├── variables.tf | |
│ │ └── outputs.tf | |
│ ├── cloudwan_policy/ | |
│ │ ├── main.tf | |
│ │ ├── policy.json.tpl | |
│ │ ├── variables.tf | |
│ │ └── outputs.tf | |
│ └── firewall/ | |
│ ├── main.tf | |
│ ├── variables.tf | |
│ └── outputs.tf | |
├── nonprod/ | |
│ ├── mel-cloudwan-policy.tf | |
│ ├── mel-vpc-attachment.tf | |
│ ├── syd-cloudwan-policy.tf | |
│ ├── syd-vpc-attachment.tf | |
│ ├── global-sdwan-seg.tf | |
│ ├── variables.tf | |
│ └── outputs.tf | |
└── prod/ | |
├── mel-cloudwan-policy.tf | |
├── mel-vpc-attachment.tf | |
├── syd-cloudwan-policy.tf | |
├── syd-vpc-attachment.tf | |
├── direct-connect-seg.tf | |
├── variables.tf | |
└── outputs.tf | |
• main.tf at the top-level can define providers and global data sources if needed. | |
• nonprod/ and prod/ directories hold environment-specific .tf files that call modules to create attachments, policies, etc. | |
• Modules are in modules/ directory and contain reusable code. | |
Module: cloudwan_core | |
modules/cloudwan_core/variables.tf: | |
variable "core_network_name" { | |
type = string | |
description = "Name for the CloudWAN core network." | |
} | |
variable "tags" { | |
type = map(string) | |
default = {} | |
} | |
modules/cloudwan_core/main.tf: | |
resource "aws_networkmanager_core_network" "this" { | |
global_network_id = "<YOUR_GLOBAL_NETWORK_ID>" # Pre-existing global network ID | |
description = "Core network for CloudWAN" | |
tags = var.tags | |
} | |
modules/cloudwan_core/outputs.tf: | |
output "core_network_id" { | |
value = aws_networkmanager_core_network.this.id | |
} | |
You would call this module once at a global level (e.g., in main.tf at top level) if you haven’t created the core network yet. | |
Module: cloudwan_segment | |
Segments are typically defined in the core network policy. If you prefer to have a module that just outputs segment names (for consistency), you can do so, but note that segments themselves are not standalone resources; they are defined within the aws_networkmanager_core_network_policy resource’s JSON policy document. | |
modules/cloudwan_segment/variables.tf: | |
variable "segment_name" { | |
type = string | |
} | |
modules/cloudwan_segment/main.tf: | |
# This module might just return the segment name, as segments are defined in policy | |
output "segment_name" { | |
value = var.segment_name | |
} | |
modules/cloudwan_segment/outputs.tf: | |
# Already outputted in main.tf | |
You’ll integrate these segments into the policy module later by providing segment names as inputs. | |
Module: cloudwan_vpc_attachment | |
modules/cloudwan_vpc_attachment/variables.tf: | |
variable "core_network_id" { | |
type = string | |
} | |
variable "vpc_id" { | |
type = string | |
} | |
variable "subnet_arns" { | |
type = list(string) | |
} | |
variable "segment_name" { | |
type = string | |
} | |
variable "tags" { | |
type = map(string) | |
default = {} | |
} | |
modules/cloudwan_vpc_attachment/main.tf: | |
resource "aws_networkmanager_vpc_attachment" "this" { | |
core_network_id = var.core_network_id | |
vpc_arn = "arn:aws:ec2:${var.region}:${data.aws_caller_identity.current.account_id}:vpc/${var.vpc_id}" | |
subnet_arns = var.subnet_arns | |
segment_name = var.segment_name | |
tags = var.tags | |
} | |
data "aws_caller_identity" "current" {} | |
modules/cloudwan_vpc_attachment/outputs.tf: | |
output "attachment_id" { | |
value = aws_networkmanager_vpc_attachment.this.id | |
} | |
Module: cloudwan_policy | |
The policy is defined as a JSON document that you feed into aws_networkmanager_core_network_policy. You can use a template file (policy.json.tpl) to generate this JSON. This policy defines segments, routing rules, and attachments between them. | |
modules/cloudwan_policy/variables.tf: | |
variable "core_network_id" { | |
type = string | |
} | |
variable "policy_json" { | |
type = string | |
description = "Rendered policy JSON" | |
} | |
modules/cloudwan_policy/policy.json.tpl (Example skeleton, must be customized): | |
{ | |
"Version": "2021-03-11", | |
"SegmentActions": { | |
"CreateSegment": [ | |
{"Name": "NP_MEL_int_seg"}, | |
{"Name": "NP_MEL_ext_seg"}, | |
{"Name": "NP_MEL_ext_fw_seg"}, | |
{"Name": "NP_MEL_prot_seg"}, | |
{"Name": "NP_MEL_prot_fw_seg"}, | |
{"Name": "NP_SYD_int_seg"}, | |
{"Name": "NP_SYD_ext_seg"}, | |
{"Name": "NP_SYD_ext_fw_seg"}, | |
{"Name": "NP_SYD_prot_seg"}, | |
{"Name": "NP_SYD_prot_fw_seg"}, | |
{"Name": "segr_fw_seg"}, | |
{"Name": "SDWAN_seg"}, | |
{"Name": "PROD_MEL_int_seg"}, | |
{"Name": "PROD_MEL_ext_seg"}, | |
{"Name": "PROD_MEL_ext_fw_seg"}, | |
{"Name": "PROD_MEL_prot_seg"}, | |
{"Name": "PROD_MEL_prot_fw_seg"}, | |
{"Name": "PROD_SYD_int_seg"}, | |
{"Name": "PROD_SYD_ext_seg"}, | |
{"Name": "PROD_SYD_ext_fw_seg"}, | |
{"Name": "PROD_SYD_prot_seg"}, | |
{"Name": "PROD_SYD_prot_fw_seg"}, | |
{"Name": "Direct_Connect_seg"} | |
] | |
}, | |
"SegmentRouting": { | |
"AllowRoutePropagation": [ | |
{ | |
"SegmentName": "NP_MEL_int_seg", | |
"AllowedRoutes": [ | |
{"SegmentName": "NP_MEL_int_seg"}, | |
{"SegmentName": "NP_MEL_prot_seg", "ThroughSegments": ["NP_MEL_prot_fw_seg"]}, | |
{"SegmentName": "NP_MEL_ext_seg", "ThroughSegments": ["NP_MEL_ext_fw_seg"]}, | |
... | |
/* You must fully define all route rules based on your requirements */ | |
] | |
} | |
/* Additional segment-to-segment routing definitions go here */ | |
] | |
} | |
} | |
modules/cloudwan_policy/main.tf: | |
resource "aws_networkmanager_core_network_policy" "this" { | |
core_network_id = var.core_network_id | |
policy_document = var.policy_json | |
} | |
output "policy_version_id" { | |
value = aws_networkmanager_core_network_policy.this.core_network_policy_version | |
} | |
You’d use a templatefile function in the calling code to render policy.json.tpl into var.policy_json. | |
Module: firewall | |
For firewall configuration, this could mean creating AWS Network Firewall or referencing a firewall appliance in a firewall VPC. For simplicity, assume you have a firewall appliance in a firewall VPC that’s already deployed. Here we just show how you might attach that firewall VPC to CloudWAN segments if needed. | |
modules/firewall/variables.tf: | |
variable "core_network_id" { | |
type = string | |
} | |
variable "vpc_id" { | |
type = string | |
} | |
variable "subnet_arns" { | |
type = list(string) | |
} | |
variable "segment_name" { | |
type = string | |
} | |
variable "tags" { | |
type = map(string) | |
default = {} | |
} | |
modules/firewall/main.tf: | |
module "firewall_attachment" { | |
source = "../cloudwan_vpc_attachment" | |
core_network_id = var.core_network_id | |
vpc_id = var.vpc_id | |
subnet_arns = var.subnet_arns | |
segment_name = var.segment_name | |
tags = var.tags | |
} | |
modules/firewall/outputs.tf: | |
output "firewall_attachment_id" { | |
value = module.firewall_attachment.attachment_id | |
} | |
Example Usage in nonprod/mel-vpc-attachment.tf | |
In your environment-specific files, you’ll call these modules and provide the appropriate variables: | |
variable "np_mel_int_vpc_id" {} | |
variable "np_mel_int_subnet_arns" { | |
type = list(string) | |
} | |
variable "core_network_id" {} | |
module "np_mel_int_vpc_attachment" { | |
source = "../modules/cloudwan_vpc_attachment" | |
core_network_id = var.core_network_id | |
vpc_id = var.np_mel_int_vpc_id | |
subnet_arns = var.np_mel_int_subnet_arns | |
segment_name = "NP_MEL_int_seg" | |
tags = { | |
Environment = "nonprod" | |
Region = "MEL" | |
Segment = "int" | |
} | |
} | |
You’d repeat similar code for each VPC attachment in MEL, SYD, etc., just changing variables and segment names accordingly. | |
Example Usage in nonprod/mel-cloudwan-policy.tf | |
You’ll need to provide the rendered policy JSON. One way is to use templatefile() in a calling file: | |
variable "core_network_id" {} | |
data "template_file" "policy_doc" { | |
template = file("../modules/cloudwan_policy/policy.json.tpl") | |
# If you have any variables in policy.json.tpl, pass them in vars = {} | |
} | |
module "np_mel_policy" { | |
source = "../modules/cloudwan_policy" | |
core_network_id = var.core_network_id | |
policy_json = data.template_file.policy_doc.rendered | |
} | |
Adjust segment names and route rules inside the policy.json.tpl file to fully reflect your routing requirements. | |
In Summary: | |
• Core Network Module: Creates the CloudWAN core network (if not existing yet). | |
• Segment Module: Mostly a placeholder because segments are defined in the policy. | |
• VPC Attachment Module: Attaches VPCs to segments. | |
• Policy Module: Manages the core network policy and defines the segments and routing rules. | |
• Firewall Module: Attaches firewall VPCs to the appropriate firewall segments. | |
You can now replicate this pattern for prod/ environment files, just changing variables and calling the same modules, ensuring proper isolation and routing as per your requirements. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Below is an example of a single Terraform configuration that directly creates the CloudWAN core network, defines segments (within the policy), creates VPC attachments, and applies a policy. This configuration does not use separate modules. Instead, all resources are defined at the top level. You will need to tailor this code to your environment (e.g., replace placeholder IDs, regions, CIDRs, VPCs, and segment names). | |
This is a minimal example to illustrate the approach: | |
File: main.tf | |
terraform { | |
required_version = ">= 1.3.0" | |
required_providers { | |
aws = { | |
source = "hashicorp/aws" | |
version = ">= 4.0.0" | |
} | |
} | |
} | |
provider "aws" { | |
region = "ap-southeast-2" | |
} | |
############################# | |
# Variables (Adjust Values) # | |
############################# | |
# The global network ID is a prerequisite; this must already exist in your AWS environment. | |
variable "global_network_id" { | |
type = string | |
default = "GLOBAL-NETWORK-ID-HERE" | |
} | |
# Example VPC IDs (Replace with your actual VPC IDs) | |
variable "np_mel_int_vpc_id" { | |
type = string | |
default = "vpc-0examplemelint" | |
} | |
variable "np_mel_ext_vpc_id" { | |
type = string | |
default = "vpc-0examplemelext" | |
} | |
variable "np_mel_ext_fw_vpc_id" { | |
type = string | |
default = "vpc-0examplemelextfw" | |
} | |
variable "np_mel_prot_vpc_id" { | |
type = string | |
default = "vpc-0examplemelprot" | |
} | |
variable "np_mel_prot_fw_vpc_id" { | |
type = string | |
default = "vpc-0examplemelprotfw" | |
} | |
# Example Subnet ARNs for attachments (Replace with actual subnet ARNs) | |
# Typically, you attach 2-4 subnets for redundancy (one per AZ). | |
variable "np_mel_int_subnet_arns" { | |
type = list(string) | |
default = [ | |
"arn:aws:ec2:ap-southeast-2:111111111111:subnet/subnet-0intA", | |
"arn:aws:ec2:ap-southeast-2:111111111111:subnet/subnet-0intB" | |
] | |
} | |
variable "np_mel_ext_subnet_arns" { | |
type = list(string) | |
default = [ | |
"arn:aws:ec2:ap-southeast-2:111111111111:subnet/subnet-0extA", | |
"arn:aws:ec2:ap-southeast-2:111111111111:subnet/subnet-0extB" | |
] | |
} | |
# Similarly define variables for ext_fw, prot, and prot_fw VPC subnets: | |
variable "np_mel_ext_fw_subnet_arns" { | |
type = list(string) | |
default = [ | |
"arn:aws:ec2:ap-southeast-2:111111111111:subnet/subnet-0extfwA", | |
"arn:aws:ec2:ap-southeast-2:111111111111:subnet/subnet-0extfwB" | |
] | |
} | |
variable "np_mel_prot_subnet_arns" { | |
type = list(string) | |
default = [ | |
"arn:aws:ec2:ap-southeast-2:111111111111:subnet/subnet-0protA", | |
"arn:aws:ec2:ap-southeast-2:111111111111:subnet/subnet-0protB" | |
] | |
} | |
variable "np_mel_prot_fw_subnet_arns" { | |
type = list(string) | |
default = [ | |
"arn:aws:ec2:ap-southeast-2:111111111111:subnet/subnet-0protfwA", | |
"arn:aws:ec2:ap-southeast-2:111111111111:subnet/subnet-0protfwB" | |
] | |
} | |
############################# | |
# Core Network Creation # | |
############################# | |
resource "aws_networkmanager_core_network" "core" { | |
global_network_id = var.global_network_id | |
description = "CloudWAN core network for multi-env routing" | |
tags = { | |
Name = "my-core-network" | |
} | |
} | |
output "core_network_id" { | |
value = aws_networkmanager_core_network.core.id | |
} | |
############################# | |
# Policy Definition # | |
############################# | |
# Create a local file for the policy JSON or inline heredoc. | |
# Here, we define segments and routing rules according to your design. | |
# Adjust segments and routing according to your requirements. | |
locals { | |
policy_document = <<-EOT | |
{ | |
"Version": "2021-03-11", | |
"SegmentActions": { | |
"CreateSegment": [ | |
{"Name": "NP_MEL_int_seg"}, | |
{"Name": "NP_MEL_ext_seg"}, | |
{"Name": "NP_MEL_ext_fw_seg"}, | |
{"Name": "NP_MEL_prot_seg"}, | |
{"Name": "NP_MEL_prot_fw_seg"} | |
/* Add other segments for SYD, PROD, etc. as needed */ | |
] | |
}, | |
"SegmentRouting": { | |
"AllowRoutePropagation": [ | |
{ | |
"SegmentName": "NP_MEL_int_seg", | |
"AllowedRoutes": [ | |
{"SegmentName": "NP_MEL_int_seg"}, | |
{ | |
"SegmentName": "NP_MEL_ext_seg", | |
"ThroughSegments": ["NP_MEL_ext_fw_seg"] | |
}, | |
{ | |
"SegmentName": "NP_MEL_prot_seg", | |
"ThroughSegments": ["NP_MEL_prot_fw_seg"] | |
} | |
] | |
}, | |
{ | |
"SegmentName": "NP_MEL_ext_seg", | |
"AllowedRoutes": [ | |
{"SegmentName": "NP_MEL_int_seg"}, | |
{ | |
"SegmentName": "NP_MEL_prot_seg", | |
"ThroughSegments": ["NP_MEL_prot_fw_seg"] | |
} | |
] | |
} | |
/* Add similar routing policies for other segments/environments/regional segments | |
and cross-environment rules (e.g., NP to PROD via ext and segr_fw) as needed */ | |
] | |
} | |
} | |
EOT | |
} | |
resource "aws_networkmanager_core_network_policy" "policy" { | |
core_network_id = aws_networkmanager_core_network.core.id | |
policy_document = local.policy_document | |
} | |
output "policy_version" { | |
value = aws_networkmanager_core_network_policy.policy.core_network_policy_version | |
} | |
############################# | |
# VPC Attachments # | |
############################# | |
# Attach the NP MEL int VPC to NP_MEL_int_seg | |
resource "aws_networkmanager_vpc_attachment" "np_mel_int_attachment" { | |
core_network_id = aws_networkmanager_core_network.core.id | |
vpc_arn = "arn:aws:ec2:ap-southeast-2:${data.aws_caller_identity.current.account_id}:vpc/${var.np_mel_int_vpc_id}" | |
subnet_arns = var.np_mel_int_subnet_arns | |
segment_name = "NP_MEL_int_seg" | |
tags = { | |
Name = "np-mel-int-attachment" | |
} | |
} | |
# Attach the NP MEL ext VPC to NP_MEL_ext_seg | |
resource "aws_networkmanager_vpc_attachment" "np_mel_ext_attachment" { | |
core_network_id = aws_networkmanager_core_network.core.id | |
vpc_arn = "arn:aws:ec2:ap-southeast-2:${data.aws_caller_identity.current.account_id}:vpc/${var.np_mel_ext_vpc_id}" | |
subnet_arns = var.np_mel_ext_subnet_arns | |
segment_name = "NP_MEL_ext_seg" | |
tags = { | |
Name = "np-mel-ext-attachment" | |
} | |
} | |
# Attach the NP MEL ext fw VPC to NP_MEL_ext_fw_seg | |
resource "aws_networkmanager_vpc_attachment" "np_mel_ext_fw_attachment" { | |
core_network_id = aws_networkmanager_core_network.core.id | |
vpc_arn = "arn:aws:ec2:ap-southeast-2:${data.aws_caller_identity.current.account_id}:vpc/${var.np_mel_ext_fw_vpc_id}" | |
subnet_arns = var.np_mel_ext_fw_subnet_arns | |
segment_name = "NP_MEL_ext_fw_seg" | |
tags = { | |
Name = "np-mel-ext-fw-attachment" | |
} | |
} | |
# Attach the NP MEL prot VPC to NP_MEL_prot_seg | |
resource "aws_networkmanager_vpc_attachment" "np_mel_prot_attachment" { | |
core_network_id = aws_networkmanager_core_network.core.id | |
vpc_arn = "arn:aws:ec2:ap-southeast-2:${data.aws_caller_identity.current.account_id}:vpc/${var.np_mel_prot_vpc_id}" | |
subnet_arns = var.np_mel_prot_subnet_arns | |
segment_name = "NP_MEL_prot_seg" | |
tags = { | |
Name = "np-mel-prot-attachment" | |
} | |
} | |
# Attach the NP MEL prot fw VPC to NP_MEL_prot_fw_seg | |
resource "aws_networkmanager_vpc_attachment" "np_mel_prot_fw_attachment" { | |
core_network_id = aws_networkmanager_core_network.core.id | |
vpc_arn = "arn:aws:ec2:ap-southeast-2:${data.aws_caller_identity.current.account_id}:vpc/${var.np_mel_prot_fw_vpc_id}" | |
subnet_arns = var.np_mel_prot_fw_subnet_arns | |
segment_name = "NP_MEL_prot_fw_seg" | |
tags = { | |
Name = "np-mel-prot-fw-attachment" | |
} | |
} | |
data "aws_caller_identity" "current" {} | |
What This Code Does: | |
1. Creates a CloudWAN Core Network using aws_networkmanager_core_network. | |
2. Defines Segments and Routing Policies using aws_networkmanager_core_network_policy. | |
• The segments (NP_MEL_int_seg, NP_MEL_ext_seg, etc.) are created by the policy’s CreateSegment actions. | |
• The policy’s SegmentRouting section defines how routes propagate and what firewall segments to go through. | |
3. Attaches Existing VPCs to Specific Segments using aws_networkmanager_vpc_attachment. Each VPC attachment links the VPC to a specific segment. | |
4. Outputs the core network ID and policy version for reference. | |
Important: | |
• Update global_network_id with your actual global network ID. | |
• Update vpc_arn and subnet_arns variables with the correct values from your environment. | |
• Add more segments and VPC attachments as required for NP SYD, PROD MEL, PROD SYD, SDWAN segments, and Direct Connect. | |
• Expand the policy_document local variable’s JSON to cover all of your routing rules, including cross-environment routing via segr_fw_seg, ext_fw, prot_fw, etc. | |
• The rules given are simplified. In a real scenario, you must elaborate the policy JSON extensively to represent all your required inter-segment rules. | |
This single configuration file (with any necessary variable adjustments) will create and configure the CloudWAN resources without using modules. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Below is an example of a single Terraform configuration that directly creates the CloudWAN core network, defines segments (within the policy), creates VPC attachments, and applies a policy. This configuration does not use separate modules. Instead, all resources are defined at the top level. You will need to tailor this code to your environment (e.g., replace placeholder IDs, regions, CIDRs, VPCs, and segment names). | |
This is a minimal example to illustrate the approach: | |
File: main.tf | |
terraform { | |
required_version = ">= 1.3.0" | |
required_providers { | |
aws = { | |
source = "hashicorp/aws" | |
version = ">= 4.0.0" | |
} | |
} | |
} | |
provider "aws" { | |
region = "ap-southeast-2" | |
} | |
############################# | |
# Variables (Adjust Values) # | |
############################# | |
# The global network ID is a prerequisite; this must already exist in your AWS environment. | |
variable "global_network_id" { | |
type = string | |
default = "GLOBAL-NETWORK-ID-HERE" | |
} | |
# Example VPC IDs (Replace with your actual VPC IDs) | |
variable "np_mel_int_vpc_id" { | |
type = string | |
default = "vpc-0examplemelint" | |
} | |
variable "np_mel_ext_vpc_id" { | |
type = string | |
default = "vpc-0examplemelext" | |
} | |
variable "np_mel_ext_fw_vpc_id" { | |
type = string | |
default = "vpc-0examplemelextfw" | |
} | |
variable "np_mel_prot_vpc_id" { | |
type = string | |
default = "vpc-0examplemelprot" | |
} | |
variable "np_mel_prot_fw_vpc_id" { | |
type = string | |
default = "vpc-0examplemelprotfw" | |
} | |
# Example Subnet ARNs for attachments (Replace with actual subnet ARNs) | |
# Typically, you attach 2-4 subnets for redundancy (one per AZ). | |
variable "np_mel_int_subnet_arns" { | |
type = list(string) | |
default = [ | |
"arn:aws:ec2:ap-southeast-2:111111111111:subnet/subnet-0intA", | |
"arn:aws:ec2:ap-southeast-2:111111111111:subnet/subnet-0intB" | |
] | |
} | |
variable "np_mel_ext_subnet_arns" { | |
type = list(string) | |
default = [ | |
"arn:aws:ec2:ap-southeast-2:111111111111:subnet/subnet-0extA", | |
"arn:aws:ec2:ap-southeast-2:111111111111:subnet/subnet-0extB" | |
] | |
} | |
# Similarly define variables for ext_fw, prot, and prot_fw VPC subnets: | |
variable "np_mel_ext_fw_subnet_arns" { | |
type = list(string) | |
default = [ | |
"arn:aws:ec2:ap-southeast-2:111111111111:subnet/subnet-0extfwA", | |
"arn:aws:ec2:ap-southeast-2:111111111111:subnet/subnet-0extfwB" | |
] | |
} | |
variable "np_mel_prot_subnet_arns" { | |
type = list(string) | |
default = [ | |
"arn:aws:ec2:ap-southeast-2:111111111111:subnet/subnet-0protA", | |
"arn:aws:ec2:ap-southeast-2:111111111111:subnet/subnet-0protB" | |
] | |
} | |
variable "np_mel_prot_fw_subnet_arns" { | |
type = list(string) | |
default = [ | |
"arn:aws:ec2:ap-southeast-2:111111111111:subnet/subnet-0protfwA", | |
"arn:aws:ec2:ap-southeast-2:111111111111:subnet/subnet-0protfwB" | |
] | |
} | |
############################# | |
# Core Network Creation # | |
############################# | |
resource "aws_networkmanager_core_network" "core" { | |
global_network_id = var.global_network_id | |
description = "CloudWAN core network for multi-env routing" | |
tags = { | |
Name = "my-core-network" | |
} | |
} | |
output "core_network_id" { | |
value = aws_networkmanager_core_network.core.id | |
} | |
############################# | |
# Policy Definition # | |
############################# | |
# Create a local file for the policy JSON or inline heredoc. | |
# Here, we define segments and routing rules according to your design. | |
# Adjust segments and routing according to your requirements. | |
locals { | |
policy_document = <<-EOT | |
{ | |
"Version": "2021-03-11", | |
"SegmentActions": { | |
"CreateSegment": [ | |
{"Name": "NP_MEL_int_seg"}, | |
{"Name": "NP_MEL_ext_seg"}, | |
{"Name": "NP_MEL_ext_fw_seg"}, | |
{"Name": "NP_MEL_prot_seg"}, | |
{"Name": "NP_MEL_prot_fw_seg"} | |
/* Add other segments for SYD, PROD, etc. as needed */ | |
] | |
}, | |
"SegmentRouting": { | |
"AllowRoutePropagation": [ | |
{ | |
"SegmentName": "NP_MEL_int_seg", | |
"AllowedRoutes": [ | |
{"SegmentName": "NP_MEL_int_seg"}, | |
{ | |
"SegmentName": "NP_MEL_ext_seg", | |
"ThroughSegments": ["NP_MEL_ext_fw_seg"] | |
}, | |
{ | |
"SegmentName": "NP_MEL_prot_seg", | |
"ThroughSegments": ["NP_MEL_prot_fw_seg"] | |
} | |
] | |
}, | |
{ | |
"SegmentName": "NP_MEL_ext_seg", | |
"AllowedRoutes": [ | |
{"SegmentName": "NP_MEL_int_seg"}, | |
{ | |
"SegmentName": "NP_MEL_prot_seg", | |
"ThroughSegments": ["NP_MEL_prot_fw_seg"] | |
} | |
] | |
} | |
/* Add similar routing policies for other segments/environments/regional segments | |
and cross-environment rules (e.g., NP to PROD via ext and segr_fw) as needed */ | |
] | |
} | |
} | |
EOT | |
} | |
resource "aws_networkmanager_core_network_policy" "policy" { | |
core_network_id = aws_networkmanager_core_network.core.id | |
policy_document = local.policy_document | |
} | |
output "policy_version" { | |
value = aws_networkmanager_core_network_policy.policy.core_network_policy_version | |
} | |
############################# | |
# VPC Attachments # | |
############################# | |
# Attach the NP MEL int VPC to NP_MEL_int_seg | |
resource "aws_networkmanager_vpc_attachment" "np_mel_int_attachment" { | |
core_network_id = aws_networkmanager_core_network.core.id | |
vpc_arn = "arn:aws:ec2:ap-southeast-2:${data.aws_caller_identity.current.account_id}:vpc/${var.np_mel_int_vpc_id}" | |
subnet_arns = var.np_mel_int_subnet_arns | |
segment_name = "NP_MEL_int_seg" | |
tags = { | |
Name = "np-mel-int-attachment" | |
} | |
} | |
# Attach the NP MEL ext VPC to NP_MEL_ext_seg | |
resource "aws_networkmanager_vpc_attachment" "np_mel_ext_attachment" { | |
core_network_id = aws_networkmanager_core_network.core.id | |
vpc_arn = "arn:aws:ec2:ap-southeast-2:${data.aws_caller_identity.current.account_id}:vpc/${var.np_mel_ext_vpc_id}" | |
subnet_arns = var.np_mel_ext_subnet_arns | |
segment_name = "NP_MEL_ext_seg" | |
tags = { | |
Name = "np-mel-ext-attachment" | |
} | |
} | |
# Attach the NP MEL ext fw VPC to NP_MEL_ext_fw_seg | |
resource "aws_networkmanager_vpc_attachment" "np_mel_ext_fw_attachment" { | |
core_network_id = aws_networkmanager_core_network.core.id | |
vpc_arn = "arn:aws:ec2:ap-southeast-2:${data.aws_caller_identity.current.account_id}:vpc/${var.np_mel_ext_fw_vpc_id}" | |
subnet_arns = var.np_mel_ext_fw_subnet_arns | |
segment_name = "NP_MEL_ext_fw_seg" | |
tags = { | |
Name = "np-mel-ext-fw-attachment" | |
} | |
} | |
# Attach the NP MEL prot VPC to NP_MEL_prot_seg | |
resource "aws_networkmanager_vpc_attachment" "np_mel_prot_attachment" { | |
core_network_id = aws_networkmanager_core_network.core.id | |
vpc_arn = "arn:aws:ec2:ap-southeast-2:${data.aws_caller_identity.current.account_id}:vpc/${var.np_mel_prot_vpc_id}" | |
subnet_arns = var.np_mel_prot_subnet_arns | |
segment_name = "NP_MEL_prot_seg" | |
tags = { | |
Name = "np-mel-prot-attachment" | |
} | |
} | |
# Attach the NP MEL prot fw VPC to NP_MEL_prot_fw_seg | |
resource "aws_networkmanager_vpc_attachment" "np_mel_prot_fw_attachment" { | |
core_network_id = aws_networkmanager_core_network.core.id | |
vpc_arn = "arn:aws:ec2:ap-southeast-2:${data.aws_caller_identity.current.account_id}:vpc/${var.np_mel_prot_fw_vpc_id}" | |
subnet_arns = var.np_mel_prot_fw_subnet_arns | |
segment_name = "NP_MEL_prot_fw_seg" | |
tags = { | |
Name = "np-mel-prot-fw-attachment" | |
} | |
} | |
data "aws_caller_identity" "current" {} | |
What This Code Does: | |
1. Creates a CloudWAN Core Network using aws_networkmanager_core_network. | |
2. Defines Segments and Routing Policies using aws_networkmanager_core_network_policy. | |
• The segments (NP_MEL_int_seg, NP_MEL_ext_seg, etc.) are created by the policy’s CreateSegment actions. | |
• The policy’s SegmentRouting section defines how routes propagate and what firewall segments to go through. | |
3. Attaches Existing VPCs to Specific Segments using aws_networkmanager_vpc_attachment. Each VPC attachment links the VPC to a specific segment. | |
4. Outputs the core network ID and policy version for reference. | |
Important: | |
• Update global_network_id with your actual global network ID. | |
• Update vpc_arn and subnet_arns variables with the correct values from your environment. | |
• Add more segments and VPC attachments as required for NP SYD, PROD MEL, PROD SYD, SDWAN segments, and Direct Connect. | |
• Expand the policy_document local variable’s JSON to cover all of your routing rules, including cross-environment routing via segr_fw_seg, ext_fw, prot_fw, etc. | |
• The rules given are simplified. In a real scenario, you must elaborate the policy JSON extensively to represent all your required inter-segment rules. | |
This single configuration file (with any necessary variable adjustments) will create and configure the CloudWAN resources without using modules. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Below is an example Terraform configuration that demonstrates how to set up AWS Cloud WAN with multiple segments and insert a firewall VPC between traffic flows. This code includes: | |
• A global network and a core network. | |
• Three segments: segment-a, segment-fw, and segment-c. | |
• Three VPC attachments (for VPC A, VPC FW, and VPC C) associating each with its respective segment. | |
• A core network policy that ensures traffic from segment A to segment C passes through the firewall segment. | |
Important Notes: | |
1. Prerequisites: | |
• You must have already created three VPCs: | |
• VPC A (for example, vpc_a_id), | |
• VPC FW (the firewall VPC, vpc_fw_id), | |
• VPC C (vpc_c_id). | |
Each VPC should have at least one subnet. You will need the ARNs of these subnets (e.g., var.vpc_a_subnet_arns, etc.) for the attachment. Ensure your firewall VPC is set up with AWS Network Firewall or a suitable firewall appliance as required. | |
2. AWS Provider and Terraform Version: | |
Make sure you are using a recent AWS provider version (>= 5.x) and Terraform >= 1.x. | |
Some of the Cloud WAN features are relatively new, so ensure that your provider version supports aws_networkmanager_core_network_policy_version or the equivalent. If the resource doesn’t exist in your current provider, consider updating or using the AWS Cloud Control Provider (awscc_* resources). | |
3. Policy Document Schema: | |
The JSON policy used in aws_networkmanager_core_network_policy_version must follow the Cloud WAN policy schema. The example below is representative; you should review the latest AWS documentation to confirm the exact fields and structure: | |
AWS Cloud WAN Policy Reference | |
4. Placeholders: | |
Replace variable values (like var.vpc_a_id, var.vpc_fw_id, var.vpc_c_id, and subnet ARNs) with your actual values. | |
Example Terraform Code | |
terraform { | |
required_version = ">= 1.0.0" | |
required_providers { | |
aws = { | |
source = "hashicorp/aws" | |
version = "~> 5.0" | |
} | |
} | |
} | |
provider "aws" { | |
region = "us-east-1" | |
} | |
variable "vpc_a_id" { | |
type = string | |
} | |
variable "vpc_fw_id" { | |
type = string | |
} | |
variable "vpc_c_id" { | |
type = string | |
} | |
variable "vpc_a_subnet_arns" { | |
type = list(string) | |
} | |
variable "vpc_fw_subnet_arns" { | |
type = list(string) | |
} | |
variable "vpc_c_subnet_arns" { | |
type = list(string) | |
} | |
# 1. Create a Global Network | |
resource "aws_networkmanager_global_network" "this" { | |
description = "My Global Network" | |
} | |
# 2. Create a Core Network | |
resource "aws_networkmanager_core_network" "this" { | |
global_network_id = aws_networkmanager_global_network.this.id | |
description = "My Core Network" | |
# The initial core network is created without a custom policy. | |
# We'll create and attach a new policy version later. | |
} | |
# 3. Create VPC Attachments | |
resource "aws_networkmanager_vpc_attachment" "vpc_a_attach" { | |
core_network_id = aws_networkmanager_core_network.this.core_network_id | |
vpc_id = var.vpc_a_id | |
subnet_arns = var.vpc_a_subnet_arns | |
segment_name = "segment-a" | |
tags = { | |
Name = "vpc-a-attachment" | |
} | |
} | |
resource "aws_networkmanager_vpc_attachment" "vpc_fw_attach" { | |
core_network_id = aws_networkmanager_core_network.this.core_network_id | |
vpc_id = var.vpc_fw_id | |
subnet_arns = var.vpc_fw_subnet_arns | |
segment_name = "segment-fw" | |
tags = { | |
Name = "vpc-fw-attachment" | |
} | |
} | |
resource "aws_networkmanager_vpc_attachment" "vpc_c_attach" { | |
core_network_id = aws_networkmanager_core_network.this.core_network_id | |
vpc_id = var.vpc_c_id | |
subnet_arns = var.vpc_c_subnet_arns | |
segment_name = "segment-c" | |
tags = { | |
Name = "vpc-c-attachment" | |
} | |
} | |
# 4. Define the Core Network Policy | |
# | |
# This policy: | |
# - Defines three segments: segment-a, segment-fw, segment-c | |
# - Associates VPC attachments with their respective segments | |
# - Inserts a firewall between segment-a and segment-c traffic | |
# | |
# Make sure to verify that "INSERT_FIREWALL" action and policy structure | |
# align with the latest AWS documentation. | |
resource "aws_networkmanager_core_network_policy_version" "example" { | |
core_network_id = aws_networkmanager_core_network.this.core_network_id | |
policy_document = <<-EOT | |
{ | |
"CoreNetworkConfiguration": { | |
"Segments": [ | |
{ "Name": "segment-a" }, | |
{ "Name": "segment-fw" }, | |
{ "Name": "segment-c" } | |
], | |
"Edges": [], | |
"Policies": [ | |
{ | |
"PolicyType": "SEGMENT", | |
"SegmentActions": [ | |
{ | |
"Action": "INSERT_FIREWALL", | |
"FirewallSegment": "segment-fw", | |
"SourceSegments": ["segment-a"], | |
"DestinationSegments": ["segment-c"] | |
} | |
] | |
}, | |
{ | |
"PolicyType": "ATTACHMENT", | |
"Rules": [ | |
{ | |
"Action": "ASSOCIATE", | |
"SegmentName": "segment-a", | |
"ResourceTypes": ["VPC"] | |
}, | |
{ | |
"Action": "ASSOCIATE", | |
"SegmentName": "segment-fw", | |
"ResourceTypes": ["VPC"] | |
}, | |
{ | |
"Action": "ASSOCIATE", | |
"SegmentName": "segment-c", | |
"ResourceTypes": ["VPC"] | |
} | |
] | |
} | |
] | |
} | |
} | |
EOT | |
set_as_default = true | |
depends_on = [ | |
aws_networkmanager_vpc_attachment.vpc_a_attach, | |
aws_networkmanager_vpc_attachment.vpc_fw_attach, | |
aws_networkmanager_vpc_attachment.vpc_c_attach | |
] | |
} | |
What This Configuration Does | |
• Global & Core Network: Sets up a global and core network to manage your WAN. | |
• Segments: The policy defines three segments: | |
• segment-a: Contains VPC A. | |
• segment-fw: Contains your firewall VPC. | |
• segment-c: Contains VPC C. | |
• Routing/Policy: The core network policy: | |
• Routes traffic from segment A to segment C via the firewall segment. | |
• Ensures each VPC attachment is associated with the correct segment. | |
• Firewall Insertion: The "INSERT_FIREWALL" action ensures that traffic going from A to C first passes through the firewall in segment-fw, allowing you to apply security inspections. | |
Additional Steps: | |
You must ensure that the firewall VPC is set up correctly with AWS Network Firewall or other suitable firewall solutions, and that the necessary endpoints or Transit Gateway Connect attachments are created as required. Those resources are not shown here (the user requested we exclude VPC definitions and firewall specifics). | |
This example provides a starting point. Always refer to the latest AWS and Terraform documentation to confirm resource attributes, policy schema, and any required dependencies. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment