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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 12:35:21