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

Terraform遍历嵌套对象获取EC2私网IP并创建Route53记录

使用Terraform基于EC2实例ID自动生成Route53 A记录

需求:通过嵌套对象变量定义域名与对应EC2实例ID的关联,动态查询运行中EC2实例的私网IP,自动创建Route53 A记录,替代硬编码IP的方案。

完整实现代码

1. 配置AWS Provider与变量

保留原有的嵌套对象变量结构,明确域名和关联的实例ID集合:

provider "aws" {
  region = "us-east-2"
}

variable "dns-records" {
  type = set(object({
    dns       = string
    instances = set(string)
  }))
  default = [
    {
      dns       = "web.example.com"
      instances = ["i-ins1", "i-ins2", "i-ins3"]
    },
    {
      dns       = "web1.example.com"
      instances = ["i-ins1"]
    },
    {
      dns       = "web2.example.com"
      instances = ["i-ins2"]
    },
    {
      dns       = "web3.example.com"
      instances = ["i-ins3"]
    },
    {
      dns       = "web1-2.example.com"
      instances = ["i-ins1", "i-ins2"]
    }
  ]
}

2. 批量查询EC2实例数据

提取所有需要查询的实例ID并去重,批量获取运行中实例的信息:

# 提取所有唯一的实例ID,避免重复查询
locals {
  all_instance_ids = distinct(flatten([for record in var.dns-records : record.instances]))
}

# 查询目标EC2实例,仅获取运行中的实例
data "aws_instance" "target_instances" {
  for_each = toset(local.all_instance_ids)
  instance_id = each.value

  filter {
    name   = "instance-state-name"
    values = ["running"]
  }
}

3. 构建域名与私网IP的映射

将原变量转换为域名: 私网IP列表的键值对结构,自动匹配实例ID对应的IP:

locals {
  dns_to_ips = {
    for record in var.dns-records : record.dns => [
      # 匹配每个实例ID对应的私网IP
      for instance_id in record.instances : data.aws_instance.target_instances[instance_id].private_ip
      # 过滤未查询到的实例(避免实例不存在导致的错误)
      if contains(keys(data.aws_instance.target_instances), instance_id)
    ]
    # 过滤掉没有有效IP的域名
    if length([
      for instance_id in record.instances : data.aws_instance.target_instances[instance_id].private_ip
      if contains(keys(data.aws_instance.target_instances), instance_id)
    ]) > 0
  }
}

4. 创建Route53 A记录

遍历处理后的映射,自动生成每个域名对应的A记录:

resource "aws_route53_record" "dns_records" {
  for_each = local.dns_to_ips

  zone_id = "ZID" # 替换为你的Route53托管区ID
  name    = each.key
  type    = "A"
  ttl     = 300
  records = each.value
}

关键说明

  • 去重实例ID:通过distinct(flatten(...))提取唯一实例ID,减少重复查询的开销。
  • 状态过滤:仅查询运行中的实例,避免已终止/停止实例的无效数据。
  • 容错处理:过滤未查询到的实例,防止因实例不存在导致Terraform执行失败。
  • 结构适配:将嵌套对象转换为适合for_each的键值对结构,符合Terraform资源遍历要求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 01:57:36