Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support to create a custom route in a subnet for TGW #116

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -341,11 +341,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 @@ -379,6 +381,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