Created
December 30, 2024 03:29
-
-
Save huynhbaoan/cf71c66e94086a49f138e861b1f1b059 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 one cohesive example showing how to set up two Network Firewalls (one in NP MEL, one in NP SYD) and a CloudWAN policy that enforces traffic from the NP MEL prot segment to the NP SYD prot segment (and vice versa) to pass through both the NP MEL prot firewall and the NP SYD prot firewall. | |
| Important Notes | |
| 1. We are not including VPC creations or VPC attachments—only the firewall resources and the CloudWAN policy references. | |
| 2. The code demonstrates a sample approach to modules and file structures. You can adapt naming and values to match your real environment. | |
| 3. The CloudWAN policy JSON is simplified but illustrates the essential concept of multiple firewalls in a strict path. | |
| 1. Directory Structure | |
| Below is a proposed layout. You can adjust file names as needed, but this structure keeps things organized: | |
| cloudwan-project/ | |
| np/ | |
| np_mel_syd_prot_firewalls.tf # top-level TF for creating both NP MEL and NP SYD "prot" firewalls | |
| np_cloudwan_policy.tf # top-level TF to apply the CloudWAN policy | |
| cloudwan_policy.json # the policy JSON describing segments & traffic rules | |
| modules/ | |
| firewall/ | |
| main.tf | |
| variables.tf | |
| outputs.tf | |
| cloudwan_policy/ | |
| main.tf | |
| variables.tf | |
| outputs.tf | |
| 2. Firewall Module (modules/firewall/) | |
| This module will deploy an AWS Network Firewall (with a minimal rule group and policy) into an existing firewall VPC. You’ll call it twice—once for NP MEL prot firewall and once for NP SYD prot firewall. | |
| modules/firewall/variables.tf | |
| variable "name" { | |
| type = string | |
| description = "A name prefix or identifier for firewall resources." | |
| } | |
| variable "vpc_id" { | |
| type = string | |
| description = "ID of the VPC where the firewall is deployed." | |
| } | |
| variable "subnet_ids" { | |
| type = list(string) | |
| description = "Subnet IDs in which the firewall endpoints will be created." | |
| } | |
| variable "tags" { | |
| type = map(string) | |
| default = {} | |
| description = "Tags for all firewall resources." | |
| } | |
| modules/firewall/main.tf | |
| resource "aws_networkfirewall_rule_group" "stateful_group" { | |
| capacity = 100 | |
| name = "${var.name}-stateful-rules" | |
| type = "STATEFUL" | |
| rule_group { | |
| rules_source { | |
| # Very simple ALLOWLIST example | |
| rules_source_list { | |
| generated_rules_type = "ALLOWLIST" | |
| targets = ["0.0.0.0/0"] # ALLOW any domain/IP (placeholder) | |
| target_types = ["TLS_SNI"] | |
| } | |
| } | |
| } | |
| tags = var.tags | |
| } | |
| resource "aws_networkfirewall_firewall_policy" "this" { | |
| name = "${var.name}-policy" | |
| firewall_policy { | |
| stateless_default_actions = ["aws:forward_to_sfe"] | |
| stateless_fragment_default_actions = ["aws:forward_to_sfe"] | |
| stateful_engine_options { | |
| rule_order = "STRICT_ORDER" | |
| } | |
| # Reference our single stateful rule group | |
| stateful_rule_group_reference { | |
| resource_arn = aws_networkfirewall_rule_group.stateful_group.arn | |
| priority = 1 | |
| } | |
| } | |
| tags = var.tags | |
| } | |
| resource "aws_networkfirewall_firewall" "this" { | |
| name = "${var.name}-firewall" | |
| firewall_policy_arn = aws_networkfirewall_firewall_policy.this.arn | |
| vpc_id = var.vpc_id | |
| dynamic "subnet_mapping" { | |
| for_each = var.subnet_ids | |
| content { | |
| subnet_id = subnet_mapping.value | |
| } | |
| } | |
| # For demonstration, we turn off protection features | |
| delete_protection = false | |
| firewall_policy_change_protection = false | |
| subnet_change_protection = false | |
| description = "AWS Network Firewall for ${var.name}" | |
| tags = var.tags | |
| } | |
| modules/firewall/outputs.tf | |
| output "firewall_arn" { | |
| description = "ARN of the AWS Network Firewall firewall" | |
| value = aws_networkfirewall_firewall.this.arn | |
| } | |
| output "firewall_policy_arn" { | |
| description = "ARN of the AWS Network Firewall policy" | |
| value = aws_networkfirewall_firewall_policy.this.arn | |
| } | |
| output "firewall_name" { | |
| description = "Name of the AWS Network Firewall firewall" | |
| value = aws_networkfirewall_firewall.this.name | |
| } | |
| 3. Create Two Firewalls (NP MEL & NP SYD) | |
| In np/np_mel_syd_prot_firewalls.tf, we call the firewall module twice—once for NP MEL prot fw and once for NP SYD prot fw. | |
| Note: We assume you already have VPCs and subnets for these firewall deployments. Replace the placeholder IDs with your real resource references. | |
| ############################################################ | |
| # NP MEL Protected Firewall | |
| ############################################################ | |
| module "np_mel_prot_fw" { | |
| source = "../modules/firewall" | |
| name = "np-mel-prot" | |
| vpc_id = "vpc-0abcd1234melprot" # <--- Replace with real VPC ID | |
| subnet_ids = [ | |
| "subnet-0aaa1234melA", # <--- Replace | |
| "subnet-0bbb1234melB", # <--- Replace | |
| ] | |
| tags = { | |
| Environment = "nonprod" | |
| Region = "mel" | |
| Firewall = "prot" | |
| } | |
| } | |
| ############################################################ | |
| # NP SYD Protected Firewall | |
| ############################################################ | |
| module "np_syd_prot_fw" { | |
| source = "../modules/firewall" | |
| name = "np-syd-prot" | |
| vpc_id = "vpc-0abcd1234sydprot" # <--- Replace with real VPC ID | |
| subnet_ids = [ | |
| "subnet-0aaa1234sydA", # <--- Replace | |
| "subnet-0bbb1234sydB", # <--- Replace | |
| ] | |
| tags = { | |
| Environment = "nonprod" | |
| Region = "syd" | |
| Firewall = "prot" | |
| } | |
| } | |
| 4. CloudWAN Policy Module (modules/cloudwan_policy/) | |
| This module simply applies the JSON policy to an existing core network. You can keep your policy logic in a separate cloudwan_policy.json for clarity. | |
| modules/cloudwan_policy/variables.tf | |
| variable "core_network_id" { | |
| type = string | |
| description = "ID of the AWS Network Manager core network" | |
| } | |
| variable "policy_json_file" { | |
| type = string | |
| description = "Path to the JSON file that defines the CloudWAN policy" | |
| } | |
| variable "description" { | |
| type = string | |
| default = "CloudWAN policy update" | |
| } | |
| modules/cloudwan_policy/main.tf | |
| resource "aws_networkmanager_core_network_policy" "this" { | |
| core_network_id = var.core_network_id | |
| policy_document = file(var.policy_json_file) | |
| description = var.description | |
| } | |
| output "policy_version" { | |
| description = "Policy version number" | |
| value = aws_networkmanager_core_network_policy.this.core_network_policy_version | |
| } | |
| 5. CloudWAN Policy JSON | |
| In np/cloudwan_policy.json, we define segments and segmentActions such that NP MEL prot and NP SYD prot must always go through NP MEL prot fw and NP SYD prot fw, respectively. In a 2-region scenario, we effectively want: | |
| 1. MEL prot seg → SYD prot seg path: | |
| • Must pass through np-mel-prot-fw-seg first | |
| • Then through np-syd-prot-fw-seg next | |
| 2. SYD prot seg → MEL prot seg path: | |
| • Must pass through np-syd-prot-fw-seg first | |
| • Then np-mel-prot-fw-seg | |
| A minimal example might look like this: | |
| { | |
| // 1) Define your segments | |
| "segments": [ | |
| { "name": "np-mel-prot-seg" }, | |
| { "name": "np-mel-prot-fw-seg" }, | |
| { "name": "np-syd-prot-seg" }, | |
| { "name": "np-syd-prot-fw-seg" } | |
| ], | |
| // 2) CloudWAN core config | |
| "coreNetworkConfiguration": { | |
| "edgeLocations": ["ALL_REGIONS"], | |
| "asnRanges": ["64512-64516"] | |
| }, | |
| // 3) The key: segmentActions | |
| "segmentActions": [ | |
| // A) MEL prot -> SYD prot | |
| { | |
| "segmentName": "np-mel-prot-seg", | |
| "destinations": [ | |
| { | |
| "segmentName": "np-syd-prot-seg", | |
| "mode": "STRICT", | |
| // Must pass through MEL's firewall first | |
| "attachmentName": "np-mel-prot-fw-seg" | |
| } | |
| ] | |
| }, | |
| { | |
| // After MEL fw, must pass through SYD's fw to reach SYD prot | |
| "segmentName": "np-mel-prot-fw-seg", | |
| "destinations": [ | |
| { | |
| "segmentName": "np-syd-prot-seg", | |
| "mode": "STRICT", | |
| "attachmentName": "np-syd-prot-fw-seg" | |
| } | |
| ] | |
| }, | |
| // B) SYD prot -> MEL prot (reverse path) | |
| { | |
| "segmentName": "np-syd-prot-seg", | |
| "destinations": [ | |
| { | |
| "segmentName": "np-mel-prot-seg", | |
| "mode": "STRICT", | |
| "attachmentName": "np-syd-prot-fw-seg" | |
| } | |
| ] | |
| }, | |
| { | |
| "segmentName": "np-syd-prot-fw-seg", | |
| "destinations": [ | |
| { | |
| "segmentName": "np-mel-prot-seg", | |
| "mode": "STRICT", | |
| "attachmentName": "np-mel-prot-fw-seg" | |
| } | |
| ] | |
| } | |
| ] | |
| } | |
| Notice how we break the path into two steps for each direction so that traffic transits the local firewall segment, then the remote firewall segment, before reaching the remote prot segment. | |
| 6. Applying the Policy | |
| In np/np_cloudwan_policy.tf, we reference the JSON file and the core network ID (assume it’s named aws_networkmanager_core_network.np_core_network.id or similar): | |
| module "np_cloudwan_policy" { | |
| source = "../modules/cloudwan_policy" | |
| core_network_id = aws_networkmanager_core_network.np_core_network.id | |
| policy_json_file = "${path.module}/cloudwan_policy.json" | |
| description = "NP CloudWAN policy for MEL-SYD prot via firewall insertion" | |
| } | |
| This ensures: | |
| 1. The segments (np-mel-prot-seg, np-mel-prot-fw-seg, np-syd-prot-seg, np-syd-prot-fw-seg) exist in the core network. | |
| 2. Traffic from np-mel-prot-seg to np-syd-prot-seg forcibly goes: | |
| • np-mel-prot-seg → np-mel-prot-fw-seg → np-syd-prot-fw-seg → np-syd-prot-seg | |
| 3. And the reverse path likewise. | |
| 7. High-Level Flow | |
| Here’s what the final flow looks like after you attach your actual VPCs: | |
| • NP MEL Protected VPC is attached to np-mel-prot-seg. | |
| • NP MEL Protected FW VPC is attached to np-mel-prot-fw-seg. | |
| • NP SYD Protected VPC is attached to np-syd-prot-seg. | |
| • NP SYD Protected FW VPC is attached to np-syd-prot-fw-seg. | |
| Now, traffic from NP MEL prot → NP SYD prot is: | |
| 1. Start in np-mel-prot-seg | |
| 2. Hit np-mel-prot-fw-seg (the local firewall) | |
| 3. Transit to np-syd-prot-fw-seg (the remote firewall) | |
| 4. Finally reach np-syd-prot-seg (the destination VPC) | |
| And symmetrical in reverse. | |
| 8. Summary | |
| • Firewall Module: Creates AWS Network Firewall resources (rule groups, firewall policy, firewall) inside a firewall VPC. | |
| • CloudWAN Policy Module: Reads a JSON file defining segments, traffic rules, and service-insertion paths. | |
| • Multiple Firewalls: Achieved by chaining “segmentActions” with "mode": "STRICT" so traffic must pass through local FW segment first, then the remote FW segment. | |
| • 2 Directions: Simply replicate the rules in the JSON for both source→destination and destination→source. | |
| Feel free to adapt the naming, subnets, and references to match your actual environment. Once your VPC attachments align with these segment names, the CloudWAN policy routes traffic as specified. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment