diff --git a/README.md b/README.md
index 9238a57..ff905a0 100644
--- a/README.md
+++ b/README.md
@@ -340,11 +340,13 @@ Please see our [developer documentation](https://github.com/aws-ia/terraform-aws
| [aws_route.ipv6_private_to_tgw](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route) | resource |
| [aws_route.ipv6_public_to_cwan](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route) | resource |
| [aws_route.ipv6_public_to_tgw](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route) | resource |
+| [aws_route.private_subnets_custom_route_to_tgw](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route) | resource |
| [aws_route.private_to_cwan](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route) | resource |
| [aws_route.private_to_egress_only](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route) | resource |
| [aws_route.private_to_nat](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route) | resource |
| [aws_route.private_to_tgw](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route) | resource |
| [aws_route.public_ipv6_to_igw](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route) | resource |
+| [aws_route.public_subnets_custom_route_to_tgw](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route) | resource |
| [aws_route.public_to_cwan](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route) | resource |
| [aws_route.public_to_igw](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route) | resource |
| [aws_route.public_to_tgw](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route) | resource |
@@ -377,6 +379,7 @@ Please see our [developer documentation](https://github.com/aws-ia/terraform-aws
| [core\_network](#input\_core\_network) | AWS Cloud WAN's core network information - to create a VPC attachment. Required when `cloud_wan` subnet is defined. Two attributes are required: the `id` and `arn` of the resource. |
object({
id = string
arn = string
})
| {
"arn": null,
"id": null
}
| no |
| [core\_network\_ipv6\_routes](#input\_core\_network\_ipv6\_routes) | Configuration of IPv6 route(s) to AWS Cloud WAN's core network.
For each `public` and/or `private` subnets named in the `subnets` variable, optionally create routes from the subnet to the core network.
You can specify either a CIDR range or a prefix-list-id that you want routed to the core network.
Example:core_network_ivp6_routes = {
public = "::/0"
private = "pl-123"
}
| `any` | `{}` | no |
| [core\_network\_routes](#input\_core\_network\_routes) | Configuration of route(s) to AWS Cloud WAN's core network.
For each `public` and/or `private` subnets named in the `subnets` variable, optionally create routes from the subnet to the core network.
You can specify either a CIDR range or a prefix-list-id that you want routed to the core network.
Example:core_network_routes = {
public = "10.0.0.0/8"
private = "pl-123"
}
| `any` | `{}` | no |
+| [custom\_route\_to\_tgw](#input\_custom\_route\_to\_tgw) | Add a custom route to a transit gateway in a subnet.
The subnet is determined based on a map key that matches the key
provided in the var.subnets variable. This allows you to define
the specific subnet where the custom route should be applied.
Example:subnets = {
# Dual-stack subnet
public = {
netmask = 24
assign_ipv6_cidr = true
nat_gateway_configuration = "single_az"
}
# IPv4 only subnet
private = {
netmask = 24
connect_to_public_natgw = true
}
}
custom_route_to_tgw = {
private = {
destination_cidr_block = "10.0.0.0/16"
transit_gateway_id = "tgw-0282179847129898sd"
}
}
| map(object({
destination_cidr_block = optional(string)
destination_prefix_list_id = optional(string)
transit_gateway_id = string
}))
| `{}` | no |
| [tags](#input\_tags) | Tags to apply to all resources. | `map(string)` | `{}` | no |
| [transit\_gateway\_id](#input\_transit\_gateway\_id) | Transit gateway id to attach the VPC to. Required when `transit_gateway` subnet is defined. | `string` | `null` | no |
| [transit\_gateway\_ipv6\_routes](#input\_transit\_gateway\_ipv6\_routes) | Configuration of IPv6 route(s) to transit gateway.
For each `public` and/or `private` subnets named in the `subnets` variable,
Optionally create routes from the subnet to transit gateway. Specify the CIDR range or a prefix-list-id that you want routed to the transit gateway.
Example:transit_gateway_ipv6_routes = {
public = "::/0"
private = "pl-123"
}
| `any` | `{}` | no |
diff --git a/data.tf b/data.tf
index 3b17778..c339111 100644
--- a/data.tf
+++ b/data.tf
@@ -27,6 +27,16 @@ locals {
# constructed list of /az
private_per_az = flatten([for az in local.azs : [for subnet in local.private_subnet_names : "${subnet}/${az}"]])
+ # List of private subnets names where will be added a route to a TGW.
+ # The tricky part here is that we have to identify the subnet names where a route
+ # should be added because the subnet name has suffix /az in the name.
+ custom_route_to_tgw_subnet_names = flatten([
+ for subnet_name, _ in var.custom_route_to_tgw :
+ [
+ for subnet_name_az in local.private_per_az :
+ subnet_name_az if startswith(subnet_name_az, "${subnet_name}/")
+ ]
+ ])
# list of private subnet keys with connect_to_public_natgw = true
private_subnets_nat_routed = [for type in local.private_subnet_names : type if try(var.subnets[type].connect_to_public_natgw == true, false)]
# private subnets with cidrs per az if connect_to_public_natgw = true ... "privatetwo/us-east-1a"
diff --git a/main.tf b/main.tf
index a99757c..d94082f 100644
--- a/main.tf
+++ b/main.tf
@@ -305,6 +305,26 @@ resource "aws_route" "private_to_tgw" {
]
}
+resource "aws_route" "private_subnets_custom_route_to_tgw" {
+ for_each = toset(local.custom_route_to_tgw_subnet_names)
+
+ destination_cidr_block = var.custom_route_to_tgw[split("/", each.key)[0]].destination_cidr_block
+ destination_prefix_list_id = var.custom_route_to_tgw[split("/", each.key)[0]].destination_prefix_list_id
+
+ route_table_id = aws_route_table.private[each.key].id
+ transit_gateway_id = var.custom_route_to_tgw[split("/", each.key)[0]].transit_gateway_id
+}
+
+resource "aws_route" "public_subnets_custom_route_to_tgw" {
+ for_each = lookup(var.custom_route_to_tgw, "public", null) != null ? toset(local.azs) : toset([])
+
+ destination_cidr_block = var.custom_route_to_tgw["public"].destination_cidr_block
+ destination_prefix_list_id = var.custom_route_to_tgw["public"].destination_prefix_list_id
+
+ route_table_id = aws_route_table.public[each.key].id
+ transit_gateway_id = var.custom_route_to_tgw["public"].transit_gateway_id
+}
+
# Route: IPv6 routes from private subnets to the Transit Gateway (if configured in var.transit_gateway_ipv6_routes)
resource "aws_route" "ipv6_private_to_tgw" {
for_each = toset(local.ipv6_private_subnet_key_names_tgw_routed)
diff --git a/variables.tf b/variables.tf
index 8e7e6d8..1233f8d 100644
--- a/variables.tf
+++ b/variables.tf
@@ -250,6 +250,44 @@ EOF
}
}
+variable "custom_route_to_tgw" {
+ description = <<-EOF
+ Add a custom route to a transit gateway in a subnet.
+ The subnet is determined based on a map key that matches the key
+ provided in the var.subnets variable. This allows you to define
+ the specific subnet where the custom route should be applied.
+
+ Example:
+ ```
+ subnets = {
+ # Dual-stack subnet
+ public = {
+ netmask = 24
+ assign_ipv6_cidr = true
+ nat_gateway_configuration = "single_az"
+ }
+ # IPv4 only subnet
+ private = {
+ netmask = 24
+ connect_to_public_natgw = true
+ }
+ }
+ custom_route_to_tgw = {
+ private = {
+ destination_cidr_block = "10.0.0.0/16"
+ transit_gateway_id = "tgw-0282179847129898sd"
+ }
+ }
+ ```
+ EOF
+ type = map(object({
+ destination_cidr_block = optional(string)
+ destination_prefix_list_id = optional(string)
+ transit_gateway_id = string
+ }))
+ default = {}
+}
+
variable "tags" {
description = "Tags to apply to all resources."
type = map(string)