Skip to content

Commit

Permalink
Add support to configure custom routes to TGWs
Browse files Browse the repository at this point in the history
Adding a new variable custom_route_to_tgw which is map of objects.
The map key is used to identify required subnets.
Each object contains route configuration.
Right now I'm creating a new route in the private and public subnets.
Not sure if this can be useful also for the transit_gateway and / or core_network subnets.
It is fair to mention that there is one limitation of this variable - one cannot create more routes per a subnet.
Not sure how to achieve it without too much changes.
  • Loading branch information
adrianeib committed Jun 7, 2023
1 parent ffb5715 commit fd017d0
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 0 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 |
Expand Down Expand Up @@ -377,6 +379,7 @@ Please see our [developer documentation](https://github.com/aws-ia/terraform-aws
| <a name="input_core_network"></a> [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. | <pre>object({<br> id = string<br> arn = string<br> })</pre> | <pre>{<br> "arn": null,<br> "id": null<br>}</pre> | no |
| <a name="input_core_network_ipv6_routes"></a> [core\_network\_ipv6\_routes](#input\_core\_network\_ipv6\_routes) | Configuration of IPv6 route(s) to AWS Cloud WAN's core network.<br>For each `public` and/or `private` subnets named in the `subnets` variable, optionally create routes from the subnet to the core network.<br>You can specify either a CIDR range or a prefix-list-id that you want routed to the core network.<br>Example:<pre>core_network_ivp6_routes = {<br> public = "::/0"<br> private = "pl-123"<br>}</pre> | `any` | `{}` | no |
| <a name="input_core_network_routes"></a> [core\_network\_routes](#input\_core\_network\_routes) | Configuration of route(s) to AWS Cloud WAN's core network.<br>For each `public` and/or `private` subnets named in the `subnets` variable, optionally create routes from the subnet to the core network.<br>You can specify either a CIDR range or a prefix-list-id that you want routed to the core network.<br>Example:<pre>core_network_routes = {<br> public = "10.0.0.0/8"<br> private = "pl-123"<br>}</pre> | `any` | `{}` | no |
| <a name="input_custom_route_to_tgw"></a> [custom\_route\_to\_tgw](#input\_custom\_route\_to\_tgw) | Add a custom route to a transit gateway in a subnet.<br> The subnet is determined based on a map key that matches the key<br> provided in the var.subnets variable. This allows you to define<br> the specific subnet where the custom route should be applied.<br><br>Example:<pre>subnets = {<br> # Dual-stack subnet<br> public = {<br> netmask = 24<br> assign_ipv6_cidr = true<br> nat_gateway_configuration = "single_az"<br> }<br> # IPv4 only subnet<br> private = {<br> netmask = 24<br> connect_to_public_natgw = true<br> }<br>}<br>custom_route_to_tgw = {<br> private = {<br> destination_cidr_block = "10.0.0.0/16"<br> transit_gateway_id = "tgw-0282179847129898sd"<br> }<br>}</pre> | <pre>map(object({<br> destination_cidr_block = optional(string)<br> destination_prefix_list_id = optional(string)<br> transit_gateway_id = string<br> }))</pre> | `{}` | no |
| <a name="input_tags"></a> [tags](#input\_tags) | Tags to apply to all resources. | `map(string)` | `{}` | no |
| <a name="input_transit_gateway_id"></a> [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 |
| <a name="input_transit_gateway_ipv6_routes"></a> [transit\_gateway\_ipv6\_routes](#input\_transit\_gateway\_ipv6\_routes) | Configuration of IPv6 route(s) to transit gateway.<br>For each `public` and/or `private` subnets named in the `subnets` variable,<br>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.<br>Example:<pre>transit_gateway_ipv6_routes = {<br> public = "::/0"<br> private = "pl-123"<br>}</pre> | `any` | `{}` | no |
Expand Down
10 changes: 10 additions & 0 deletions data.tf
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,16 @@ locals {

# constructed list of <private_subnet_key>/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"
Expand Down
20 changes: 20 additions & 0 deletions main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
38 changes: 38 additions & 0 deletions variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down

0 comments on commit fd017d0

Please sign in to comment.