jmkite
jmkite

Reputation: 315

Terraform output object with multiple attributes for each of `for` resources?

I have terraform with a resource being created with for. As is typical, each instance of this resource has several attributes. At the moment I have a series of map outputs for this resource group but each consists of only a single key-value pair. I would like my terraform output to include a list or map of maps or objects with all of the attributes grouped by resource instance. How do I do this without using flatten; zipmap etc to construct them from my current outputs? This example is with aws_route53_record but this is a generic query:

Current code

output "r53record_zonal_fqdn" {
  value = {
    for entry in aws_route53_record.zonal :
    entry.name => entry.fqdn
  }
}
output "r53record_zonal_records" {
  value = {
    for entry in aws_route53_record.zonal :
    entry.name => entry.records
  }
}
output "r53record_zonal_zone_id" {
  value = {
    for entry in aws_route53_record.zonal :
    entry.name => entry.zone_id
  }
}

As you would expect, this renders three maps with aws_route53_record.zonal.name as the key and the other attribute(s) as the value.

What I would like is to have these outputs grouped by resource with a predefined key for each value, e.g. (pseudocode):

output "r53record_zonal_zone_id" {
    value = {
        for entry in aws_route53_record.zonal : {
            instance[count.index] {
                "name"    = entry.name 
                "fqdn"    = entry.fqdn
                "records" = entry.records
                "zone_id" = entry.zone_id
            }
        }
    }
}

Producing a map or list of maps for each instance.

How can this or something like it be done?

Upvotes: 6

Views: 15570

Answers (1)

Giridhar
Giridhar

Reputation: 588

I created a random route53_record resource block with two "name" arguments in for_each loop and tried to output something close to what you were looking for.

Assuming "mydomain.com" is the domain in Route53 as example....

resource "aws_route53_record" "zonal" {
for_each=toset(["site1","site2"])
  name    = each.key
  zone_id = "ABCDZONEIDSTRING"
  type    = "A"
  ttl     = "300"
  records = ["192.168.1.10"]
}



output "test" {
  value = {
    for dns, details in aws_route53_record.zonal:
    dns => ({"fqdn" = details.fqdn , "zone_id" = details.zone_id , "records" = details.records})
  }
}

this will create output in this fashion..

    test = {
      "site1" = {
         "fqdn" = "site1.mydomain.com"
         "records" = [
           "192.168.1.10",
         ]
         "zone_id" = "Z0630117NTQNSYTXYQ4Z"
      }

      "site2" = {
         "fqdn" = "site2.mydomain.com"
         "records" = [
          "192.168.1.10",
         ]
         "zone_id" = "Z0630117NTQNSYTXYQ4Z"
       }
    }

Suppose you passed the name values with domain name, like below...

for_each=toset(["site1.mydomain.com","site2.mydomain.com"])

the output would look like

    test = {
       "site1.mydomain.com" = {
       "fqdn" = "site1.mydomain.com"
       "records" = [
        "192.168.1.10",
       ]
       "zone_id" = "ABCDMYZONEIDSTRING"
       }

       "site2.mydomain.com" = {
       "fqdn" = "site2.mydomain.com"
       "records" = [
        "192.168.1.10",
       ]
       "zone_id" = "ABCDMYZONEIDSTRING"
       }
    }

Upvotes: 12

Related Questions