1

I have a terraform output for acm_certificate domain_validation_options

the output is something of this type. I want to extract resource_record_value and resource_record_name

     ~ base_module_outputs = {
          + acm_certificate_name = [
              + {
                  + domain_name           = "xxxx"
                  + resource_record_name  = "xxxxx"
                  + resource_record_type  = "CNAME"
                  + resource_record_value = "xxxx"
                },
            ]
            # (2 unchanged elements hidden)
        }

root module outputs.tf

output "base_module_outputs" {
  value = module.base
}

base module outputs.tf

output "acm_certificate_name" {
  value = aws_acm_certificate.xx.domain_validation_options
}
Marko E
  • 13,362
  • 2
  • 19
  • 28
Jatin Mehrotra
  • 9,286
  • 4
  • 28
  • 67
  • You want to extract that from the `base_module_outputs` output or `acm_certificate_name` output? – Marko E Jul 12 '23 at 11:18
  • I want to extract from `acm_certificate_name`. So basically extraction should happened inside base module. root module should output what base module provides it. – Jatin Mehrotra Jul 12 '23 at 11:22
  • Would `module.base.acm_certificate_name["resource_record_value"]` and `module.base.acm_certificate_name["resource_record_name"]` work? – Marko E Jul 12 '23 at 11:38
  • I am actual outputting 2 more value with resource_record_value and resource_record_name so in total 4 value. This will restrict me to only two values. that is why I wanted to do the extraction inside base module and not root module – Jatin Mehrotra Jul 12 '23 at 11:40
  • I can see you are, but where do you need those outputs to be? Where do you want to use them? – Marko E Jul 12 '23 at 11:45
  • will be displayed on console so that users can copy this value and update it manually. this is a required step, cannot be changed – Jatin Mehrotra Jul 12 '23 at 11:46
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/254459/discussion-between-jatin-mehrotra-and-marko-e). – Jatin Mehrotra Jul 12 '23 at 11:54

1 Answers1

1

Since the output value needs to be present in the base module outputs, here's how to get it:

output "acm_certificate_name" {
  value = tolist(aws_acm_certificate.xx.domain_validation_options)[0].resource_record_value
}

The explicit conversion to a list (using tolist built-in function) is required here as the domain_validation_options attribute is a set:

domain_validation_options - Set of domain validation objects which can be used to complete certificate validation. [...]

Hence domain_validation_options has no indexes. The same type of logic can be applied to the second required output which references the resource_record_name.


EDIT: As suggest in the comments (h/t: @Matt Schuchard), the safer way to fetch the values is by using the one built-in function. The above code would then change to:

output "acm_certificate_name" {
  value = one(aws_acm_certificate.xx.domain_validation_options).resource_record_value
}
Marko E
  • 13,362
  • 2
  • 19
  • 28
  • In my opinion this should be `one(aws_acm_certificate.xx.domain_validation_options).resource_record_value` because a set is unordered, and therefore the `0` element after list conversion could change between applications for no apparent reason. Using the `one` function guarantees an error if the number of elements is ever not one, and this seems safer to me as it guarantees the output value only changes if `aws_acm_certificate.xx.domain_validation_options` changes. – Matthew Schuchard Jul 12 '23 at 16:17
  • Sure, I'll add your suggestion to the answer, thanks, I'm learning as well from this. :) – Marko E Jul 12 '23 at 18:07