Home > Software engineering >  Terraform multiple AWS route53 MX records
Terraform multiple AWS route53 MX records

Time:03-29

I have locals in tf to push MX records to cloudflare and it works exactly I want it to. The same locals I want to use for Route53 but for route53 the records should be combined to one. How I can use blow locals to push to Route53 using terraform.

locals {
    MXRecordSets = [
         {
            Name =  "example.com.",
            Type =  "MX",
            TTL =  3600,
            MXRecords =  [
                {
                    "Value" =  "1 aspmx.l.google.com"
                },
                {
                     "Value" =  "5 alt1.aspmx.l.google.com"
                 }
            ]
        }
    ]
}
locals {
    FlatMXRecordSets = merge([
    for idx, MXRecordSet in local.MXRecordSets:
      {
        for MXRecord in MXRecordSet.MXRecords:
            "${idx}-${MXRecord.Value}" => {
              MXRecordSet = MXRecordSet
              MXRecord =  MXRecord["Value"]
          }
      }
    ]...)
}

and finally I am using below aws route53 module to push changes to AWS, but its not working:

resource "aws_route53_record" "mx_records" {
  for_each =local.FlatMXRecordSets
  zone_id  = aws_route53_zone.carfeine_com.id
  name     = each.value["MXRecordSet"].Name
  type     = each.value["MXRecordSet"].Type
  records  = [ each.value["MXRecord"] ]
  ttl      = 1
}

The error comes as [Tried to create resource record set [name='example.com.', type='MX'] but it already exists] because I am using for_each and I should not use that. Any other way ?

CodePudding user response:

Your MXRecordSets is already flat, thus it does not require flattening. But Its also a list of maps, which can lead to more issues, as a list depends on order of items. Thus its better to use just a map of maps, if possible:

locals {
    MXRecordSets = {
       "mail.mwotest.xyz." = {
            Type =  "MX",
            TTL =  3600,
            MXRecords =  [
                {
                    "Value" =  "1 aspmx.l.google.com"
                },
                {
                     "Value" =  "5 alt1.aspmx.l.google.com"
                 }
            ]
        }
    }            
}

then

resource "aws_route53_record" "mx_records" {
  for_each = local.MXRecordSets
  zone_id  = aws_route53_zone.carfeine_com.id
  name     = each.key
  type     = each.value.Type
  records  = [ for key,record in each.value["MXRecords"]: record["Value"] ]
  ttl      = 1
}

in the above, the

 [ for key,record in each.value["MXRecords"]: record["Value"] ]

will produce correct records for MX as:

records = ["1 aspmx.l.google.com", "5 alt1.aspmx.l.google.com"]
  • Related