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
相关产品推荐
相关产品推荐

