【问题标题】:Define Module Dependencies in Terraform在 Terraform 中定义模块依赖关系
【发布时间】:2019-01-12 02:12:42
【问题描述】:

我们如何确保第一个模块“frontend_1”在其他模块之前执行?

module "frontend_1" {
  source = "/modules/frontend-app"
}
module "frontend_2" {
  source = "/modules/frontend-app"
}
module "frontend_3" {
  source = "/modules/frontend-app"
}

另外 - 记录了几个关于这个问题的 Gitissues,但其中任何一个都没有提供好的解决方法。作为一个开始 - 你可以检查这个,这样你就可以熟悉我的问题的本质 - https://github.com/hashicorp/terraform/issues/10462

以及如何在模块执行之前为模块资源构建一个外部资源 - 如果它依赖于从此类外部资源计算的值,则可以计算“计数”? 例如 - 如果您需要在模块的“计数”中使用新创建的 VPC 的 ID,该模块在该 VPC 中创建多个 AWS 安全组?

【问题讨论】:

  • 希望我的回答能回答您的问题。但也许你描述得更多,你真正想要达到的目标感觉有点不寻常。
  • 它没有。它实际上是非常需要的——如果你使用一个模块创建一个资源,然后使用同一个模块创建另一个资源,但第二个资源需要第一个资源的 ID ......不可能在第二个资源中获取并使用它.
  • 我已经删除了关于模块的明显但不存在的depends_on 的答案。似乎我再次过度简化了 terraform ;-)
  • 将一个模块的输出传递给另一个模块的变量,不是吗?或者什么代码“需要第一个资源的ID”?数据资源?
  • 由于某种原因,它在我的情况下不起作用 - 我正在尝试将由模块创建的 AWS 安全组的 ID 传递给创建第二个 SG 的同一模块的另一个初始化它在其源入口规则中使用第一个 SG 的 ID。

标签: amazon-web-services terraform


【解决方案1】:

如问题中所述,我能够使用 depends on 变量为您制定解决方法。

请参阅 this 了解 Terraform 依赖项。

假设我们有 2 个模块,一个定义 vpc 和子网,第二个定义要在基础架构中使用的各种安全组范围。

由于我们有依赖,所有的安全组都需要在VPC模块中成功创建vpc之后才能创建,所以可以通过下面的策略来满足。

variable "vpc_arn" {
   description = "The ARN of the VPC which is created in the VPC module"
}

resource "null_resource" "vpc_found" {
  triggers = {
    vpc_name = "${var.vpc_arn}"
  }
}

resource "aws_security_group" "allow_all" {

  depends_on = ["null_resource.vpc_found"]

  name        = "allow_all"
  description = "Allow all inbound traffic"
  vpc_id      = "${var.vpc_arn}"
  ......
}

有关空资源,请参阅this

【讨论】:

  • 感谢您分享答案。它按预期工作。
【解决方案2】:

模块不是作为一个单元全部创建或全部销毁的资源包,因此一个模块在另一个模块之前或之后运行是没有意义的。如果您查看terraform graph 的输出,您会看到模块中的各个资源在执行引擎同时遍历的计划图中显示为节点。这意味着完全有可能在两个模块之间存在双向依赖(模块 A 从模块 B 输出中获取输入,并且还提供用于模块 B 输入的输出),只要计划图不包含循环即可。

使用 Terraform 观察的一件事是,计划图是通过查看哪些资源属性、变量、输入输出等通过插值依赖于其他哪些资源属性、变量、输入输出等,并结合使用 depends_on 的任何显式声明的依赖关系来构建的(这不是可用于模块)。对于您上面的示例,这样做的结果是,如果没有插值引用将值从一个模块的输出链接到另一个模块的输入,那么在计划图中就不能构造任何路径来指示资源之间的任何依赖关系。

【讨论】:

  • 感谢山姆的精彩解释!
  • 这是一个很好的答案,但我认为最后几段不是真的。根据我的经验和现在的快速测试,确认 Terraform 将等待资源完全创建(包括任何附加到资源的配置器),然后再开始创建另一个资源,该资源依赖于第一个资源,通过 depends_on 或插值。跨度>
  • 事实上,依赖图是从静态引用创建的,无论它们的值是否“已知”。如果可以,Terraform 将在计划输出中包含该实际资源名称,但它仍然可以在 some_other_resource.other_thing 之前的 some_resource.thing 上工作,即使 name 属性已经具有已知值。
  • @MartinAtkins 以及如何在模块执行之前构建模块资源的外部?
  • @Xtigyro 除了那个小细节之外,这个答案是准确的。控制操作顺序的方法是在资源之间创建插值引用,或者在模块的输入变量和输出值之间创建插值引用。
猜你喜欢
  • 1970-01-01
  • 2018-02-21
  • 2015-12-28
  • 1970-01-01
  • 2020-02-05
  • 2020-03-17
  • 1970-01-01
  • 1970-01-01
  • 2012-05-25
相关资源
最近更新 更多