diff --git a/README.md b/README.md
index ba49b13..4b6e160 100644
--- a/README.md
+++ b/README.md
@@ -12,10 +12,12 @@ This repository contains a number of Terraform modules for creation of the pre-r
| [terraform-cdp-deploy](modules/terraform-cdp-deploy/README.md) | For deployment of CDP on AWS, Azure or GCP. |
| [terraform-aws-cred-permissions](modules/terraform-aws-cred-permissions/README.md) | Module for creation of the Cross Account Credential pre-requisite on AWS. Note that this module is called from the terraform-cdp-aws-prereqs module. |
| [terraform-aws-permissions](modules/terraform-aws-permissions/README.md) | Module for creation of the AWS IAM permissions required by the (CDP) Public Cloud environment and datalake deployment. Note that this module is called from the terraform-cdp-aws-prereqs module. |
-| [terraform-aws-vpc](modules/terraform-aws-vpc/README.md) | Module for creation of the VPC networking resources on AWS suitable. Can be used to create the CDP VPC and Subnets. Note that this module is called from the terraform-cdp-aws-prereqs module. |
+| [terraform-aws-vpc](modules/terraform-aws-vpc/README.md) | Module for creation of the VPC networking resources on AWS. Can be used to create the CDP VPC and Subnets. Note that this module is called from the terraform-cdp-aws-prereqs module. |
+| [terraform-aws-fw-vpc](modules/terraform-aws-fw-vpc/README.md) | Module for creation of the VPC networking resources on AWS suitable for running a Firewall in a distributed architecture on AWS. Can be used to create a networking VPC which runs the AWS Network Firewall and connects to a Cloudera on cloud full-private deployment. |
| [terraform-aws-tgw](modules/terraform-aws-tgw/README.md) | Module for creation of AWS Transity Gateway (TGW) and attaching a specified list of VPCs via the TGW. This module can be used to assist in deploying Cloudera Data Platform (CDP) Public Cloud in a fully private networking configuration where a CDP VPC and Networking VPC are connected using the Transit Gateway. |
| [terraform-aws-bastion](modules/terraform-aws-bastion/README.md) | Module to create a Bastion EC2 instance on AWS. This module can be used to assist in deploying Cloudera Data Platform (CDP) Public Cloud in a secure environment, where the CDP Environment requires a Bastion host. |
| [terraform-aws-proxy](modules/terraform-aws-proxy/README.md) | Module to create and configure and EC2 Auto-Scaling Group for a highly available Squid Proxy service with Network Load Balancer (NLB) to forward traffic to the proxy instances. This module can be used to assist in deploying Cloudera Data Platform (CDP) Public Cloud in a fully private networking configuration where a the CDP Environments uses a proxy config via the NLB. |
+| [terraform-aws-firewall](modules/terraform-aws-firewall/README.md) | Module to create and configure to create and configure an AWS Network Firewall. This module can be used to assist in deploying Cloudera Data Platform (CDP) Public Cloud in a fully private networking configuration where the CDP Environment is connected to a Networking VPC running the Firewall. |
| [terraform-azure-nfs](modules/terraform-azure-nfs/README.md) | Module for creation of Azure NFS File Share required for Cloudera Machine Learning (CML) Public Cloud. Also optionally creates a Virtual Machine which can be used to mount and set the required ownership for CML workspace's projects folder.|
| [terraform-azure-cdw-permissions](modules/terraform-azure-cdw-permissions/README.md) | Module for creation of the Azure Kubernetes Service (AKS) managed identity required for the Cloudera Data Warehouse (CDW) service.|
| [terraform-azure-storage-endpoints](modules/terraform-azure-storage-endpoints/README.md) | Module for creation creation of Azure private endpoints between specified storage accounts and VNet subnets.|
diff --git a/modules/terraform-aws-firewall/.terraform-docs.yaml b/modules/terraform-aws-firewall/.terraform-docs.yaml
new file mode 100644
index 0000000..0936036
--- /dev/null
+++ b/modules/terraform-aws-firewall/.terraform-docs.yaml
@@ -0,0 +1,21 @@
+formatter: markdown
+header-from: doc_fragments/header.md
+settings:
+ anchor: true
+ color: true
+ default: true
+ escape: true
+ html: true
+ indent: 2
+ required: true
+ sensitive: true
+ type: true
+
+
+sort:
+ enabled: true
+ by: required
+
+output:
+ file: README.md
+ mode: replace
\ No newline at end of file
diff --git a/modules/terraform-aws-firewall/README.md b/modules/terraform-aws-firewall/README.md
new file mode 100644
index 0000000..c4397d0
--- /dev/null
+++ b/modules/terraform-aws-firewall/README.md
@@ -0,0 +1,69 @@
+
+# Terraform Module for AWS Network Firewall
+
+This module contains resource files and example variable definition files to create and configure an AWS Network Firewall. This module can be used to assist in deploying Cloudera Data Platform (CDP) Public Cloud in a fully private networking configuration where the CDP Environment is connected to a Networking VPC running the Firewall.
+
+## Usage
+
+The [examples](./examples) directory has example of using this module:
+
+* `ex01-minimal_inputs` demonstrates how this module can be used to within a networking VPC. The [terraform-aws-nfw-vpc](../../../terraform-aws-nfw-vpc/README.md) module is also used as part of this example.
+
+The sample `terraform.tfvars.sample` describes the required inputs for the example.
+
+## Requirements
+
+| Name | Version |
+|------|---------|
+| [terraform](#requirement\_terraform) | > 1.3.0 |
+| [aws](#requirement\_aws) | >= 5.30 |
+
+## Providers
+
+| Name | Version |
+|------|---------|
+| [aws](#provider\_aws) | >= 5.30 |
+
+## Modules
+
+No modules.
+
+## Resources
+
+| Name | Type |
+|------|------|
+| [aws_cloudwatch_log_group.nfw_log_group](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_log_group) | resource |
+| [aws_networkfirewall_firewall.fw](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/networkfirewall_firewall) | resource |
+| [aws_networkfirewall_firewall_policy.fw_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/networkfirewall_firewall_policy) | resource |
+| [aws_networkfirewall_logging_configuration.nfw_log_config](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/networkfirewall_logging_configuration) | resource |
+| [aws_networkfirewall_rule_group.cdp_env_fw_rg](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/networkfirewall_rule_group) | resource |
+| [aws_route.vpc_tgw_route](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route) | resource |
+| [aws_vpc.cdp_vpc](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/vpc) | data source |
+| [aws_vpc.network_vpc](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/vpc) | data source |
+
+## Inputs
+
+| Name | Description | Type | Default | Required |
+|------|-------------|------|---------|:--------:|
+| [cdp\_firewall\_rule\_group\_name](#input\_cdp\_firewall\_rule\_group\_name) | Name of the CDP Rule Group. | `string` | n/a | yes |
+| [cdp\_vpc\_id](#input\_cdp\_vpc\_id) | VPC ID for where the CDP environment is running | `string` | n/a | yes |
+| [firewall\_name](#input\_firewall\_name) | Name of the Firewall. | `string` | n/a | yes |
+| [firewall\_policy\_name](#input\_firewall\_policy\_name) | Name of the Firewall Policy. | `string` | n/a | yes |
+| [firewall\_subnet\_ids](#input\_firewall\_subnet\_ids) | List of subnet ids to assign to the Firewall. | `list(string)` | n/a | yes |
+| [network\_vpc\_id](#input\_network\_vpc\_id) | VPC ID for where the Networking components are running | `string` | n/a | yes |
+| [cdp\_firewall\_domain\_allowlist](#input\_cdp\_firewall\_domain\_allowlist) | Domain allowlist for CDP Rule Group. | `list(string)` |
[
"cloudera.com"
]
| no |
+| [cdp\_fw\_rule\_group\_capacity](#input\_cdp\_fw\_rule\_group\_capacity) | Capacity (maximum number of operating resources) for the CDP Firewall Rule Group | `number` | `300` | no |
+| [firewall\_logging\_config](#input\_firewall\_logging\_config) | Logging config for cloudwatch logs created for network Firewall | `map(any)` | {
"alert": {
"retention_in_days": 3
},
"flow": {
"retention_in_days": 1
}
}
| no |
+| [route\_tables\_to\_update](#input\_route\_tables\_to\_update) | List of any route tables to update to target the Firewall Endpoint | list(object({
route_tables = list(string)
availability_zones = optional(list(string))
destination_cidr_block = string
}))
| `[]` | no |
+| [tags](#input\_tags) | Tags applied to provisioned resources | `map(any)` | `{}` | no |
+
+## Outputs
+
+| Name | Description |
+|------|-------------|
+| [nfw\_arn](#output\_nfw\_arn) | The Amazon Resource Name (ARN) of the AWS Network Firewall |
+| [nfw\_id](#output\_nfw\_id) | The Amazon Resource id of the AWS Network Firewall |
+| [nfw\_logging\_configuration\_ids](#output\_nfw\_logging\_configuration\_ids) | The Amazon Resource id (ARN) of the logging configuration associated with the AWS Network Firewall |
+| [nfw\_policy\_arn](#output\_nfw\_policy\_arn) | The Amazon Resource Name (ARN) that identifies the firewall policy |
+| [nfw\_policy\_id](#output\_nfw\_policy\_id) | The Amazon Resource id of the firewall policy for the AWS Network Firewall |
+
\ No newline at end of file
diff --git a/modules/terraform-aws-firewall/data.tf b/modules/terraform-aws-firewall/data.tf
new file mode 100644
index 0000000..ee83290
--- /dev/null
+++ b/modules/terraform-aws-firewall/data.tf
@@ -0,0 +1,22 @@
+# Copyright 2025 Cloudera, Inc. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Find details of the CDP and Networking VPCs
+data "aws_vpc" "network_vpc" {
+ id = var.network_vpc_id
+}
+
+data "aws_vpc" "cdp_vpc" {
+ id = var.cdp_vpc_id
+}
diff --git a/modules/terraform-aws-firewall/defaults.tf b/modules/terraform-aws-firewall/defaults.tf
new file mode 100644
index 0000000..c82d5e7
--- /dev/null
+++ b/modules/terraform-aws-firewall/defaults.tf
@@ -0,0 +1,30 @@
+# Copyright 2025 Cloudera, Inc. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+locals {
+
+ # Local variables to determine route table to Firewall VPC Endpoint mapping
+ route_tables_to_update = flatten([
+ for route in var.route_tables_to_update :
+ [
+ for rti, rt in route.route_tables :
+ {
+ route_table = rt
+ availability_zone = try(route.availability_zones[rti], null)
+ destination_cidr_block = route.destination_cidr_block
+ }
+ ]
+ ])
+
+}
\ No newline at end of file
diff --git a/modules/terraform-aws-firewall/doc_fragments/header.md b/modules/terraform-aws-firewall/doc_fragments/header.md
new file mode 100644
index 0000000..1e384a2
--- /dev/null
+++ b/modules/terraform-aws-firewall/doc_fragments/header.md
@@ -0,0 +1,11 @@
+# Terraform Module for AWS Network Firewall
+
+This module contains resource files and example variable definition files to create and configure an AWS Network Firewall. This module can be used to assist in deploying Cloudera Data Platform (CDP) Public Cloud in a fully private networking configuration where the CDP Environment is connected to a Networking VPC running the Firewall.
+
+## Usage
+
+The [examples](./examples) directory has example of using this module:
+
+* `ex01-minimal_inputs` demonstrates how this module can be used to within a networking VPC. The [terraform-aws-nfw-vpc](../../../terraform-aws-nfw-vpc/README.md) module is also used as part of this example.
+
+The sample `terraform.tfvars.sample` describes the required inputs for the example.
diff --git a/modules/terraform-aws-firewall/examples/ex01-minimal_inputs/main.tf b/modules/terraform-aws-firewall/examples/ex01-minimal_inputs/main.tf
new file mode 100644
index 0000000..6817ea0
--- /dev/null
+++ b/modules/terraform-aws-firewall/examples/ex01-minimal_inputs/main.tf
@@ -0,0 +1,51 @@
+# Copyright 2025 Cloudera, Inc. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+provider "aws" {
+ region = var.aws_region
+}
+
+module "ex01_network_vpc" {
+ source = "../../../terraform-aws-nfw-vpc"
+
+ vpc_name = "${var.name_prefix}-network-vpc"
+
+ subnet_name_prefix = var.name_prefix
+ nat_gateway_name_prefix = var.name_prefix
+ route_table_name_prefix = var.name_prefix
+
+ vpc_cidr = var.vpc_cidr
+
+ tags = var.env_tags
+
+}
+
+module "ex01_nfw" {
+ source = "../.."
+
+ cdp_firewall_rule_group_name = "${var.name_prefix}-cdp-rg"
+ firewall_policy_name = "${var.name_prefix}-fwp"
+ firewall_name = "${var.name_prefix}-fw"
+
+ cdp_vpc_id = module.ex01_network_vpc.vpc_id
+ network_vpc_id = module.ex01_network_vpc.vpc_id
+
+ firewall_subnet_ids = module.ex01_network_vpc.fw_subnet_ids
+
+ # route_tables_to_update = []
+
+ tags = var.env_tags
+
+
+}
diff --git a/modules/terraform-aws-firewall/examples/ex01-minimal_inputs/terraform.tfvars.sample b/modules/terraform-aws-firewall/examples/ex01-minimal_inputs/terraform.tfvars.sample
new file mode 100644
index 0000000..175c3d9
--- /dev/null
+++ b/modules/terraform-aws-firewall/examples/ex01-minimal_inputs/terraform.tfvars.sample
@@ -0,0 +1,23 @@
+# Copyright 2025 Cloudera, Inc. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# ------- Global Settings -------
+name_prefix = ""
+
+# ------- Cloud Settings -------
+aws_region = "" # Change this to specify Cloud Provider region, e.g. eu-west-1
+
+# ------- VPC Settings -------
+
+vpc_cidr = "10.11.0.0/16" # Change CIDR value if needed
\ No newline at end of file
diff --git a/modules/terraform-aws-firewall/examples/ex01-minimal_inputs/variables.tf b/modules/terraform-aws-firewall/examples/ex01-minimal_inputs/variables.tf
new file mode 100644
index 0000000..38ef1cb
--- /dev/null
+++ b/modules/terraform-aws-firewall/examples/ex01-minimal_inputs/variables.tf
@@ -0,0 +1,38 @@
+# Copyright 2025 Cloudera, Inc. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# ------- Global settings -------
+variable "aws_region" {
+ type = string
+ description = "Region which Cloud resources will be created"
+}
+
+variable "env_tags" {
+ type = map(any)
+ description = "Tags applied to provised resources"
+
+ default = null
+}
+
+variable "name_prefix" {
+ type = string
+ description = "Shorthand name to use when naming resources."
+}
+
+# ------- Network Resources -------
+variable "vpc_cidr" {
+ type = string
+ description = "VPC CIDR Block. Required if create_vpc is true."
+
+}
\ No newline at end of file
diff --git a/modules/terraform-aws-firewall/main.tf b/modules/terraform-aws-firewall/main.tf
new file mode 100644
index 0000000..03ca8e4
--- /dev/null
+++ b/modules/terraform-aws-firewall/main.tf
@@ -0,0 +1,137 @@
+# Copyright 2025 Cloudera, Inc. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# ------- Firewall Rule Group -------
+resource "aws_networkfirewall_rule_group" "cdp_env_fw_rg" {
+ capacity = var.cdp_fw_rule_group_capacity
+ name = var.cdp_firewall_rule_group_name
+ type = "STATEFUL"
+
+ rule_group {
+ stateful_rule_options {
+ rule_order = "STRICT_ORDER"
+ }
+ rule_variables {
+ ip_sets {
+ key = "HOME_NET"
+ ip_set {
+ definition = [data.aws_vpc.network_vpc.cidr_block, data.aws_vpc.cdp_vpc.cidr_block]
+ }
+ }
+ }
+ rules_source {
+ rules_source_list {
+ generated_rules_type = "ALLOWLIST"
+ target_types = ["TLS_SNI", "HTTP_HOST"]
+ targets = var.cdp_firewall_domain_allowlist
+ }
+ }
+
+ }
+ tags = var.tags
+}
+# ------- Firewall Policies -------
+resource "aws_networkfirewall_firewall_policy" "fw_policy" {
+ name = var.firewall_policy_name
+
+ firewall_policy {
+ stateful_default_actions = ["aws:drop_established", "aws:alert_established"]
+ stateful_engine_options {
+ rule_order = "STRICT_ORDER"
+ stream_exception_policy = "DROP"
+ }
+ stateless_default_actions = ["aws:forward_to_sfe"]
+ stateless_fragment_default_actions = ["aws:forward_to_sfe"]
+
+ # TODO: Handle multiple rule groups
+ stateful_rule_group_reference {
+ priority = 1
+ resource_arn = aws_networkfirewall_rule_group.cdp_env_fw_rg.arn
+ }
+ }
+
+ tags = var.tags
+}
+# ------- Firewall -------
+resource "aws_networkfirewall_firewall" "fw" {
+ name = var.firewall_name
+ firewall_policy_arn = aws_networkfirewall_firewall_policy.fw_policy.arn
+ vpc_id = data.aws_vpc.network_vpc.id
+
+ dynamic "subnet_mapping" {
+ for_each = var.firewall_subnet_ids
+
+ content {
+ subnet_id = subnet_mapping.value
+ }
+ }
+
+ tags = var.tags
+
+ timeouts {
+ create = "40m"
+ update = "50m"
+ delete = "1h"
+ }
+}
+
+# ------- Route Table update -------
+
+# Update the route tables to point to Firewall VPC Endpoint
+resource "aws_route" "vpc_tgw_route" {
+ for_each = {
+ for k, v in local.route_tables_to_update : k => v
+ }
+
+ route_table_id = each.value.route_table
+ destination_cidr_block = each.value.destination_cidr_block
+
+ # Where route AZ info is available, use Firewall VPC Endpoint from same AZ as subnet where route table is associated. Otherwise set to first Firewall Endpoint
+ # Ref: https://github.com/hashicorp/terraform-provider-aws/issues/16759#issuecomment-1768591117
+ vpc_endpoint_id = try(element([for ss in tolist(aws_networkfirewall_firewall.fw.firewall_status[0].sync_states) : ss.attachment[0].endpoint_id if ss.availability_zone == each.value.availability_zone], 0), tolist(aws_networkfirewall_firewall.fw.firewall_status[0].sync_states)[0].attachment[0].endpoint_id)
+}
+
+# ------- Logging Configuration -------
+resource "aws_cloudwatch_log_group" "nfw_log_group" {
+ for_each = try(var.firewall_logging_config, {})
+
+ name = "/aws/network-firewall/${var.firewall_name}-${each.key}"
+ retention_in_days = try(each.value.retention_in_days, null)
+ log_group_class = try(each.value.log_group_class, null)
+
+ tags = var.tags
+
+}
+
+resource "aws_networkfirewall_logging_configuration" "nfw_log_config" {
+
+ count = try(length(var.firewall_logging_config), 0) > 0 ? 1 : 0
+
+ firewall_arn = aws_networkfirewall_firewall.fw.arn
+
+ logging_configuration {
+ dynamic "log_destination_config" {
+ for_each = var.firewall_logging_config
+ content {
+ log_destination = {
+ logGroup = aws_cloudwatch_log_group.nfw_log_group[log_destination_config.key].name
+ }
+ log_destination_type = "CloudWatchLogs"
+ log_type = upper(log_destination_config.key)
+ }
+
+ }
+ }
+}
+
diff --git a/modules/terraform-aws-firewall/outputs.tf b/modules/terraform-aws-firewall/outputs.tf
new file mode 100644
index 0000000..9c2598d
--- /dev/null
+++ b/modules/terraform-aws-firewall/outputs.tf
@@ -0,0 +1,50 @@
+# Copyright 2025 Cloudera, Inc. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+################################################################################
+# Firewall
+################################################################################
+
+output "nfw_id" {
+ description = "The Amazon Resource id of the AWS Network Firewall"
+ value = aws_networkfirewall_firewall.fw.id
+}
+
+output "nfw_arn" {
+ description = "The Amazon Resource Name (ARN) of the AWS Network Firewall"
+ value = aws_networkfirewall_firewall.fw.arn
+}
+
+################################################################################
+# Firewall Logging Configuration
+################################################################################
+
+output "nfw_logging_configuration_ids" {
+ description = "The Amazon Resource id (ARN) of the logging configuration associated with the AWS Network Firewall"
+ value = try(values(aws_networkfirewall_logging_configuration.nfw_log_config[*].id), null)
+}
+
+################################################################################
+# Firewall Policy
+################################################################################
+
+output "nfw_policy_id" {
+ description = "The Amazon Resource id of the firewall policy for the AWS Network Firewall"
+ value = aws_networkfirewall_firewall_policy.fw_policy.id
+}
+
+output "nfw_policy_arn" {
+ description = "The Amazon Resource Name (ARN) that identifies the firewall policy"
+ value = aws_networkfirewall_firewall_policy.fw_policy.arn
+}
diff --git a/modules/terraform-aws-firewall/provider.tf b/modules/terraform-aws-firewall/provider.tf
new file mode 100644
index 0000000..d215e0b
--- /dev/null
+++ b/modules/terraform-aws-firewall/provider.tf
@@ -0,0 +1,24 @@
+# Copyright 2025 Cloudera, Inc. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+terraform {
+ required_providers {
+ aws = {
+ source = "hashicorp/aws"
+ version = ">= 5.30"
+ }
+ }
+
+ required_version = "> 1.3.0"
+}
diff --git a/modules/terraform-aws-firewall/variables.tf b/modules/terraform-aws-firewall/variables.tf
new file mode 100644
index 0000000..24edaf1
--- /dev/null
+++ b/modules/terraform-aws-firewall/variables.tf
@@ -0,0 +1,138 @@
+# Copyright 2025 Cloudera, Inc. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# ------- Global settings -------
+variable "tags" {
+ type = map(any)
+ description = "Tags applied to provisioned resources"
+
+ default = {}
+}
+
+# ------- Firewall Rule Groups -------
+# Rule group for CDP deployment
+variable "cdp_fw_rule_group_capacity" {
+ type = number
+ description = "Capacity (maximum number of operating resources) for the CDP Firewall Rule Group"
+
+ default = 300
+}
+
+variable "cdp_firewall_rule_group_name" {
+ type = string
+
+ description = "Name of the CDP Rule Group."
+
+ validation {
+ condition = (length(var.cdp_firewall_rule_group_name) >= 1 && length(var.cdp_firewall_rule_group_name) <= 64)
+ error_message = "The length of cdp_firewall_rule_group_name must be between 1 and 64 characters."
+ }
+}
+
+variable "cdp_firewall_domain_allowlist" {
+ type = list(string)
+
+ description = "Domain allowlist for CDP Rule Group."
+
+ default = [
+ "cloudera.com"
+ ]
+}
+
+# TODO: Other rule groups?
+
+# ------- Firewall Policies -------
+variable "firewall_policy_name" {
+ type = string
+
+ description = "Name of the Firewall Policy."
+
+ validation {
+ condition = (length(var.firewall_policy_name) >= 1 && length(var.firewall_policy_name) <= 128)
+ error_message = "The length of firewall_policy_name must be between 1 and 128 characters."
+ }
+}
+
+# ------- Firewall -------
+variable "firewall_name" {
+ type = string
+
+ description = "Name of the Firewall."
+
+ validation {
+ condition = (length(var.firewall_name) >= 1 && length(var.firewall_name) <= 256)
+ error_message = "The length of firewall_name must be between 1 and 256 characters."
+ }
+}
+
+variable "firewall_subnet_ids" {
+ type = list(string)
+
+ description = "List of subnet ids to assign to the Firewall."
+}
+
+
+# ------- Logging Config -------
+variable "firewall_logging_config" {
+ description = "Logging config for cloudwatch logs created for network Firewall"
+ type = map(any)
+
+ # NOTE: Stricter type definition below didn't work
+ # type = map(object({
+ # alert = optional(object({
+ # retention_in_days = optional(number)
+ # log_group_class = optional(string)
+ # }))
+ # flow = optional(object({
+ # retention_in_days = optional(number)
+ # log_group_class = optional(string)
+ # }))
+ # tls = optional(object({
+ # retention_in_days = optional(number)
+ # log_group_class = optional(string)
+ # }))
+ # })
+ # )
+ default = {
+ alert = {
+ retention_in_days = 3
+ }
+ flow = {
+ retention_in_days = 1
+ }
+ }
+}
+
+# ------- VPC and Network Settings -------
+variable "cdp_vpc_id" {
+ type = string
+ description = "VPC ID for where the CDP environment is running"
+}
+
+variable "network_vpc_id" {
+ type = string
+ description = "VPC ID for where the Networking components are running"
+}
+
+# ------- Route table updates -------
+variable "route_tables_to_update" {
+ description = "List of any route tables to update to target the Firewall Endpoint"
+ type = list(object({
+ route_tables = list(string)
+ availability_zones = optional(list(string))
+ destination_cidr_block = string
+ }))
+
+ default = []
+}
diff --git a/modules/terraform-aws-nfw-vpc/.terraform-docs.yaml b/modules/terraform-aws-nfw-vpc/.terraform-docs.yaml
new file mode 100644
index 0000000..0936036
--- /dev/null
+++ b/modules/terraform-aws-nfw-vpc/.terraform-docs.yaml
@@ -0,0 +1,21 @@
+formatter: markdown
+header-from: doc_fragments/header.md
+settings:
+ anchor: true
+ color: true
+ default: true
+ escape: true
+ html: true
+ indent: 2
+ required: true
+ sensitive: true
+ type: true
+
+
+sort:
+ enabled: true
+ by: required
+
+output:
+ file: README.md
+ mode: replace
\ No newline at end of file
diff --git a/modules/terraform-aws-nfw-vpc/.tfsec/config.yml b/modules/terraform-aws-nfw-vpc/.tfsec/config.yml
new file mode 100644
index 0000000..82d917c
--- /dev/null
+++ b/modules/terraform-aws-nfw-vpc/.tfsec/config.yml
@@ -0,0 +1,5 @@
+# ---
+exclude:
+#region1 TODO: Explore how to expose these parameters
+ - aws-ec2-require-vpc-flow-logs-for-all-vpcs
+#endregion3
\ No newline at end of file
diff --git a/modules/terraform-aws-nfw-vpc/README.md b/modules/terraform-aws-nfw-vpc/README.md
new file mode 100644
index 0000000..85578ba
--- /dev/null
+++ b/modules/terraform-aws-nfw-vpc/README.md
@@ -0,0 +1,89 @@
+
+# Terraform Module for AWS VPC suitable for hosting AWS Network Firewall
+
+This module contains resource files and example variable definition files for creation of the Virtual Private Cloud (VPC) suitable for running a Firewall in a distributed architecture on AWS. It creates subnets across multiple availability zones for NAT gateways, the Network Firewall and for a Transit Gateway connections to other VPCs.
+
+The module can be used for creation of the a networking VPC which runs the AWS Network Firewall and connects to a Cloudera on cloud full-private deployment.
+
+## Usage
+
+The [examples](./examples) directory has example creating a VPC:
+
+* `ex01-fw-vpc` uses the minimum set of inputs to create a AWS VPC suitable for hosting the AWS Network Firewall.
+
+In each directory an example `terraform.tfvars.sample` values file is included to show input variable values.
+
+## Requirements
+
+| Name | Version |
+|------|---------|
+| [terraform](#requirement\_terraform) | >= 1.3.0 |
+| [aws](#requirement\_aws) | >= 5.30 |
+
+## Providers
+
+| Name | Version |
+|------|---------|
+| [aws](#provider\_aws) | >= 5.30 |
+
+## Modules
+
+No modules.
+
+## Resources
+
+| Name | Type |
+|------|------|
+| [aws_default_route_table.default_rt](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/default_route_table) | resource |
+| [aws_eip.nat_gateway_eip](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/eip) | resource |
+| [aws_internet_gateway.igw](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/internet_gateway) | resource |
+| [aws_nat_gateway.nat_gateway](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/nat_gateway) | resource |
+| [aws_route.fw_nat_rtb_rt](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route) | resource |
+| [aws_route.nat_igw_rtb_rt](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route) | resource |
+| [aws_route_table.fw](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route_table) | resource |
+| [aws_route_table.nat](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route_table) | resource |
+| [aws_route_table.tgw](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route_table) | resource |
+| [aws_route_table_association.fw](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route_table_association) | resource |
+| [aws_route_table_association.nat](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route_table_association) | resource |
+| [aws_route_table_association.tgw](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route_table_association) | resource |
+| [aws_subnet.fw](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/subnet) | resource |
+| [aws_subnet.nat](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/subnet) | resource |
+| [aws_subnet.tgw](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/subnet) | resource |
+| [aws_vpc.vpc](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc) | resource |
+| [aws_availability_zones.zones_in_region](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/availability_zones) | data source |
+
+## Inputs
+
+| Name | Description | Type | Default | Required |
+|------|-------------|------|---------|:--------:|
+| [nat\_gateway\_name\_prefix](#input\_nat\_gateway\_name\_prefix) | Prefix string for the name of all NAT Gateway resources | `string` | n/a | yes |
+| [route\_table\_name\_prefix](#input\_route\_table\_name\_prefix) | Prefix string for the name of all Route Tables created | `string` | n/a | yes |
+| [subnet\_name\_prefix](#input\_subnet\_name\_prefix) | Prefix string for the name of all Subnets created | `string` | n/a | yes |
+| [vpc\_cidr](#input\_vpc\_cidr) | VPC CIDR Block. Only used when create\_vpc is true. | `string` | n/a | yes |
+| [vpc\_name](#input\_vpc\_name) | Name of the VPC | `string` | n/a | yes |
+| [enable\_dns\_hostnames](#input\_enable\_dns\_hostnames) | Enable DNS Hostname support for the VPC. Only used when create\_vpc is true. | `bool` | `true` | no |
+| [enable\_dns\_support](#input\_enable\_dns\_support) | Enable DNS support for the VPC. Only used when create\_vpc is true. | `bool` | `true` | no |
+| [fw\_cidr\_range](#input\_fw\_cidr\_range) | Size of each Firewall subnets. | `number` | `24` | no |
+| [nat\_cidr\_range](#input\_nat\_cidr\_range) | Size of each NAT subnets. | `number` | `24` | no |
+| [tags](#input\_tags) | Tags applied to VPC resources. | `map(any)` | `null` | no |
+| [tgw\_cidr\_range](#input\_tgw\_cidr\_range) | Size of each Transit Gateway subnets. | `number` | `24` | no |
+
+## Outputs
+
+| Name | Description |
+|------|-------------|
+| [default\_route\_table](#output\_default\_route\_table) | The ID of the default route table |
+| [fw\_subnet\_ids](#output\_fw\_subnet\_ids) | The IDs of Firewall subnets |
+| [fw\_subnet\_route\_tables](#output\_fw\_subnet\_route\_tables) | List of IDs of the routes tables associated with the Firewall subnets |
+| [fw\_subnets](#output\_fw\_subnets) | All details of the Firewall subnets |
+| [internet\_gateway\_id](#output\_internet\_gateway\_id) | The ID of the Internet Gateway |
+| [nat\_gateway\_ids](#output\_nat\_gateway\_ids) | List of IDs of the NAT Gateways |
+| [nat\_subnet\_ids](#output\_nat\_subnet\_ids) | The IDs of NAT subnets |
+| [nat\_subnet\_route\_tables](#output\_nat\_subnet\_route\_tables) | List of IDs of the routes tables associated with the NAT subnets |
+| [nat\_subnets](#output\_nat\_subnets) | All details of the NAT subnets |
+| [tgw\_subnet\_ids](#output\_tgw\_subnet\_ids) | The IDs of Transit Gateway subnets |
+| [tgw\_subnet\_route\_tables](#output\_tgw\_subnet\_route\_tables) | List of IDs of the routes tables associated with the Transit Gateway subnets |
+| [tgw\_subnets](#output\_tgw\_subnets) | All details of the Transit Gateway subnets |
+| [vpc\_cidr\_blocks](#output\_vpc\_cidr\_blocks) | CIDR Block Associations for the VPC |
+| [vpc\_id](#output\_vpc\_id) | The ID of the VPC |
+
\ No newline at end of file
diff --git a/modules/terraform-aws-nfw-vpc/data.tf b/modules/terraform-aws-nfw-vpc/data.tf
new file mode 100644
index 0000000..4da2e81
--- /dev/null
+++ b/modules/terraform-aws-nfw-vpc/data.tf
@@ -0,0 +1,18 @@
+# Copyright 2025 Cloudera, Inc. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Find Availability Zones is AWS region
+data "aws_availability_zones" "zones_in_region" {
+ state = "available"
+}
diff --git a/modules/terraform-aws-nfw-vpc/defaults.tf b/modules/terraform-aws-nfw-vpc/defaults.tf
new file mode 100644
index 0000000..d675371
--- /dev/null
+++ b/modules/terraform-aws-nfw-vpc/defaults.tf
@@ -0,0 +1,62 @@
+# Copyright 2025 Cloudera, Inc. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+locals {
+
+ # Create a list of supported zones in the region
+ zones_in_region = tolist(data.aws_availability_zones.zones_in_region.names)
+
+ # ------- Determine subnet details from inputs -------
+ subnets_required = {
+ total = (3 * length(local.zones_in_region))
+ tgw_subnets = length(local.zones_in_region)
+ fw_subnets = length(local.zones_in_region)
+ nat_subnets = length(local.zones_in_region)
+ }
+
+ # Extract the VPC CIDR range from the user-provided CIDR
+ vpc_cidr_range = split("/", var.vpc_cidr)[1]
+
+ tgw_subnets = [
+ for idx in range(local.subnets_required.tgw_subnets) :
+ {
+ name = "${var.subnet_name_prefix}-tgw-sbnt-${format("%02d", idx + 1)}"
+ az = local.zones_in_region[idx % length(local.zones_in_region)]
+ cidr = cidrsubnet(var.vpc_cidr, var.tgw_cidr_range - local.vpc_cidr_range, idx)
+ }
+ ]
+
+ # Calculate the first suitable CIDR range for Firewall subnets after Transit Gateway subnets have been allocated (normalize the offset, expressed as a multiplier of TGW subnet ranges)
+ fw_subnet_offset = ceil(local.subnets_required.fw_subnets * pow(2, 32 - var.fw_cidr_range) / pow(2, 32 - var.tgw_cidr_range))
+ fw_subnets = [
+ for idx in range(local.subnets_required.fw_subnets) :
+ {
+ name = "${var.subnet_name_prefix}-fw-sbnt-${format("%02d", idx + 1)}"
+ az = local.zones_in_region[idx % length(local.zones_in_region)]
+ cidr = cidrsubnet(var.vpc_cidr, var.fw_cidr_range - local.vpc_cidr_range, idx + local.fw_subnet_offset)
+ }
+ ]
+
+ # Calculate the first suitable CIDR range for NAT subnets after Transit Gateway subnets have been allocated (normalize the offset, expressed as a multiplier of TGW subnet ranges)
+ nat_subnet_offset = (ceil(local.subnets_required.nat_subnets * pow(2, 32 - var.nat_cidr_range) / pow(2, 32 - var.tgw_cidr_range))) + local.fw_subnet_offset
+ nat_subnets = [
+ for idx in range(local.subnets_required.nat_subnets) :
+ {
+ name = "${var.subnet_name_prefix}-nat-sbnt-${format("%02d", idx + 1)}"
+ az = local.zones_in_region[idx % length(local.zones_in_region)]
+ cidr = cidrsubnet(var.vpc_cidr, var.nat_cidr_range - local.vpc_cidr_range, idx + local.nat_subnet_offset)
+ }
+ ]
+
+}
diff --git a/modules/terraform-aws-nfw-vpc/doc_fragments/header.md b/modules/terraform-aws-nfw-vpc/doc_fragments/header.md
new file mode 100644
index 0000000..c2db96c
--- /dev/null
+++ b/modules/terraform-aws-nfw-vpc/doc_fragments/header.md
@@ -0,0 +1,13 @@
+# Terraform Module for AWS VPC suitable for hosting AWS Network Firewall
+
+This module contains resource files and example variable definition files for creation of the Virtual Private Cloud (VPC) suitable for running a Firewall in a distributed architecture on AWS. It creates subnets across multiple availability zones for NAT gateways, the Network Firewall and for a Transit Gateway connections to other VPCs.
+
+The module can be used for creation of the a networking VPC which runs the AWS Network Firewall and connects to a Cloudera on cloud full-private deployment.
+
+## Usage
+
+The [examples](./examples) directory has example creating a VPC:
+
+* `ex01-fw-vpc` uses the minimum set of inputs to create a AWS VPC suitable for hosting the AWS Network Firewall.
+
+In each directory an example `terraform.tfvars.sample` values file is included to show input variable values.
diff --git a/modules/terraform-aws-nfw-vpc/examples/ex01-fw-vpc/main.tf b/modules/terraform-aws-nfw-vpc/examples/ex01-fw-vpc/main.tf
new file mode 100644
index 0000000..853d1ce
--- /dev/null
+++ b/modules/terraform-aws-nfw-vpc/examples/ex01-fw-vpc/main.tf
@@ -0,0 +1,31 @@
+# Copyright 2025 Cloudera, Inc. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+provider "aws" {
+ region = var.aws_region
+}
+
+module "ex01_network_vpc" {
+ source = "../.."
+
+ vpc_name = "${var.env_prefix}-network-vpc"
+ vpc_cidr = var.vpc_cidr
+
+ subnet_name_prefix = var.env_prefix
+ nat_gateway_name_prefix = var.env_prefix
+ route_table_name_prefix = var.env_prefix
+
+ tags = var.env_tags
+
+}
diff --git a/modules/terraform-aws-nfw-vpc/examples/ex01-fw-vpc/terraform.tfvars.sample b/modules/terraform-aws-nfw-vpc/examples/ex01-fw-vpc/terraform.tfvars.sample
new file mode 100644
index 0000000..c353723
--- /dev/null
+++ b/modules/terraform-aws-nfw-vpc/examples/ex01-fw-vpc/terraform.tfvars.sample
@@ -0,0 +1,23 @@
+# Copyright 2025 Cloudera, Inc. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# ------- Cloud Settings -------
+aws_region = "" # Change this to specify Cloud Provider region, e.g. eu-west-1
+
+env_prefix = ""
+
+# ------- VPC Settings -------
+
+vpc_cidr = "10.11.0.0/16" # Change CIDR value if needed
+
diff --git a/modules/terraform-aws-nfw-vpc/examples/ex01-fw-vpc/variables.tf b/modules/terraform-aws-nfw-vpc/examples/ex01-fw-vpc/variables.tf
new file mode 100644
index 0000000..e93f1ad
--- /dev/null
+++ b/modules/terraform-aws-nfw-vpc/examples/ex01-fw-vpc/variables.tf
@@ -0,0 +1,39 @@
+# Copyright 2025 Cloudera, Inc. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# ------- Global settings -------
+variable "aws_region" {
+ type = string
+ description = "Region which Cloud resources will be created"
+}
+
+variable "env_tags" {
+ type = map(any)
+ description = "Tags applied to provised resources"
+
+ default = null
+}
+
+variable "env_prefix" {
+ type = string
+ description = "Shorthand name to prefix on all resources."
+}
+
+# ------- Network Resources -------
+variable "vpc_cidr" {
+ type = string
+ description = "VPC CIDR Block. Required if create_vpc is true."
+
+}
+
diff --git a/modules/terraform-aws-nfw-vpc/main.tf b/modules/terraform-aws-nfw-vpc/main.tf
new file mode 100644
index 0000000..30aa32e
--- /dev/null
+++ b/modules/terraform-aws-nfw-vpc/main.tf
@@ -0,0 +1,177 @@
+# Copyright 2025 Cloudera, Inc. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# ------- VPC -------
+# Create the VPC
+resource "aws_vpc" "vpc" {
+ cidr_block = var.vpc_cidr
+ tags = merge({ Name = var.vpc_name })
+
+ enable_dns_support = var.enable_dns_support
+ enable_dns_hostnames = var.enable_dns_hostnames
+}
+
+# Internet Gateway
+resource "aws_internet_gateway" "igw" {
+ vpc_id = aws_vpc.vpc.id
+ tags = merge({ Name = "${var.vpc_name}-igw" })
+}
+
+# Public Route Table
+resource "aws_default_route_table" "default_rt" {
+ default_route_table_id = aws_vpc.vpc.default_route_table_id
+
+ route {
+ cidr_block = "0.0.0.0/0"
+ gateway_id = aws_internet_gateway.igw.id
+ }
+
+ tags = merge({ Name = "${var.route_table_name_prefix}-public-rtb" })
+
+}
+
+# ------- Subnets for Transit Gateway -------
+resource "aws_subnet" "tgw" {
+ for_each = { for idx, subnet in local.tgw_subnets : idx => subnet }
+
+ vpc_id = aws_vpc.vpc.id
+ cidr_block = each.value.cidr
+ map_public_ip_on_launch = false
+ availability_zone = each.value.az
+ tags = merge(var.tags, { Name = each.value.name })
+}
+
+# Route Tables for Transit Gateway subnets
+resource "aws_route_table" "tgw" {
+ for_each = { for idx, subnet in local.tgw_subnets : idx => subnet }
+
+ vpc_id = aws_vpc.vpc.id
+
+ tags = { Name = format("%s-%02d", "${var.route_table_name_prefix}-tgw-rtb", index(local.tgw_subnets, each.value)) }
+}
+
+# Associate the Transit Gateway Route Tables with the TGW Subnets
+resource "aws_route_table_association" "tgw" {
+
+ count = length(aws_subnet.tgw)
+
+ subnet_id = aws_subnet.tgw[count.index].id
+ route_table_id = aws_route_table.tgw[count.index].id
+}
+
+# ------- Subnets for Firewall -------
+resource "aws_subnet" "fw" {
+ for_each = { for idx, subnet in local.fw_subnets : idx => subnet }
+
+ vpc_id = aws_vpc.vpc.id
+ cidr_block = each.value.cidr
+ map_public_ip_on_launch = false
+ availability_zone = each.value.az
+ tags = merge(var.tags, { Name = each.value.name })
+}
+
+# Route Tables for Firewall subnets
+resource "aws_route_table" "fw" {
+ for_each = { for idx, subnet in local.fw_subnets : idx => subnet }
+
+ vpc_id = aws_vpc.vpc.id
+
+ tags = { Name = format("%s-%02d", "${var.route_table_name_prefix}-fw-rtb", index(local.fw_subnets, each.value)) }
+}
+
+# Associate the Firewall Route Tables with the Firewall Subnets
+resource "aws_route_table_association" "fw" {
+
+ count = length(aws_subnet.fw)
+
+ subnet_id = aws_subnet.fw[count.index].id
+ route_table_id = aws_route_table.fw[count.index].id
+}
+
+
+# ------- Subnets for NAT -------
+resource "aws_subnet" "nat" {
+ for_each = { for idx, subnet in local.nat_subnets : idx => subnet }
+
+ vpc_id = aws_vpc.vpc.id
+ cidr_block = each.value.cidr
+ map_public_ip_on_launch = false
+ availability_zone = each.value.az
+ tags = merge(var.tags, { Name = each.value.name })
+}
+
+# Route Tables for Firewall subnets
+resource "aws_route_table" "nat" {
+ for_each = { for idx, subnet in local.nat_subnets : idx => subnet }
+
+ vpc_id = aws_vpc.vpc.id
+
+ tags = { Name = format("%s-%02d", "${var.route_table_name_prefix}-nat-rtb", index(local.nat_subnets, each.value)) }
+}
+
+# Associate the Firewall Route Tables with the Firewall Subnets
+resource "aws_route_table_association" "nat" {
+
+ count = length(aws_subnet.nat)
+
+ subnet_id = aws_subnet.nat[count.index].id
+ route_table_id = aws_route_table.nat[count.index].id
+}
+
+
+# ------- NAT Gateway Configuration -------
+# Elastic IP for each NAT gateway
+resource "aws_eip" "nat_gateway_eip" {
+
+ for_each = { for idx, subnet in local.nat_subnets : idx => subnet }
+
+ domain = "vpc"
+ tags = { Name = format("%s-%s-%02d", "${var.nat_gateway_name_prefix}-ngw", "eip", index(local.nat_subnets, each.value) + 1) }
+}
+
+# Network Gateways (NAT) for each NAT subnet
+resource "aws_nat_gateway" "nat_gateway" {
+
+ count = length(aws_subnet.nat)
+
+ subnet_id = aws_subnet.nat[count.index].id
+ allocation_id = aws_eip.nat_gateway_eip[count.index].id
+ connectivity_type = "public"
+
+ tags = { Name = format("%s-%02d", "${var.nat_gateway_name_prefix}-ngw", count.index) }
+}
+
+# ------- Route Table Entries -------
+resource "aws_route" "fw_nat_rtb_rt" {
+
+ count = length(local.fw_subnets)
+ # count = length(var.public_nat_cidr_block)
+
+ route_table_id = aws_route_table.fw[count.index].id
+ destination_cidr_block = "0.0.0.0/0"
+
+ nat_gateway_id = element(aws_nat_gateway.nat_gateway[*].id, count.index)
+}
+
+# Route tables for NAT Subnets:
+# 0.0.0.0/0 -> IGW
+resource "aws_route" "nat_igw_rtb_rt" {
+
+ for_each = aws_route_table.nat
+
+ route_table_id = each.value.id
+ gateway_id = aws_internet_gateway.igw.id
+ destination_cidr_block = "0.0.0.0/0"
+
+}
diff --git a/modules/terraform-aws-nfw-vpc/outputs.tf b/modules/terraform-aws-nfw-vpc/outputs.tf
new file mode 100644
index 0000000..f96ee3a
--- /dev/null
+++ b/modules/terraform-aws-nfw-vpc/outputs.tf
@@ -0,0 +1,87 @@
+# Copyright 2025 Cloudera, Inc. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+output "vpc_id" {
+ description = "The ID of the VPC"
+ value = aws_vpc.vpc.id
+}
+
+output "vpc_cidr_blocks" {
+ value = try(aws_vpc.vpc.cidr_block, null)
+
+ description = "CIDR Block Associations for the VPC"
+}
+
+output "internet_gateway_id" {
+ value = aws_internet_gateway.igw.id
+ description = "The ID of the Internet Gateway"
+}
+
+output "default_route_table" {
+ value = aws_vpc.vpc.default_route_table_id
+ description = "The ID of the default route table"
+}
+
+# ------- Outputs related to TGW Subnets -------
+output "tgw_subnet_ids" {
+ value = values(aws_subnet.tgw)[*].id
+ description = "The IDs of Transit Gateway subnets"
+}
+
+output "tgw_subnets" {
+ value = values(aws_subnet.tgw)
+ description = "All details of the Transit Gateway subnets"
+}
+
+output "tgw_subnet_route_tables" {
+ value = values(aws_route_table.tgw)[*].id
+ description = "List of IDs of the routes tables associated with the Transit Gateway subnets"
+}
+
+# ------- Outputs related to Firewall Subnets -------
+output "fw_subnet_ids" {
+ value = values(aws_subnet.fw)[*].id
+ description = "The IDs of Firewall subnets"
+}
+
+output "fw_subnets" {
+ value = values(aws_subnet.fw)
+ description = "All details of the Firewall subnets"
+}
+
+output "fw_subnet_route_tables" {
+ value = values(aws_route_table.fw)[*].id
+ description = "List of IDs of the routes tables associated with the Firewall subnets"
+}
+
+# ------- Outputs related to NAT Subnets -------
+output "nat_subnet_ids" {
+ value = values(aws_subnet.nat)[*].id
+ description = "The IDs of NAT subnets"
+}
+
+output "nat_subnets" {
+ value = values(aws_subnet.nat)
+ description = "All details of the NAT subnets"
+}
+
+output "nat_subnet_route_tables" {
+ value = values(aws_route_table.nat)[*].id
+ description = "List of IDs of the routes tables associated with the NAT subnets"
+}
+
+output "nat_gateway_ids" {
+ value = aws_nat_gateway.nat_gateway[*].id
+ description = "List of IDs of the NAT Gateways"
+}
diff --git a/modules/terraform-aws-nfw-vpc/provider.tf b/modules/terraform-aws-nfw-vpc/provider.tf
new file mode 100644
index 0000000..3ae2eb9
--- /dev/null
+++ b/modules/terraform-aws-nfw-vpc/provider.tf
@@ -0,0 +1,24 @@
+# Copyright 2025 Cloudera, Inc. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+terraform {
+ required_providers {
+ aws = {
+ source = "hashicorp/aws"
+ version = ">= 5.30"
+ }
+ }
+
+ required_version = ">= 1.3.0"
+}
diff --git a/modules/terraform-aws-nfw-vpc/variables.tf b/modules/terraform-aws-nfw-vpc/variables.tf
new file mode 100644
index 0000000..08c74ac
--- /dev/null
+++ b/modules/terraform-aws-nfw-vpc/variables.tf
@@ -0,0 +1,96 @@
+# Copyright 2025 Cloudera, Inc. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+variable "vpc_name" {
+ type = string
+
+ description = "Name of the VPC"
+
+ validation {
+ condition = length(var.vpc_name) <= 64
+ error_message = "The length of vpc_name must be 64 characters or less."
+ }
+}
+
+variable "vpc_cidr" {
+ type = string
+ description = "VPC CIDR Block. Only used when create_vpc is true."
+
+}
+
+variable "subnet_name_prefix" {
+ type = string
+
+ description = "Prefix string for the name of all Subnets created"
+
+}
+
+variable "route_table_name_prefix" {
+ type = string
+
+ description = "Prefix string for the name of all Route Tables created"
+
+}
+
+variable "nat_gateway_name_prefix" {
+ type = string
+
+ description = "Prefix string for the name of all NAT Gateway resources"
+
+}
+
+variable "tgw_cidr_range" {
+ type = number
+ description = "Size of each Transit Gateway subnets."
+
+ default = 24
+}
+
+variable "fw_cidr_range" {
+ type = number
+ description = "Size of each Firewall subnets."
+
+ default = 24
+}
+
+variable "nat_cidr_range" {
+ type = number
+ description = "Size of each NAT subnets."
+
+ default = 24
+}
+
+variable "tags" {
+ type = map(any)
+ description = "Tags applied to VPC resources."
+
+ default = null
+}
+
+variable "enable_dns_support" {
+ type = bool
+ description = "Enable DNS support for the VPC. Only used when create_vpc is true."
+
+ default = true
+}
+
+variable "enable_dns_hostnames" {
+ type = bool
+ description = "Enable DNS Hostname support for the VPC. Only used when create_vpc is true."
+
+ default = true
+}
+
+
+