首页 > 解决方案 > 如何使用terraform从json模板中定义的字符串数组中获取字符串值

问题描述

我正在尝试使用 json 模板在中转网关路由表中创建路由。但是,在从 json 模板中定义的字符串数组中获取每个字符串值时,出现如下错误;

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

下面是我的代码-->

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 文件 -->

{
  
  "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"
    ]
    }
  
}

如果仅在“ip_network”中传递单个字符串(例如:“ip_network”:“1.1.1.0/24”)但在使用字符串数组定义时无法获取,我能够将“destination_cidr_block”值作为“字符串”。

标签: arraysjsonamazon-web-servicesterraform

解决方案


如您所见,destination_cidr_block仅接受单个 CIDR 块(字符串),而不接受多个 CIDR 块。您需要aws_ec2_transit_gateway_route为每个路由表的每个 CIDR 块创建一个单独的。您可以通过展平地图来做到这一点,这样每个 RT/CIDR 组合都有一个元素。

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
}

如果您想查看扁平化地图现在的样子:

output "rt_cidr_blocks" {
  value = local.rt_cidr_blocks
}

输出:

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"
  }
}

推荐阅读