You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Terraform中处理嵌套数组?从本地映射提取记录至Route53

How to Extract Nested Arrays from Terraform Locals for AWS Route53 Records

Got it, let's break down how to handle nested arrays in Terraform for your Route53 use case. I’ve dealt with this exact scenario before, so let’s walk through it step by step.

First, Let's Align on Your Current Setup

Based on your description, I assume your locals block looks something like this, with nested records arrays inside each CNAME entry:

locals {
  cname_records = {
    "app" = {
      zone_id = "ZXXXXXXXXXXXXXX" # Your Route53 zone ID
      ttl     = 300
      records = [
        "app.example.com.",
        "www.app.example.com."
      ]
    }
    "api" = {
      zone_id = "ZYYYYYYYYYYYYYY"
      ttl     = 300
      records = [
        "api.example.com.",
        "v1.api.example.com."
      ]
    }
  }
}

And your problematic aws_route53_record resource looks like this, with the records field unpopulated:

resource "aws_route53_record" "cname" {
  for_each = local.cname_records
  zone_id  = each.value.zone_id
  name     = each.key
  type     = "CNAME"
  ttl      = each.value.ttl
  records  = # ❌ This is the problem area you're stuck on
}

The Simple Fix for Your Basic Case

The solution is straightforward—you can directly reference the nested records array using each.value.records. Here's the corrected resource:

resource "aws_route53_record" "cname" {
  for_each = local.cname_records
  zone_id  = each.value.zone_id
  name     = each.key
  type     = "CNAME"
  ttl      = each.value.ttl
  records  = each.value.records # ✅ Correctly pulls the nested array
}

Why This Works

When you use for_each with local.cname_records, each iteration of each.value represents the entire map for a single CNAME entry (e.g., the app entry with zone_id, ttl, and records). Since the Route53 records field accepts a list of strings, this direct reference perfectly matches the required input type.

Handling More Complex Nested Structures (If You Need It)

If your locals have a deeper nested structure (e.g., grouping records under parent domains), you’ll need to flatten the structure first using Terraform’s for expressions and flatten function. For example, if your locals look like this:

locals {
  domains = {
    "example.com" = {
      zone_id = "ZXXXXXXXXXXXXXX"
      cnames = [
        {
          name    = "app"
          ttl     = 300
          records = ["app.example.com."]
        },
        {
          name    = "www"
          ttl     = 300
          records = ["www.example.com."]
        }
      ]
    }
  }
}

You can transform this into a flat map suitable for for_each like so:

resource "aws_route53_record" "cname" {
  for_each = {
    for domain, domain_details in local.domains :
    for cname in domain_details.cnames :
    "${domain}-${cname.name}" => merge(cname, { zone_id = domain_details.zone_id })
  }

  zone_id  = each.value.zone_id
  name     = each.value.name
  type     = "CNAME"
  ttl      = each.value.ttl
  records  = each.value.records # Still works for the flattened entries
}

The nested for loop converts the 2-level structure into a single-level map, and merge combines the parent domain's zone_id with each CNAME's details so you can access all fields easily.

Quick Validation Tip

Before running terraform apply, you can test your nested array extraction using the Terraform console:

terraform console

Then run this command to verify you’re pulling the correct records:

local.cname_records["app"].records

You should see the array of CNAME values printed out—this confirms your reference is working correctly.

内容的提问来源于stack exchange,提问作者jadejoe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 17:27:34