Terraform 资源作为模块输入变量

Terraform resource as a module input variable

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

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

我似乎无法找到执行此操作的方法。有谁知道这是否可能?

您可以定义一个输入变量,其 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
}