Dave Michaels
Dave Michaels

Reputation: 937

Iterating through a map of objects with multiple values using for_each

I have multiple DNS records that I am creating using Terraform. One of my records has two values that it needs to read from. I am having an issue getting Terraform to be able to loop through my variables in order for this to read successfully. Below is my code. I am getting an error that does not make any sense even though I have the correct data type. There is some error with how I am looping through these resources, and I am having some trouble figuring out where I went wrong. Any advice would be appreciated.

variables.tf
    variable "mx" {
      type = map(object({
        ttl     = string
        records = set(string)
      }))
    }
variables.tfvars
  mx = {
       "mx_record1" = {
         ttl = "3600"
         records = [
           "mx_record1_value"
         ]
       }
       "mx_record2" = {
         ttl = "3600"
         records = [
           "mx_record2_value"
           "mx_record2_value2"
         ]
       }
mx.tf
  locals {
       mx_records = flatten([
         for mx_key, mx in var.mx : [
           for record in mx.records : {
             record = record
             mx     = mx_key
           }
         ]
       ])
     }
 
 resource "aws_route53_record" "mx_records" {
   for_each = { for mx in local.mx_records : mx.record => mx }
   zone_id  = aws_route53_zone.zone.zone_id
   name     = each.key
   type     = "MX"
   ttl      = each.value.ttl
 
   records = [
     each.value.record
   ]
 }

Got below error

    Error:
    
        Error: Unsupported attribute
    
      on mx.tf line 17, in resource "aws_route53_record" "mx_records":
      17:   ttl      = each.value.ttl
        |----------------
        | each.value is object with 2 attributes
    
    This object does not have an attribute named "ttl".

UPDATE:


    locals {
  mx_records = flatten([
    for mx_key, mx in var.mx : [
      for record in mx.records : {
        record = record
        mx     = mx_key
        ttl    = mx.ttl
      }
    ]
  ])
}

resource "aws_route53_record" "mx_records" {
  for_each = { for mx in local.mx_records : mx.record => mx }
  zone_id  = aws_route53_zone.zone.zone_id
  name     = each.key
  type     = "MX"
  ttl      = each.value.ttl

  records = [
    each.value.record
  ]
}

ERROR


    Error: [ERR]: Error building changeset: InvalidChangeBatch: [FATAL problem: UnsupportedCharacter (Value contains unsupported characters) encountered with ' ']
        status code: 400, request id: a27e6a47-c10f-42ce-be94-10aaa9c276f8

  on mx.tf line 13, in resource "aws_route53_record" "mx_records":
  13: resource "aws_route53_record" "mx_records" {

Upvotes: 0

Views: 7626

Answers (1)

Marcin
Marcin

Reputation: 239005

I think your mx_records should be:

locals {
    mx_records = flatten([
      for mx_key, mx in var.mx :
        [for record in mx.records: {
          record = record
          mx     = mx_key
          ttl    = mx.ttl
        }]
      ])
}

This will result in the following structure:

mx_records = [
  {
    "mx" = "mx_record1"
    "record" = "mx_record1_value"
    "ttl" = "3600"
  },
  {
    "mx" = "mx_record2"
    "record" = "mx_record2_value"
    "ttl" = "3600"
  },
  {
    "mx" = "mx_record2"
    "record" = "mx_record2_value2"
    "ttl" = "3600"
  },
]

Upvotes: 2

Related Questions