Can someone please explain what a for loop inside a for_each argument does in Terraform? I am trying to create an AWS SSL certificate. I've seen other code like the below but I don't understand it:
resource "aws_acm_certificate" "nonprod_cert" {
domain_name = var.phz_domain_name
validation_method = "DNS"
}
resource "aws_route53_record" "nonprod_cert_record" {
for_each = {
for dvo in aws_acm_certificate.nonprod_cert.domain_validation_options : dvo.domain_name => {
name = dvo.resource_record_name
record = dvo.resource_record_value
type = dvo.resource_record_type
}
}
zone_id = var.phz_id
name = each.value.name
type = each.value.type
records = [each.value.record]
ttl = 60
}
resource "aws_acm_certificate_validation" "nonprod_cert_validated" {
certificate_arn = aws_acm_certificate.nonprod_cert.arn
validation_record_fqdns = [for record in aws_route53_record.nonprod_cert_record : record.fqdn]
depends_on = [
aws_acm_certificate.nonprod_cert,
aws_route53_record.nonprod_cert_record
]
}
The specific line that I don't understand is the one in the route53 record. I get that a for_each argument can be used to create multiple resources from a single block, but I can't find anywhere that explains what this for loop is doing inside of it. If someone could explain that would be great!
CodePudding user response:
The inner for "loop" creates the data that the for_each
then iterates over. Specifically the each.key
will be the dvo.domain_name
and the each.value
will be the
{
name = dvo.resource_record_name
record = dvo.resource_record_value
type = dvo.resource_record_type
}
You could simply move that into a locals
block beforehand and not have it in a single line:
locals {
records = {
for dvo in aws_acm_certificate.nonprod_cert.domain_validation_options : dvo.domain_name => {
name = dvo.resource_record_name
record = dvo.resource_record_value
type = dvo.resource_record_type
}
}
}
resource "aws_route53_record" "nonprod_cert_record" {
for_each = local.records
zone_id = var.phz_id
name = each.value.name
type = each.value.type
records = [each.value.record]
ttl = 60
}
That will have the exact same effect.
CodePudding user response:
First they are using a for expression to convert one type of object into another type. In this case they are converting the list of domain_validation_options
into a list of objects that can be used for creating aws_route53_record
resources.
Next they are using for_each to create a new aws_route53_record
resource for each element of the list that was generated by the for
expression.
The key things to be aware of here are:
for
is used to convert a list of objects into a list of different objects.for_each
is used to create multiple resources from a list, set, or map of values.
I highly recommend spending the time to go through the Terraform learning site, or at least the Terraform documentation to learn the basic keywords and overall syntax.