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)