Skip to content

Instantly share code, notes, and snippets.

@huynhbaoan
Created December 30, 2024 03:30
Show Gist options
  • Select an option

  • Save huynhbaoan/6a9a7ff511494da3973bc52f479610ed to your computer and use it in GitHub Desktop.

Select an option

Save huynhbaoan/6a9a7ff511494da3973bc52f479610ed to your computer and use it in GitHub Desktop.
Below is a conceptual guide to how AWS Network Firewall fits together with CloudWAN service insertion, answering common questions about subnets, firewall VPC design, and how the various AWS Network Firewall resources (firewall, firewall policy, logging config, resource policy, rule groups) work together in Terraform.
1. How Many Subnets Does a Firewall VPC Need?
When using AWS Network Firewall in a “service insertion” scenario with CloudWAN, you typically need one dedicated subnet per Availability Zone for the firewall endpoints. Each of those subnets hosts a firewall endpoint in that AZ.
• Minimum: 1 subnet in each AZ you want covered by the firewall.
• High Availability: If you need multi-AZ redundancy, you create a subnet in each AZ (e.g., AZ-a, AZ-b, AZ-c).
Do We Also Need a “Transit” Subnet?
For some reference architectures (especially with Transit Gateway or a more complex design), you’ll see separate “transport” or “inspection” subnets. With CloudWAN service insertion, the traffic is routed at the CloudWAN layer into the firewall VPC. You don’t necessarily need a separate “transit” subnet in the firewall VPC unless your broader architecture requires it (e.g., if you’re also hosting additional components or NAT gateways).
In most CloudWAN-based designs:
1. Firewall subnets in each AZ for the AWS Network Firewall endpoints (required).
2. Optionally, management or utility subnets if you run other services in that VPC (e.g., a jump box).
The critical piece for AWS Network Firewall is:
• The firewall resource is mapped to one or more subnets (one per AZ).
• CloudWAN’s policy insertion ensures traffic automatically flows to these endpoints.
2. How Network Firewall Components Work Together
AWS Network Firewall has a few building blocks you’ll see in Terraform:
1. Rule Groups
• Define your actual firewall rules. Can be stateless or stateful.
• Example usage in Terraform:
resource "aws_networkfirewall_rule_group" "stateful_group" {
name = "my-stateful-rules"
capacity = 100
type = "STATEFUL"
rule_group {
rules_source {
rules_source_list {
generated_rules_type = "ALLOWLIST"
targets = ["1.2.3.4/32"] // Example
target_types = ["TLS_SNI"]
}
}
}
}
2. Firewall Policy
• References one or more rule groups to form the complete policy.
• Example usage:
resource "aws_networkfirewall_firewall_policy" "example" {
name = "my-firewall-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"
}
stateful_rule_group_reference {
resource_arn = aws_networkfirewall_rule_group.stateful_group.arn
priority = 1
}
}
}
3. Firewall
• Binds a firewall policy to a VPC and its subnets (one subnet per AZ).
• In Terraform:
resource "aws_networkfirewall_firewall" "example" {
name = "my-firewall"
firewall_policy_arn = aws_networkfirewall_firewall_policy.example.arn
vpc_id = var.vpc_id
subnet_mapping {
subnet_id = var.subnet_ids[0] // e.g., one per AZ
}
subnet_mapping {
subnet_id = var.subnet_ids[1]
}
# ... additional subnets as needed
}
4. Logging Configuration (optional but recommended)
• Controls where AWS Network Firewall logs (Flow Logs, Alert Logs) go: S3, CloudWatch, or Kinesis.
• In Terraform:
resource "aws_networkfirewall_logging_configuration" "this" {
firewall_arn = aws_networkfirewall_firewall.example.arn
logging_configuration {
log_destination_config {
log_destination = { "bucketName" = "my-nfw-logs" }
log_destination_type = "S3"
log_type = "FLOW"
}
log_destination_config {
log_destination = { "bucketName" = "my-nfw-logs" }
log_destination_type = "S3"
log_type = "ALERT"
}
}
}
5. Resource Policy (optional)
• Used if you need to share AWS Network Firewall rule groups or firewall policies across accounts. It’s a JSON IAM policy that grants other principals permission to manage or attach to your firewall resources.
• In Terraform:
resource "aws_networkfirewall_resource_policy" "example_policy" {
resource_arn = aws_networkfirewall_rule_group.stateful_group.arn
policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowCrossAccountUse",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::111122223333:root"
},
"Action": "network-firewall:DescribeRuleGroup",
"Resource": "*"
}
]
}
EOF
}
3. Bringing It All Together in Terraform
Below is a short example that ties all the pieces together in a single file. Imagine we have a firewall VPC in np-mel with two subnets (subnetA, subnetB for AZ-a, AZ-b). We want:
• One stateful rule group
• One firewall policy referencing that rule group
• One firewall with logging to S3
• (Optional) Resource policy to share the rule group
<details>
<summary>A combined sample <code>.tf</code> snippet</summary>
##################
# RULE GROUP
##################
resource "aws_networkfirewall_rule_group" "my_stateful_group" {
name = "np-mel-prot-stateful-group"
capacity = 100
type = "STATEFUL"
rule_group {
rules_source {
rules_source_list {
generated_rules_type = "ALLOWLIST"
targets = ["0.0.0.0/0"] // Example allow everything
target_types = ["TLS_SNI"]
}
}
}
}
##################
# FIREWALL POLICY
##################
resource "aws_networkfirewall_firewall_policy" "my_firewall_policy" {
name = "np-mel-prot-firewall-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"
}
# Attach the rule group
stateful_rule_group_reference {
resource_arn = aws_networkfirewall_rule_group.my_stateful_group.arn
priority = 1
}
}
}
##################
# FIREWALL
##################
resource "aws_networkfirewall_firewall" "my_firewall" {
name = "np-mel-prot-firewall"
firewall_policy_arn = aws_networkfirewall_firewall_policy.my_firewall_policy.arn
vpc_id = var.firewall_vpc_id
# Subnets for the firewall endpoints (AZ-a, AZ-b for example)
subnet_mapping {
subnet_id = var.subnet_mel_a
}
subnet_mapping {
subnet_id = var.subnet_mel_b
}
delete_protection = false
firewall_policy_change_protection = false
subnet_change_protection = false
}
##################
# LOGGING
##################
resource "aws_networkfirewall_logging_configuration" "my_logging" {
firewall_arn = aws_networkfirewall_firewall.my_firewall.arn
logging_configuration {
log_destination_config {
log_type = "FLOW"
log_destination_type = "S3"
log_destination = {
"bucketName" = aws_s3_bucket.my_firewall_logs.bucket
}
}
log_destination_config {
log_type = "ALERT"
log_destination_type = "S3"
log_destination = {
"bucketName" = aws_s3_bucket.my_firewall_logs.bucket
}
}
}
}
##################
# (OPTIONAL) RESOURCE POLICY
##################
resource "aws_networkfirewall_resource_policy" "my_fw_rule_group_policy" {
resource_arn = aws_networkfirewall_rule_group.my_stateful_group.arn
policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowCrossAccountUse",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::111122223333:root"
},
"Action": [
"network-firewall:DescribeRuleGroup"
],
"Resource": "*"
}
]
}
EOF
}
</details>
How traffic flows once CloudWAN is configured for service insertion:
1. Your CloudWAN core network policy mandates traffic from segment A to segment B route via the Firewall segment.
2. CloudWAN routes that traffic into the firewall subnets in your VPC.
3. Network Firewall applies the rule groups in the firewall policy.
4. If logs are enabled, the firewall sends logs to S3 (or CloudWatch or Kinesis).
4. Key Takeaways
1. Subnets: You need at least 1 subnet per AZ where you want a firewall endpoint. With CloudWAN service insertion, you do not strictly need separate “transit” subnets unless your design calls for them.
2. Rule Groups: The actual firewall rules (stateless or stateful).
3. Firewall Policy: Bundles your rule groups into a complete “policy” that the firewall enforces.
4. Firewall: Deployed in a VPC, references the firewall policy, and attaches to subnets for each AZ.
5. Logging: Optional but recommended. Separate resource to define your log destinations for FLOW or ALERT logs.
6. Resource Policy: Only if you need to share firewall or rule groups across accounts.
7. CloudWAN Service Insertion: Instead of manually updating route tables, you rely on the CloudWAN core network policy to steer traffic to the firewall segment.
Once you grasp these building blocks, you can replicate them for multiple firewall VPCs in multiple regions (NP MEL, NP SYD, etc.) and chain them in the CloudWAN policy JSON (e.g., “MEL → MEL firewall → SYD firewall → SYD”).
Hope this clarifies how AWS Network Firewall pieces fit together (subnets, firewall, firewall policy, logging, rule groups, resource policy) and how to represent them in Terraform. Combine that with CloudWAN’s service insertion JSON for a full end-to-end solution.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment