我在陆地上创造了很少的资源-
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
.
.
.
}我想使用tf变量来使用for_each自动化类似的for_each创建。我在variables.tf中创建了一个映射变量,如下所示-
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"
}
}
}现在,我继续创建一个资源块,在task_map上循环并创建replication_task
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
.
.
.
}在我执行我的计划时,terrraform计划会引发一个错误,即引用replication_instance使用${each.value["repl_instance"]}是错误的。
错误信息-
│错误:./││/cdc/main.tf第236行上的无效字符││:该字符不在│语言中使用。╵
╷│错误:./│/cdc/main.tf第233行上的无效属性名││:在│点之后需要一个属性名。╵
错误消息指向我使用for_each引用replication_instance和source_endpoint的特定行
aws_dms_endpoint.${each.value["source_ep"]}.endpoint_arn
aws_dms_replication_instance.${each.value["repl_instance"]}.replication_instance_arn如何引用使用for_each使用其名称创建的资源。
谢谢。
发布于 2022-10-11 23:35:45
如何引用使用名称使用for_each创建的资源。
你不能这么做。换句话说,您不能以以下形式创建对资源的动态引用:
aws_dms_endpoint.${each.value["source_ep"]}.endpoint_arn相反,您必须使用映射或列表来创建aws_dms_replication_instance和aws_dms_endpoint。例如:
resource "aws_dms_replication_instance" "foobar_instance" {
for_each = toset(["foobar_instance_1", "foobar_instance_2"])
}
resource "aws_dms_endpoint" "foobar_source" {
for_each = toset(["foobar_source_1", "foobar_source_2"])
}结束时,请参阅以下内容:
resource "aws_dms_replication_task" "for_each_task_1" {
for_each = var.task_map
replication_instance_arn = aws_dms_replication_instance.foobar_instance[each.value["repl_instance"]].replication_instance_arn
source_endpoint_arn = aws_dms_endpoint.foobar_source[each.value["source_ep"]].endpoint_arn
.
.
.
}发布于 2022-10-12 02:08:26
在考虑这样的问题时,重要的是要认识到,像aws_dms_replication_instance.foobar_instance_1这样的引用表达式是一个不可分割的单元:aws_dms_replication_instance本身并不是一个独立的数据结构,您可以动态地查询它,因为Terraform需要能够准确地确定特定表达式所依赖的资源,以便在计算任何表达式之前生成依赖关系图。
但是,您可以构建自己的映射数据结构,其中包含您感兴趣的一组资源:
locals {
source_endpoints = {
"foobar_1" = aws_dms_endpoint.foobar_source_1
"foobar_2" = aws_dms_endpoint.foobar_source_2
}
replication_instances = {
"foobar_1" = aws_dms_replication_instance.foobar_instance_1
"foobar_2" = aws_dms_replication_instance.foobar_instance_2
}
}然后,您可以使用local.source_endpoints和local.replication_instances作为映射来查找模块调用方指定的键:
resource "aws_dms_replication_task" "for_each_task_1" {
for_each = var.task_map
replication_instance_arn = local.replication_instances[each.value.repl_instance].replication_instance_arn
source_endpoint_arn = local.source_endpoints[each.value.source_ep].endpoint_arn
# ...
}这可以工作,因为本地值也是参与依赖关系图的对象。Terraform可以看到local.source_endpoints同时依赖于aws_dms_endpoint.foobar_source_1和aws_dms_endpoint.foobar_source_2,因此间接地依赖于local.source_endpoints的任何东西都必须有效地依赖于这些资源。
虽然这对您的问题并不重要,但我想指出的是,这种设计意味着您的模块将声明完整的aws_dms_endpoint和aws_dms_replication_instance对象集,即使其中有些对象没有引用它们的任何var.task_map元素。
如果模块的唯一实际使用涉及到所有这些内容,我不会担心,但是如果这不是真的,那么这个设计的一个变体就是允许调用者通过输入变量指定他们需要的端点和复制实例,并在所有这三个资源上使用for_each。
如果这样做,就可以避免构造中间数据结构,因为for_each资源已经是支持相同类型动态查找的自然映射:
resource "aws_dms_replication_instance" "example" {
for_each = var.replication_instances
# ...
}
resource "aws_dms_endpoint" "example" {
for_each = var.source_endpoints
# ...
}
resource "aws_dms_replication_task" "for_each_task_1" {
for_each = var.task_map
replication_instance_arn = aws_dms_replication_instance.example[each.value.repl_instance].replication_instance_arn
source_endpoint_arn = aws_dms_endpoint.example[each.value.source_ep].endpoint_arn
# ...
}在此变体中,模块的调用方控制存在哪些复制实例和端点,以及每个任务使用哪一个,因此模块的用户负担更大,但他们也可以灵活地不声明他们不实际使用的对象,以防这些对象的开销很大。
https://stackoverflow.com/questions/74034959
复制相似问题