1

I am trying to create routes in Transit gateway route table using a json template. However, while fetching each string value from an array of string defined in json template, getting error as below;

Error: Incorrect attribute value type\n\n  on main.tf line 90, in resource \"aws_ec2_transit_gateway_route\" \"ip_route\":\n  90:   destination_cidr_block         = each.value.ip_network\n    |----------------\n    | each.value.ip_network is tuple with 3 elements\n\nInappropriate value for attribute \"destination_cidr_block\": string require

Here below is my code -->

resource "aws_ec2_transit_gateway_route" "ip_route" {
  for_each                       = jsondecode(file("templates/my.json"))
  destination_cidr_block         = each.value.ip_network
  transit_gateway_attachment_id  = "tgw-attach-123"
  transit_gateway_route_table_id = each.value.tgw_rt_id
}

json file -->

{
  
  "RT-1": {
    "tgw_rt_id": "tgw-rtb-00128",
    "ip_network": [ 
      "1.1.1.0/24",
      "1.1.2.0/24",
      "1.1.3.0/24"
    ]
    },

  "RT-2": {
    "tgw_rt_id": "tgw-rtb-01f1b",
    "ip_network": [ 
      "1.1.1.0/24",
      "1.1.2.0/24",
      "1.1.3.0/24"
    ]
    }
  
}

I am able to get the "destination_cidr_block" value as "string" if only single string is passed in "ip_network" (eg: "ip_network": "1.1.1.0/24") but failed to fetch when defined with array of string.

1 Answer 1

3

As you've identified, the destination_cidr_block only accepts a single CIDR block (a string), not multiple CIDR blocks. You need to create a separate aws_ec2_transit_gateway_route for each CIDR block for each route table. You can do this by flattening the map so there's one element for each RT/CIDR combination.

locals {
  route_tables = jsondecode(file("templates/my.json"))
  rt_cidr_blocks = merge([
    for k, rt in local.route_tables:
    { 
      for i, ip_network in rt.ip_network:
      "${k}-${i}" => {
        tgw_rt_id = rt.tgw_rt_id
        ip_network = ip_network
      }
    }
  ]...)
}

resource "aws_ec2_transit_gateway_route" "ip_route" {
  for_each                       = local.rt_cidr_blocks
  destination_cidr_block         = each.value.ip_network
  transit_gateway_attachment_id  = each.key
  transit_gateway_route_table_id = each.value.tgw_rt_id
}

If you want to see what the flattened map looks like now:

output "rt_cidr_blocks" {
  value = local.rt_cidr_blocks
}

Output:

Apply complete! Resources: 0 added, 0 changed, 0 destroyed.

Outputs:

blocks = {
  "RT-1-0" = {
    "ip_network" = "1.1.1.0/24"
    "tgw_rt_id" = "tgw-rtb-00128"
  }
  "RT-1-1" = {
    "ip_network" = "1.1.2.0/24"
    "tgw_rt_id" = "tgw-rtb-00128"
  }
  "RT-1-2" = {
    "ip_network" = "1.1.3.0/24"
    "tgw_rt_id" = "tgw-rtb-00128"
  }
  "RT-2-0" = {
    "ip_network" = "1.1.1.0/24"
    "tgw_rt_id" = "tgw-rtb-01f1b"
  }
  "RT-2-1" = {
    "ip_network" = "1.1.2.0/24"
    "tgw_rt_id" = "tgw-rtb-01f1b"
  }
  "RT-2-2" = {
    "ip_network" = "1.1.3.0/24"
    "tgw_rt_id" = "tgw-rtb-01f1b"
  }
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.