Use a map of lists of maps in resource creation

眉间皱痕 提交于 2021-01-28 05:05:13

问题


I want to be able to create multiple R53 records, using the following format defined in TF Vars:

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

Using the record as an example, it should create the R53 record of:

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

The input variable is defined as:

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

I've tried mutating the array within the resource creation using a for_each and I've tried formatting using a locals file, with no success.

Is there a better way to format or handle this, other than having the array more explicit?

Thanks.

Edit:

If I were to not use the variable, I would have to write the following code (as an example of what I am trying to achieve)

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:


One way to do this (assuming I correctly understand the issue), would be to create an a helper local variable which would "unwind" the custom_zone_records into more for_each-friendly list.

In the following example, it is called 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])
           ]
      ])
  
}

The helper_list would have the form:

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

This way, the for_each usage would be simpler, and could be (I haven't verified the following, so treat it as a pseudo-code):

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
}


来源:https://stackoverflow.com/questions/63485698/use-a-map-of-lists-of-maps-in-resource-creation

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!