Terraform for_each over list of objects


We have a list of objects defined in vars.tf:

variable "sendgrid_dns_records" {
  type = list(object({
    type  = string
    name  = string
    value = string
  description = "DNS Records for sendgrid.com"

variable "cloudflare_zone_id" {
  type        = string
  description = "cloudflare zone id"

And have recorded their values in xyz.tfvars:

sendgrid_dns_records = [
    {"name": "url3415.netletic.xyz", "value": "sendgrid.net", "type": "CNAME"},
    {"name": "29342668.netletic.xyz", "value": "sendgrid.net", "type": "CNAME"},
    {"name": "em9437.netletic.xyz", "value": "u29342668.wl169.sendgrid.net", "type": "CNAME"},
    {"name": "s1._domainkey.netletic.xyz", "value": "s1.domainkey.u29342668.wl169.sendgrid.net", "type": "CNAME"},
    {"name": "s2._domainkey.netletic.xyz", "value": "s2.domainkey.u29342668.wl169.sendgrid.net", "type": "CNAME"},

Now we want to create DNS records for each of these in Cloudflare:

resource "cloudflare_record" "this" {
  for_each = {
    for index, dns_record in var.sendgrid_dns_records:
      dns_record.name => dns_record

  zone_id  = var.cloudflare_zone_id
  name     = each.value.name
  value    = each.value.value
  type     = each.value.type
  ttl      = 300

This works because we use for_each to create a new dictionary (map), where the key=dns_record.name, and the value=the entire object. Something like:

{'29342668.netletic.xyz': {'name': '29342668.netletic.xyz',
                           'type': 'CNAME',
                           'value': 'sendgrid.net'},
 'url3415.netletic.xyz': {'name': 'url3415.netletic.xyz',
                          'type': 'CNAME',
                          'value': 'sendgrid.net'}

So when we use for_each. We can refer to each.name, each.type, and each.value for each iteration. We don't care about each.key as it's the same as each.value.name.

See StackOverflow for more info

You might be interested in these notes:

  • Couldn't find similar notes.