Terraform中使用for_each引用已有AWS DMS资源的正确方法
问题描述
我在Terraform中创建了以下DMS资源:
resource "aws_dms_replication_instance" "foobar_instance_1" { } resource "aws_dms_replication_instance" "foobar_instance_2" { } resource "aws_dms_endpoint" "foobar_source_1" { } resource "aws_dms_endpoint" "foobar_source_2" { }
随后手动定义了依赖上述资源的复制任务:
resource "aws_dms_replication_task" "foobar_task_1" { replication_instance_arn = aws_dms_replication_instance.foobar_instance_1.replication_instance_arn source_endpoint_arn = aws_dms_endpoint.foobar_source_1.endpoint_arn # 其他配置... }
为了通过for_each批量生成复制任务,我在variables.tf中定义了Map变量:
variable "task_map" { type = map(object({ source_endpoint = string repl_instance = string })) default = { "dms_attr_map" = { source_ep = "foobar_source_1" repl_instance = "foobar_instance_1" }, "dms_attr_map2" = { source_ep = "foobar_source_2" repl_instance = "foobar_instance_2" } } }
接着编写了循环生成任务的资源块:
resource "aws_dms_replication_task" "for_each_task_1" { for_each = var.task_map replication_instance_arn = aws_dms_replication_instance.${each.value["repl_instance"]}.replication_instance_arn source_endpoint_arn = aws_dms_endpoint.${each.value["source_ep"]}.endpoint_arn # 其他配置... }
执行terraform plan时出现报错:
│ Error: Invalid character │ │ On ../modules/cdc/main.tf line 236:
This character is not used within the │ language. ╵╷ │ Error: Invalid attribute name │ │ On ../modules/cdc/main.tf line
233: An attribute name is required after a │ dot. ╵
错误指向尝试通过变量引用资源的代码行:
aws_dms_endpoint.${each.value["source_ep"]}.endpoint_arn aws_dms_replication_instance.${each.value["repl_instance"]}.replication_instance_arn
请问如何在for_each中通过资源名称正确引用已创建的资源?
解决方案
Terraform不支持在资源引用中使用字符串插值(${})来动态拼接资源名称。要实现动态引用已创建的资源,需要借助资源实例集合映射来调整:
1. 修正变量定义
先统一变量内的属性名,避免命名不一致导致的逻辑混乱:
variable "task_map" { type = map(object({ source_endpoint_name = string repl_instance_name = string })) default = { "task_1" = { source_endpoint_name = "foobar_source_1" repl_instance_name = "foobar_instance_1" }, "task_2" = { source_endpoint_name = "foobar_source_2" repl_instance_name = "foobar_instance_2" } } }
2. 动态引用资源实例
Terraform中同类型的资源会自动组成一个实例集合,可通过资源类型+索引(资源名称)的方式动态获取对应实例:
resource "aws_dms_replication_task" "for_each_task_1" { for_each = var.task_map replication_instance_arn = aws_dms_replication_instance[each.value.repl_instance_name].replication_instance_arn source_endpoint_arn = aws_dms_endpoint[each.value.source_endpoint_name].endpoint_arn # 补充必要的任务配置(示例) migration_type = "full-load-and-cdc" table_mappings = jsonencode({}) # 根据实际需求填写映射规则 }
原理说明
- Terraform的资源类型(如
aws_dms_replication_instance)本质是一个映射结构,键为资源名称(如foobar_instance_1),值为对应资源实例对象。 - 使用
resource_type[resource_name]的语法,可通过资源名称动态获取实例,进而访问其属性(如replication_instance_arn),完全符合HCL语法规范。
内容的提问来源于stack exchange,提问作者Abhi
相关产品推荐
相关产品推荐

