在资源创建中使用地图列表清单

时间:2020-08-19 11:10:21

标签: terraform terraform0.12+

我希望能够使用TF Vars中定义的以下格式创建多个R53记录:

custom_zone_records = {
  "demo.a.com" = [
    {"*.b" = {type: "CNAME", records: ["d.com"]}},
    {"*.c" = {type: "CNAME", records: ["d.com"]}}
  ]
}

以记录为例,它应创建以下内容的R53记录:

Name: *.b.demo.a.com
Type: CNAME
Records: ["d.com"]

输入变量定义为:

variable "custom_zone_records" {
  description = "A map of maps for custom zone records"
  type = map(list(map(object({
    type = string
    records: list(string)
  }))))
}

我尝试使用for_each在资源创建过程中更改数组,并且尝试使用locals文件进行格式化,但没有成功。

除了使数组更明确之外,是否有更好的方法来格式化或处理此问题?

谢谢。

编辑:

如果我不使用该变量,则必须编写以下代码(作为我要实现的目标的示例)

resource "aws_route53_record" "demo_a" {
  zone_id = "ZONE_ID"
  name    = "*.b.demo.a.com"
  type    = "CNAME"
  records = ["d.com"]
  ttl     = 60
}

resource "aws_route53_record" "demo_a" {
  zone_id = "ZONE_ID"
  name    = "*.c.demo.a.com"
  type    = "CNAME"
  records = ["d.com"]
  ttl     = 60
}

1 个答案:

答案 0 :(得分:1)

执行此操作的一种方法(假设我正确理解了这个问题),将是创建一个帮助程序局部变量,该局部变量会将custom_zone_records“展开”为更for_each友好的列表。

在以下示例中,其称为helper_list

locals {
  custom_zone_records = {
    "demo.a.com" = [
      {"*.b" = {type: "CNAME", records: ["d.com"]}},
      {"*.c" = {type: "CNAME", records: ["d.com"]}}
    ],
    "demo1.a.com" = [
      {"*.b1" = {type: "CNAME", records: ["d1.com"]}},
      {"*.c1" = {type: "CNAME", records: ["d1.com"]}}
    ]    
  }
  
  helper_list = flatten([for k, v in local.custom_zone_records: 
            [for v1 in v: 
              merge({name = join("", [keys(v1)[0], ".", k])}, values(v1)[0])
           ]
      ])
  
}

helper_list的格式为:

helper_list = [                     
  {                          
    "name" = "*.b.demo.a.com"
    "records" = [   
      "d.com",               
    ]               
    "type" = "CNAME"         
  },             
  {                          
    "name" = "*.c.demo.a.com"
    "records" = [   
      "d.com",
    ]               
    "type" = "CNAME"
  },
  {
    "name" = "*.b1.demo1.a.com"
    "records" = [
      "d1.com",
    ]
    "type" = "CNAME"
  },
  {
    "name" = "*.c1.demo1.a.com"
    "records" = [
      "d1.com",
    ]
    "type" = "CNAME"
  },
]

这样,for_each的用法将更简单,并且可能是(我尚未验证以下内容,因此将其视为伪代码):

resource "aws_route53_record" "demo" {

  for_each = toset(local.helper_list)

  zone_id = "ZONE_ID"

  name    = each.value.name
  type    = each.value.type
  records = each.value.records

  ttl     = 60
}