how do i do a dynamic route in aws _route_table?

1.7k Views Asked by At

I am using terraform to create my aws route table and its routes.

I am referencing base on this: https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route_table

resource "aws_route_table" "r" {
  vpc_id = aws_vpc.default.id

  route {
    cidr_block = "10.0.1.0/24"
    gateway_id = aws_internet_gateway.main.id
  }

  route {
    ipv6_cidr_block        = "::/0"
    egress_only_gateway_id = aws_egress_only_internet_gateway.foo.id
  }

  tags = {
    Name = "main"
  }
}

How do I make it such that I do not repeat the route portion. And I can do it via an array of map and it will know I need 2 routes to be created?

example:

route = [
{
    cidr_block = "10.0.1.0/24"
    gateway_id = aws_internet_gateway.main.id
  },
{
    ipv6_cidr_block        = "::/0"
    egress_only_gateway_id = aws_egress_only_internet_gateway.foo.id
  }
]

I tried with something like this:

resource "aws_route_table" "rt" {

  vpc_id = data.aws_vpc.main.id

  dynamic route {
    count = length(var.routes)
    for_each = var.routes
    content {
      cidr_block = lookup(route.value, "cidr_block", null)
      ipv6_cidr_block = lookup(route.value, "ipv6_cidr_block", null)

      egress_only_gateway_id = lookup(route.value, "egress_only_gateway_id", null)
      gateway_id = lookup(route.value, "gateway_id", null)
      instance_id = lookup(route.value, "instance_id", null)
      nat_gateway_id = lookup(route.value, "nat_gateway_id", null)
      local_gateway_id = lookup(route.value, "local_gateway_id", null)
      network_interface_id = lookup(route.value, "network_interface_id", null)
      transit_gateway_id = lookup(route.value, "transit_gateway_id", null)
      vpc_endpoint_id = lookup(route.value, "vpc_endpoint_id", null)
      vpc_peering_connection_id = lookup(route.value, "vpc_peering_connection_id_by_data", "false") == "true" ? data.aws_vpc_peering_connection.main[count.index].id : lookup(route.value, "vpc_peering_connection_id", null)
    }
  }
}
2

There are 2 best solutions below

1
On

Dynamic blocks use only for_each, not count. However, you are using both count and for_each in your block:

  dynamic route {
    count = length(var.routes)
    for_each = var.routes

The above is incorrect, and count = length(var.routes) should be removed.

0
On

My final answer will be this

resource "aws_route_table" "rt" {

  vpc_id = data.aws_vpc.main.id

  dynamic route {
    for_each = var.routes
    content {
      cidr_block = lookup(route.value, "cidr_block", null)
      ipv6_cidr_block = lookup(route.value, "ipv6_cidr_block", null)

      egress_only_gateway_id = lookup(route.value, "egress_only_gateway_id", null)
      gateway_id = lookup(route.value, "gateway_id", null)
      instance_id = lookup(route.value, "instance_id", null)
      nat_gateway_id = lookup(route.value, "nat_gateway_id", null)
      local_gateway_id = lookup(route.value, "local_gateway_id", null)
      network_interface_id = lookup(route.value, "network_interface_id", null)
      transit_gateway_id = lookup(route.value, "transit_gateway_id", null)
      vpc_endpoint_id = lookup(route.value, "vpc_endpoint_id", null)
      vpc_peering_connection_id = lookup(route.value, "vpc_peering_connection_id_by_data", "false") == "true" ? data.aws_vpc_peering_connection.main[route.key].id : lookup(route.value, "vpc_peering_connection_id", null)
    }
  }
}