diff --git a/modules/terraform-aws-tgw/.terraform-docs.yaml b/modules/terraform-aws-tgw/.terraform-docs.yaml
new file mode 100644
index 0000000..0936036
--- /dev/null
+++ b/modules/terraform-aws-tgw/.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-tgw/README.md b/modules/terraform-aws-tgw/README.md
new file mode 100644
index 0000000..d1c2880
--- /dev/null
+++ b/modules/terraform-aws-tgw/README.md
@@ -0,0 +1,70 @@
+
+# Terraform Module for AWS Transit Gateway
+
+This module contains resource files and example variable definition files for creation of AWS Transity Gateway (TGW) and attaching a specified list of VPCs via the TGW. This module also updates both the Transit Gateway and VPC route tables. 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.
+
+## Usage
+
+The [examples](./examples) directory has example of using this module:
+
+* `ex01-vpc-tgw-attach` demonstrates how this module can be used to use a Transit Gateway to attach a private CDP VPC with a dedicated networking VPC. The [terraform-aws-vpc](../../../terraform-aws-vpc/README.md) module is also used as part of this example.
+
+The README and sample `terraform.tfvars.sample` describe how to use the example.
+
+## Requirements
+
+| Name | Version |
+|------|---------|
+| [terraform](#requirement\_terraform) | > 1.3.0 |
+| [aws](#requirement\_aws) | ~> 4.0 |
+
+## Providers
+
+| Name | Version |
+|------|---------|
+| [aws](#provider\_aws) | ~> 4.0 |
+
+## Modules
+
+No modules.
+
+## Resources
+
+| Name | Type |
+|------|------|
+| [aws_ec2_transit_gateway.tgw](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ec2_transit_gateway) | resource |
+| [aws_ec2_transit_gateway_route.tgw_routes](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ec2_transit_gateway_route) | resource |
+| [aws_ec2_transit_gateway_route_table.tgw_rt](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ec2_transit_gateway_route_table) | resource |
+| [aws_ec2_transit_gateway_route_table_association.tgw_rt_assoc](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ec2_transit_gateway_route_table_association) | resource |
+| [aws_ec2_transit_gateway_route_table_propagation.tgw_rt_propag](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ec2_transit_gateway_route_table_propagation) | resource |
+| [aws_ec2_transit_gateway_vpc_attachment.tgw_vpc_attach](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ec2_transit_gateway_vpc_attachment) | resource |
+| [aws_route.vpc_tgw_route](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route) | resource |
+
+## Inputs
+
+| Name | Description | Type | Default | Required |
+|------|-------------|------|---------|:--------:|
+| [tgw\_name](#input\_tgw\_name) | Name of the Transit Gateway. Also used to prefix associated TGW resource names. | `string` | n/a | yes |
+| [env\_tags](#input\_env\_tags) | Tags applied to provisioned resources | `map(any)` | `null` | no |
+| [tgw\_default\_route\_table\_association](#input\_tgw\_default\_route\_table\_association) | Automatically associate resource attachments with the default TGW association route table. Valid values are 'enable' or 'disable' | `string` | `"disable"` | no |
+| [tgw\_default\_route\_table\_propagation](#input\_tgw\_default\_route\_table\_propagation) | Automatically propagate resource attachments with the default TGW propagation route table. Valid values are 'enable' or 'disable' | `string` | `"disable"` | no |
+| [tgw\_dns\_support](#input\_tgw\_dns\_support) | Enable DNS support for the Transit Gateway. Valid values are 'enable' or 'disable' | `string` | `"enable"` | no |
+| [tgw\_vpn\_ecmp\_support](#input\_tgw\_vpn\_ecmp\_support) | Enable VPN Equal Cost Multipath Protocol support for the Transit Gateway. Valid values are 'enable' or 'disable' | `string` | `"enable"` | no |
+| [vpc\_attach\_dns\_support](#input\_vpc\_attach\_dns\_support) | Default behaviour for the VPC Attachment dns\_support parameter if not specified in var.vpc\_attachments | `string` | `"enable"` | no |
+| [vpc\_attach\_tgw\_default\_route\_table\_association](#input\_vpc\_attach\_tgw\_default\_route\_table\_association) | Default behaviour for the VPC Attachment transit\_gateway\_default\_route\_table\_association parameter if not specified in var.vpc\_attachments | `bool` | `false` | no |
+| [vpc\_attach\_tgw\_default\_route\_table\_propagation](#input\_vpc\_attach\_tgw\_default\_route\_table\_propagation) | Default behaviour for the VPC Attachment transit\_gateway\_default\_route\_table\_propagation parameter if not specified in var.vpc\_attachments | `bool` | `false` | no |
+| [vpc\_attachments](#input\_vpc\_attachments) | Map of map of VPC details to attach to the Transit Gateway. Type any to avoid validation on map key but should at least contain the vpc id and subnet id for the TGW attachment. | `any` | `{}` | no |
+
+## Outputs
+
+| Name | Description |
+|------|-------------|
+| [transit\_gateway\_arn](#output\_transit\_gateway\_arn) | Transit Gateway Amazon Resource Name (ARN) |
+| [transit\_gateway\_association\_default\_route\_table\_id](#output\_transit\_gateway\_association\_default\_route\_table\_id) | ID of the default association route table |
+| [transit\_gateway\_id](#output\_transit\_gateway\_id) | Transit Gateway identifier |
+| [transit\_gateway\_propagation\_default\_route\_table\_id](#output\_transit\_gateway\_propagation\_default\_route\_table\_id) | ID of the default propagation route table |
+| [transit\_gateway\_route\_table\_details](#output\_transit\_gateway\_route\_table\_details) | Map of Transit Gateway Route Table attributes |
+| [transit\_gateway\_route\_table\_ids](#output\_transit\_gateway\_route\_table\_ids) | List of Transit Gateway Route Tables |
+| [transit\_gateway\_vpc\_attachment\_details](#output\_transit\_gateway\_vpc\_attachment\_details) | Map of Transit Gateway VPC Attachment attributes |
+| [transit\_gateway\_vpc\_attachment\_ids](#output\_transit\_gateway\_vpc\_attachment\_ids) | List of Transit Gateway VPC Attachment identifiers |
+
\ No newline at end of file
diff --git a/modules/terraform-aws-tgw/defaults.tf b/modules/terraform-aws-tgw/defaults.tf
new file mode 100644
index 0000000..b39e2c9
--- /dev/null
+++ b/modules/terraform-aws-tgw/defaults.tf
@@ -0,0 +1,49 @@
+# Copyright 2023 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 local for transit gateway route table entries
+ vpc_attachment_with_tgw_routes = flatten([
+ for attach, attach_value in var.vpc_attachments :
+ [
+ for route in attach_value.tgw_routes :
+ {
+ create_tgw_route_table = attach_value.create_tgw_route_table
+ route_table_key = attach
+ route_attachement_key = route.route_attachment_key
+ destination_cidr_block = route.destination_cidr_block
+ }
+ ]
+ if can(attach_value.tgw_routes)
+ ])
+
+ vpc_attachment_with_vpc_routes = flatten([
+ for attach, attach_value in var.vpc_attachments :
+ [
+ for route in try(attach_value.vpc_routes, []) :
+ [
+ for rt in try(route.route_tables, []) :
+ {
+ create_vpc_routes = attach_value.create_vpc_routes
+ route_table = rt
+ attachement_key = attach
+ destination_cidr_block = route.destination_cidr_block
+ }
+ ]
+ ]
+ if(can(attach_value.vpc_routes) && try(attach_value.create_vpc_routes, false))
+ ])
+
+}
\ No newline at end of file
diff --git a/modules/terraform-aws-tgw/doc_fragments/header.md b/modules/terraform-aws-tgw/doc_fragments/header.md
new file mode 100644
index 0000000..e1fba47
--- /dev/null
+++ b/modules/terraform-aws-tgw/doc_fragments/header.md
@@ -0,0 +1,11 @@
+# Terraform Module for AWS Transit Gateway
+
+This module contains resource files and example variable definition files for creation of AWS Transity Gateway (TGW) and attaching a specified list of VPCs via the TGW. This module also updates both the Transit Gateway and VPC route tables. 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.
+
+## Usage
+
+The [examples](./examples) directory has example of using this module:
+
+* `ex01-vpc-tgw-attach` demonstrates how this module can be used to use a Transit Gateway to attach a private CDP VPC with a dedicated networking VPC. The [terraform-aws-vpc](../../../terraform-aws-vpc/README.md) module is also used as part of this example.
+
+The README and sample `terraform.tfvars.sample` describe how to use the example.
diff --git a/modules/terraform-aws-tgw/examples/ex01-vpc-tgw-attach/README.md b/modules/terraform-aws-tgw/examples/ex01-vpc-tgw-attach/README.md
new file mode 100644
index 0000000..55ca8df
--- /dev/null
+++ b/modules/terraform-aws-tgw/examples/ex01-vpc-tgw-attach/README.md
@@ -0,0 +1,72 @@
+# Notes on this example
+
+This example is split into two steps - the first step to create two VPCs (using the [terraform-aws-vpc](../../../terraform-aws-vpc/README.md) module); the second step to create the Transit Gateway and attach the VPCs from step 1 to the TGW.
+
+The reason for the split in deployment steps is due to the dependencies between VPC and Transit Gateway configurations (mainly the number of VPC route tables are not known at plan time).
+
+## Steps to execute the example
+
+* Copy the example variables file, `terraform.tfvars.sample`, to `terraform.tfvars` and edit as needed. This same variable input file will be used across all deployment steps.
+
+```bash
+# Copy the sample input variable file
+cp terraform.tfvars.sample terraform.tfvars
+
+# Edit
+vi terraform.tfvars
+```
+
+* Execute _Step 1_ to create the VPCs.
+
+```bash
+# change to the root module directory for step1
+cd step1_vpcs
+
+# Initialise the deployment
+terraform init
+
+# plan to review the infra changes
+terraform plan -var-file ../terraform.tfvars
+
+# apply the infra changes
+terraform apply -var-file ../terraform.tfvars
+```
+
+* Execute _Step 2_ to create the Transit Gateway and VPC attachments.
+
+```bash
+# change to the root module directory for step2 (command relative to the step1_vpcs directory)
+cd ../step2_tgw
+
+# Initialise the deployment
+terraform init
+
+# plan to review the infra changes
+terraform plan -var-file ../terraform.tfvars
+
+# apply the infra changes
+terraform apply -var-file ../terraform.tfvars
+```
+## Steps to clean up the example resources
+
+To remove all resources created by this example, work in reverse order to the setup workflow.
+
+* Change to the _Step 2_ directory and run Terraform destroy to delete the TGW and VPC Attachments
+
+ ```bash
+ # change to the root module directory for step2
+ cd /step2_tgw
+
+ # destroy terraform created resources
+ terraform destroy -var-file ../terraform.tfvars
+ ```
+
+* Change to the _Step 1_ directory to remove the Networking and CDP VPCs.
+
+ ```bash
+ # change to the root module directory for step1
+ cd ../step1_vpcs
+
+ # destroy terraform created resources
+ terraform destroy -var-file ../terraform.tfvars
+ ```
\ No newline at end of file
diff --git a/modules/terraform-aws-tgw/examples/ex01-vpc-tgw-attach/step1_vpcs/main.tf b/modules/terraform-aws-tgw/examples/ex01-vpc-tgw-attach/step1_vpcs/main.tf
new file mode 100644
index 0000000..c93cb3b
--- /dev/null
+++ b/modules/terraform-aws-tgw/examples/ex01-vpc-tgw-attach/step1_vpcs/main.tf
@@ -0,0 +1,46 @@
+# Copyright 2023 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" {
+ profile = var.aws_profile
+ region = var.aws_region
+}
+
+module "ex01_cdp_vpc" {
+ source = "../../../../terraform-aws-vpc"
+
+ deployment_template = "private"
+ vpc_name = "${var.name_prefix}-cdp-vpc"
+ vpc_cidr = "10.10.0.0/16"
+ private_network_extensions = false
+
+ tags = var.env_tags
+
+ private_cidr_range = var.cdp_vpc_private_cidr_range
+ public_cidr_range = var.cdp_vpc_public_cidr_range
+
+}
+
+module "ex01_network_vpc" {
+ source = "../../../../terraform-aws-vpc"
+
+ cdp_vpc = false
+ vpc_name = "${var.name_prefix}-network-vpc"
+ vpc_cidr = "10.11.0.0/16"
+ enable_nat_gateway = false
+
+ private_cidr_range = var.network_vpc_private_cidr_range
+ public_cidr_range = var.network_vpc_public_cidr_range
+
+}
diff --git a/modules/terraform-aws-tgw/examples/ex01-vpc-tgw-attach/step1_vpcs/outputs.tf b/modules/terraform-aws-tgw/examples/ex01-vpc-tgw-attach/step1_vpcs/outputs.tf
new file mode 100644
index 0000000..00b226e
--- /dev/null
+++ b/modules/terraform-aws-tgw/examples/ex01-vpc-tgw-attach/step1_vpcs/outputs.tf
@@ -0,0 +1,46 @@
+# Copyright 2023 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 "ex01_cdp_vpc_id" {
+ value = module.ex01_cdp_vpc.vpc_id
+}
+output "ex01_cdp_private_subnet_ids" {
+ value = module.ex01_cdp_vpc.private_subnets
+}
+output "ex01_cdp_public_subnet_ids" {
+ value = module.ex01_cdp_vpc.public_subnets
+}
+output "ex01_cdp_private_route_table_ids" {
+ value = module.ex01_cdp_vpc.private_route_tables
+}
+output "ex01_cdp_public_route_table_ids" {
+ value = module.ex01_cdp_vpc.public_route_tables
+}
+
+
+output "ex01_network_vpc_id" {
+ value = module.ex01_network_vpc.vpc_id
+}
+output "ex01_network_private_subnet_ids" {
+ value = module.ex01_network_vpc.private_subnets
+}
+output "ex01_network_public_subnet_ids" {
+ value = module.ex01_network_vpc.public_subnets
+}
+output "ex01_network_private_route_table_ids" {
+ value = module.ex01_network_vpc.private_route_tables
+}
+output "ex01_network_public_route_table_ids" {
+ value = module.ex01_network_vpc.public_route_tables
+}
\ No newline at end of file
diff --git a/modules/terraform-aws-tgw/examples/ex01-vpc-tgw-attach/step1_vpcs/variables.tf b/modules/terraform-aws-tgw/examples/ex01-vpc-tgw-attach/step1_vpcs/variables.tf
new file mode 100644
index 0000000..28e374e
--- /dev/null
+++ b/modules/terraform-aws-tgw/examples/ex01-vpc-tgw-attach/step1_vpcs/variables.tf
@@ -0,0 +1,67 @@
+# Copyright 2023 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_profile" {
+ type = string
+ description = "Profile for AWS cloud credentials"
+
+ # Profile is default unless explicitly specified
+ default = "default"
+}
+
+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."
+}
+
+variable "cdp_vpc_private_cidr_range" {
+ type = number
+ description = "Size of each private subnet for CDP VPC."
+
+ default = 19
+}
+
+variable "cdp_vpc_public_cidr_range" {
+ type = number
+ description = "Size of each public subnet for CDP VPC."
+
+ default = 24
+}
+
+variable "network_vpc_private_cidr_range" {
+ type = number
+ description = "Size of each private subnet for Network VPC."
+
+ default = 19
+}
+
+variable "network_vpc_public_cidr_range" {
+ type = number
+ description = "Size of each public subnet for Network VPC."
+
+ default = 24
+}
\ No newline at end of file
diff --git a/modules/terraform-aws-tgw/examples/ex01-vpc-tgw-attach/step2_tgw/main.tf b/modules/terraform-aws-tgw/examples/ex01-vpc-tgw-attach/step2_tgw/main.tf
new file mode 100644
index 0000000..fcdc36a
--- /dev/null
+++ b/modules/terraform-aws-tgw/examples/ex01-vpc-tgw-attach/step2_tgw/main.tf
@@ -0,0 +1,76 @@
+# Copyright 2023 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.
+
+# Read remote state from step1
+data "terraform_remote_state" "step1" {
+ backend = "local"
+
+ config = {
+ path = "../step1_vpcs/terraform.tfstate"
+ }
+}
+
+provider "aws" {
+ profile = var.aws_profile
+ region = var.aws_region
+}
+
+# Use terraform_remote_state to retrieve CDP VPC details from step01
+data "aws_vpc" "cdp_vpc_info" {
+ id = data.terraform_remote_state.step1.outputs.ex01_cdp_vpc_id
+}
+
+module "ex01_tgw_basic" {
+ source = "../../.."
+
+ tgw_name = "${var.name_prefix}-tgw"
+
+ vpc_attachments = {
+ cdp_vpc = {
+ vpc_id = data.terraform_remote_state.step1.outputs.ex01_cdp_vpc_id
+ subnet_ids = data.terraform_remote_state.step1.outputs.ex01_cdp_private_subnet_ids
+ rt_propagation_key = "network_vpc" # the vpc attachment key for the TGW Route Table association & propagation
+ create_tgw_route_table = true # create a dedicated TGW RT for the VPC attachment
+ tgw_routes = [ # List of TGW Routes to add
+ {
+ destination_cidr_block = "0.0.0.0/0" # Destination CIDR
+ route_attachment_key = "network_vpc" # vpc attachment key
+ }
+ ]
+ create_vpc_routes = true
+ vpc_routes = [ # List of VPC Route Tables to update with TGW entry
+ # Route all 0.0.0.0/0 traffic to Transit Gateway for all private subnet route tables in CDP VPC
+ {
+ route_tables = data.terraform_remote_state.step1.outputs.ex01_cdp_private_route_table_ids
+ destination_cidr_block = "0.0.0.0/0"
+ }
+ ]
+ },
+ network_vpc = {
+ vpc_id = data.terraform_remote_state.step1.outputs.ex01_network_vpc_id
+ subnet_ids = data.terraform_remote_state.step1.outputs.ex01_network_private_subnet_ids
+ rt_propagation_key = "cdp_vpc"
+ create_tgw_route_table = true # create a dedicated TGW RT for the VPC attachment
+ create_vpc_routes = true
+ vpc_routes = [
+ # All private subnet route tables will redirect CDP VPC CIDR traffic to Transit Gateway
+ {
+ route_tables = concat(data.terraform_remote_state.step1.outputs.ex01_network_private_route_table_ids, data.terraform_remote_state.step1.outputs.ex01_network_public_route_table_ids)
+ destination_cidr_block = data.aws_vpc.cdp_vpc_info.cidr_block_associations[0].cidr_block
+ }
+ ]
+ }
+ }
+
+}
diff --git a/modules/terraform-aws-tgw/examples/ex01-vpc-tgw-attach/step2_tgw/variables.tf b/modules/terraform-aws-tgw/examples/ex01-vpc-tgw-attach/step2_tgw/variables.tf
new file mode 100644
index 0000000..366836b
--- /dev/null
+++ b/modules/terraform-aws-tgw/examples/ex01-vpc-tgw-attach/step2_tgw/variables.tf
@@ -0,0 +1,40 @@
+# Copyright 2023 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_profile" {
+ type = string
+ description = "Profile for AWS cloud credentials"
+
+ # Profile is default unless explicitly specified
+ default = "default"
+}
+
+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."
+}
+
diff --git a/modules/terraform-aws-tgw/examples/ex01-vpc-tgw-attach/terraform.tfvars.sample b/modules/terraform-aws-tgw/examples/ex01-vpc-tgw-attach/terraform.tfvars.sample
new file mode 100644
index 0000000..5de6746
--- /dev/null
+++ b/modules/terraform-aws-tgw/examples/ex01-vpc-tgw-attach/terraform.tfvars.sample
@@ -0,0 +1,19 @@
+# Copyright 2023 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
diff --git a/modules/terraform-aws-tgw/main.tf b/modules/terraform-aws-tgw/main.tf
new file mode 100644
index 0000000..5d43bb0
--- /dev/null
+++ b/modules/terraform-aws-tgw/main.tf
@@ -0,0 +1,113 @@
+# Copyright 2023 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.
+
+# ------- Transit Gateway & VPC Attachments -------
+# Create Transit Gateway
+resource "aws_ec2_transit_gateway" "tgw" {
+ description = "Transit Gateway for ${var.tgw_name}"
+
+ dns_support = var.tgw_dns_support
+ vpn_ecmp_support = var.tgw_vpn_ecmp_support
+
+ default_route_table_association = var.tgw_default_route_table_association
+ default_route_table_propagation = var.tgw_default_route_table_propagation
+
+ tags = merge(var.env_tags, { Name = var.tgw_name })
+}
+
+# Attach specified VPCs to TGW
+resource "aws_ec2_transit_gateway_vpc_attachment" "tgw_vpc_attach" {
+
+ for_each = var.vpc_attachments
+
+ transit_gateway_id = aws_ec2_transit_gateway.tgw.id
+ vpc_id = each.value.vpc_id
+ subnet_ids = each.value.subnet_ids
+
+ transit_gateway_default_route_table_association = try(each.value.tgw_default_route_table_association, var.vpc_attach_tgw_default_route_table_association)
+ transit_gateway_default_route_table_propagation = try(each.value.tgw_default_route_table_propagation, var.vpc_attach_tgw_default_route_table_propagation)
+
+ dns_support = try(each.value.dns_support, var.vpc_attach_dns_support)
+
+ tags = merge(var.env_tags, { Name = "${var.tgw_name}-attach-${each.key}" })
+}
+
+# ------- Transit Gateway Route Table -------
+# Transit Gateway Route Table
+resource "aws_ec2_transit_gateway_route_table" "tgw_rt" {
+
+ for_each = {
+ for k, v in var.vpc_attachments : k => v
+ if try(v.create_tgw_route_table, false) == true
+ }
+
+ transit_gateway_id = aws_ec2_transit_gateway.tgw.id
+
+ tags = merge(var.env_tags, { Name = "${var.tgw_name}-rtb-${each.key}" })
+}
+
+# Create Association to route traffic.
+resource "aws_ec2_transit_gateway_route_table_association" "tgw_rt_assoc" {
+
+ for_each = {
+ for k, v in var.vpc_attachments : k => v
+ if try(v.create_tgw_route_table, false) == true
+ }
+
+ transit_gateway_attachment_id = aws_ec2_transit_gateway_vpc_attachment.tgw_vpc_attach[each.key].id
+ transit_gateway_route_table_id = aws_ec2_transit_gateway_route_table.tgw_rt[each.key].id
+}
+
+# Create Propagations to route traffic.
+resource "aws_ec2_transit_gateway_route_table_propagation" "tgw_rt_propag" {
+
+ for_each = {
+ for k, v in var.vpc_attachments : k => v
+ if try(v.create_tgw_route_table, false) == true
+ }
+
+ transit_gateway_attachment_id = aws_ec2_transit_gateway_vpc_attachment.tgw_vpc_attach[each.value.rt_propagation_key].id
+ transit_gateway_route_table_id = aws_ec2_transit_gateway_route_table.tgw_rt[each.key].id
+}
+
+# Create Static Transit Gateway Route Table Entries
+resource "aws_ec2_transit_gateway_route" "tgw_routes" {
+
+ for_each = {
+ for k, v in local.vpc_attachment_with_tgw_routes : k => v
+ if try(v.create_tgw_route_table, true) == true
+ }
+
+ destination_cidr_block = each.value.destination_cidr_block
+ transit_gateway_attachment_id = aws_ec2_transit_gateway_vpc_attachment.tgw_vpc_attach[each.value.route_attachement_key].id
+
+ transit_gateway_route_table_id = aws_ec2_transit_gateway_route_table.tgw_rt[each.value.route_table_key].id
+}
+
+# ------- VPC Route Table -------
+# VPC Route Tables entries
+resource "aws_route" "vpc_tgw_route" {
+ for_each = {
+ for k, v in local.vpc_attachment_with_vpc_routes : k => v
+ if try(v.create_vpc_routes, false) == true
+ }
+
+ route_table_id = each.value.route_table
+ destination_cidr_block = each.value.destination_cidr_block
+ transit_gateway_id = aws_ec2_transit_gateway.tgw.id
+}
+
+# output "vpc_attachment_with_vpc_routes" {
+# value = local.vpc_attachment_with_vpc_routes
+# }
\ No newline at end of file
diff --git a/modules/terraform-aws-tgw/outputs.tf b/modules/terraform-aws-tgw/outputs.tf
new file mode 100644
index 0000000..fabf37b
--- /dev/null
+++ b/modules/terraform-aws-tgw/outputs.tf
@@ -0,0 +1,58 @@
+# Copyright 2023 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.
+
+# TGW
+
+output "transit_gateway_id" {
+ description = "Transit Gateway identifier"
+ value = aws_ec2_transit_gateway.tgw.id
+}
+
+output "transit_gateway_arn" {
+ description = "Transit Gateway Amazon Resource Name (ARN)"
+ value = aws_ec2_transit_gateway.tgw.arn
+}
+
+output "transit_gateway_association_default_route_table_id" {
+ description = "ID of the default association route table"
+ value = aws_ec2_transit_gateway.tgw.association_default_route_table_id
+}
+
+output "transit_gateway_propagation_default_route_table_id" {
+ description = "ID of the default propagation route table"
+ value = aws_ec2_transit_gateway.tgw.propagation_default_route_table_id
+}
+
+# VPC Attachment
+
+output "transit_gateway_vpc_attachment_ids" {
+ description = "List of Transit Gateway VPC Attachment identifiers"
+ value = [for k, v in aws_ec2_transit_gateway_vpc_attachment.tgw_vpc_attach : v.id]
+}
+
+output "transit_gateway_vpc_attachment_details" {
+ description = "Map of Transit Gateway VPC Attachment attributes"
+ value = aws_ec2_transit_gateway_vpc_attachment.tgw_vpc_attach
+}
+
+# TGW Route Tables
+output "transit_gateway_route_table_ids" {
+ description = "List of Transit Gateway Route Tables"
+ value = [for k, v in aws_ec2_transit_gateway_route_table.tgw_rt : v.id]
+}
+
+output "transit_gateway_route_table_details" {
+ description = "Map of Transit Gateway Route Table attributes"
+ value = aws_ec2_transit_gateway_route_table.tgw_rt
+}
diff --git a/modules/terraform-aws-tgw/provider.tf b/modules/terraform-aws-tgw/provider.tf
new file mode 100644
index 0000000..d45eadd
--- /dev/null
+++ b/modules/terraform-aws-tgw/provider.tf
@@ -0,0 +1,24 @@
+# Copyright 2023 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 = "~> 4.0"
+ }
+ }
+
+ required_version = "> 1.3.0"
+}
diff --git a/modules/terraform-aws-tgw/variables.tf b/modules/terraform-aws-tgw/variables.tf
new file mode 100644
index 0000000..9992e30
--- /dev/null
+++ b/modules/terraform-aws-tgw/variables.tf
@@ -0,0 +1,133 @@
+# Copyright 2023 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 "tgw_name" {
+ type = string
+ description = "Name of the Transit Gateway. Also used to prefix associated TGW resource names."
+}
+
+
+variable "env_tags" {
+ type = map(any)
+ description = "Tags applied to provisioned resources"
+
+ default = null
+}
+
+# ------- TGW Settings -------
+variable "tgw_dns_support" {
+ type = string
+
+ description = "Enable DNS support for the Transit Gateway. Valid values are 'enable' or 'disable'"
+
+ validation {
+ condition = contains(["enable", "disable"], var.tgw_dns_support)
+ error_message = "Valid values for var: tgw_dns_support are (enable, disable)."
+ }
+
+ default = "enable"
+}
+
+variable "tgw_vpn_ecmp_support" {
+ type = string
+
+ description = "Enable VPN Equal Cost Multipath Protocol support for the Transit Gateway. Valid values are 'enable' or 'disable'"
+
+ validation {
+ condition = contains(["enable", "disable"], var.tgw_vpn_ecmp_support)
+ error_message = "Valid values for var: tgw_vpn_ecmp_support are (enable, disable)."
+ }
+
+ default = "enable"
+}
+
+variable "tgw_default_route_table_association" {
+ type = string
+
+ description = "Automatically associate resource attachments with the default TGW association route table. Valid values are 'enable' or 'disable'"
+
+ validation {
+ condition = contains(["enable", "disable"], var.tgw_default_route_table_association)
+ error_message = "Valid values for var: tgw_default_route_table_association are (enable, disable)."
+ }
+
+ default = "disable"
+}
+
+variable "tgw_default_route_table_propagation" {
+ type = string
+
+ description = "Automatically propagate resource attachments with the default TGW propagation route table. Valid values are 'enable' or 'disable'"
+
+ validation {
+ condition = contains(["enable", "disable"], var.tgw_default_route_table_propagation)
+ error_message = "Valid values for var: tgw_default_route_table_propagation are (enable, disable)."
+ }
+
+ default = "disable"
+}
+
+# ------- VPC Attachment settings -------
+variable "vpc_attachments" {
+ type = any
+
+ description = "Map of map of VPC details to attach to the Transit Gateway. Type any to avoid validation on map key but should at least contain the vpc id and subnet id for the TGW attachment."
+
+ default = {}
+
+ # example:
+ # vpc1 = { # <-- key name to identify vpc attachment
+ # vpc_id = # <-- the vpc_id
+ # subnet_ids = # <-- the subnet_ids
+ # create_tgw_route_table # <-- create a separate TGW Route Table for this VPC attachment
+ # },
+ # vpc 2 = {
+ # vpc_id =
+ # subnet_ids =
+ # }
+
+}
+
+variable "vpc_attach_tgw_default_route_table_association" {
+ type = bool
+
+ description = "Default behaviour for the VPC Attachment transit_gateway_default_route_table_association parameter if not specified in var.vpc_attachments"
+
+ default = false
+
+}
+
+variable "vpc_attach_tgw_default_route_table_propagation" {
+ type = bool
+
+ description = "Default behaviour for the VPC Attachment transit_gateway_default_route_table_propagation parameter if not specified in var.vpc_attachments"
+
+ default = false
+
+}
+
+variable "vpc_attach_dns_support" {
+ type = string
+
+ description = "Default behaviour for the VPC Attachment dns_support parameter if not specified in var.vpc_attachments"
+
+ validation {
+ condition = contains(["enable", "disable"], var.vpc_attach_dns_support)
+ error_message = "Valid values for var: vpc_attach_dns_support are (enable, disable)."
+ }
+
+ default = "enable"
+
+}
\ No newline at end of file