【问题标题】:Terraform resource as a module input variableTerraform 资源作为模块输入变量
【发布时间】:2020-12-08 02:42:13
【问题描述】:

在开发 terraform 模块时,我有时会发现自己需要为相同的资源定义不同的输入变量。例如,现在我的模块需要同一个 AWS/ECS 集群的 NAME 和 ARN,因此,我在模块中定义了两个变量:ecs_cluster_arnecs_cluster_name

为了 DRY,如果我可以定义 aws_ecs_cluster 类型的输入变量 ecs_cluster 并在我的模块中使用我需要的任何东西,那就太好了。

我似乎找不到办法做到这一点。有谁知道可以吗?

【问题讨论】:

  • 使用aws_ecs_cluster data source 阻止您的模块并查找给定名称的 ARN?
  • 谢谢@ydaetskcoR。老实说,我没想过,我想这可能会奏效。不过我觉得有点脏,为什么要再次请求获取我已经拥有的信息?
  • 我个人在内部模块中大量使用这样的数据源。对于公共模块,一般建议是允许人们将事物作为 ID 传入,并让他们负责从数据源、资源或硬编码 ID 传入以实现灵活性。对于内部使用,尽管我只关心使模块用户的界面尽可能简单,为此我可以询问资源的名称并使用数据源来获取模块中的更多信息。

标签: terraform terraform-provider-aws


【解决方案1】:

您可以定义一个输入变量,其type constraintaws_ecs_cluster 资源类型的架构兼容。通常,您会编写一个子集类型约束,其中仅包含模块实际需要的属性。例如:

variable "ecs_cluster" {
  type = object({
    name = string
    arn  = string
  })
}

在模块的其他地方,您可以使用var.ecs_cluster.namevar.ecs_cluster.arn 来引用这些属性。模块的调用者可以传入与该类型约束兼容的任何内容,其中包括 aws_ecs_cluster 资源类型的整个实例,但也包括仅包含这两个属性的文字对象:

module "example" {
  # ...

  ecs_cluster = aws_ecs_cluster.example
}
module "example" {
  # ...

  ecs_cluster = {
    name = "blah"
    arn  = "arn:aws:yada-yada:blah"
  }
}

在许多情况下,这也允许传递 the corresponding data source 的结果而不是托管资源类型。不幸的是,对于这种配对,特别是数据源出于某种原因使用了不同的属性名称cluster_name,因此不兼容。不幸的是,这不是成对的托管资源类型和具有相同名称的数据源的典型设计约定。我认为这是设计疏忽。

module "example" {
  # ...

  # This doesn't actually work for the aws_ecs_cluster
  # data source because of a design quirk, but this would
  # be possible for most other pairings such as
  # the aws_subnet managed resource type and data source.
  ecs_cluster = data.aws_ecs_cluster.example
}

【讨论】:

  • 非常有意义。谢谢。
猜你喜欢
  • 2021-01-11
  • 2022-01-13
  • 2022-06-22
  • 2021-12-28
  • 2019-11-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-08
相关资源
最近更新 更多