【问题标题】:Terraform - Referencing loop resources in for_each loopTerraform - 在 for_each 循环中引用循环资源
【发布时间】:2021-11-25 05:08:50
【问题描述】:

我正在使用我的自定义模块创建 ECS 服务,该模块是 for_each 循环的一部分。 我想在每个服务中修改一个安全组,以允许来自特定服务的通信。

考虑以下 ECS 服务地图:

locals {
  ecs_services = {
    "hello-world" = {
      container_image = local.ecr_repository_url_map["hello-world"]
      container_port  = "5050"
    }
    "hello-world2" = {
      container_image = local.ecr_repository_url_map["hello-world2"]
      container_port  = "8080"
      allowed_serivces = ["hello-world"] 
    }
  }
}

以下是我的失败尝试导致:

Error: Cycle: module.ecs_service.module.this_ecs_service_task (close), module.ecs_service.module.this_ecs_service_task.var.allowed_security_group_ids (expand), module.ecs_service.module.this_ecs_service_task.module.ecs_service_security_group.var.ingress_with_source_security_group_id (expand), module.ecs_service.module.this_ecs_service_task.module.ecs_service_security_group.aws_security_group_rule.ingress_with_source_security_group_id, module.ecs_service.module.this_ecs_service_task.module.ecs_service_security_group (close), module.ecs_service (close), module.ecs_service.var.allowed_security_group_ids (expand)
module "ecs_service" {
  source  = "./ecs-service"

  for_each = {
    for name, service in local.ecs_services : name => service
  }

  name = each.key

  container_image = each.value.container_image
  container_port  = each.value.container_port


  allowed_security_group_ids = [for k, v in lookup(each.value, "allowed_services", []) : module.ecs_service[v].security_group_id]
  ...
}

在我看来,这种构造是可能的,因为资源本身实际上并不相互引用,并且可以创建一个不会产生任何冲突的顺序。但显然存在一些 Terraform 限制。

有没有我可以实施的解决方法,不涉及为每个服务手动创建模块?

【问题讨论】:

  • “Terraform 存在一些限制” - 你是什么意思?你有任何错误吗?
  • 你能显示完整的错误吗?
  • @Marcin 是的,我在第二个 sn-p 上方提到了它。这是 Terraform 依赖树中的循环逻辑问题。我已经更新了完整的周期跟踪。如果我不够清楚,请道歉。
  • 我试图检查您的代码,但它有更多问题。例如,您没有定义 allowed_services。我想应该是allowed_serivces?我猜你还有其他类似的错误禁止复制你的问题。

标签: amazon-web-services foreach terraform amazon-ecs


【解决方案1】:

无论代码中的错误如何,你不能做你想做的事。有两个原因:

  1. TF 将同时创建ecs_service 模块的所有实例,而不是连续创建。因此,您不能在创建之前引用不存在的资源。
  2. 对地图的迭代基于字典顺序,而不是地图元素的插入顺序。在您的简单示例中,顺序与字典顺序一致,但依赖此顺序是以后解决问题的完美方式。

【讨论】:

  • 1.是的,我担心这就是同时创建模块的方式。这就结束了话题。但仍在寻找解决方案,我可以在其中获得简单的服务配置图。 2. 虽然我知道地图是按字典顺序排列的,但在幕后 TF 可能会创建一个资源创建方式的有序列表(depends_on,其他资源的输出)。但正如我提到的,数字 1 结束了这个话题
  • @JakubIgła 目前我能想到的唯一解决方案是创建单独的模块。这样您就可以显式控制它们的执行顺序。顺便说一句,如果我的回答有帮助,我们将不胜感激。
猜你喜欢
  • 2021-10-04
  • 2021-10-06
  • 1970-01-01
  • 2020-11-01
  • 2021-12-08
  • 1970-01-01
  • 2021-01-17
  • 2020-02-12
  • 2022-07-21
相关资源
最近更新 更多