每个元参数的解决方法

问题描述 投票:0回答:1

假设我有一个 Terragrunt 配置位于所有平台边界 Databricks 项目之上,并且正在运行集群模块。该模块循环遍历每个 PB

main.tf
中定义的 locals 块,如下所示:

locals {
    #... other local vars
    clusters = {
      clusterA = {
        name = "clusterA"
        #... other cluster config
      },
      clusterB = {
        name = "clusterB"
        #... other cluster config
      }, ...
    }
}

## main.tf

所有集群名称都是唯一的。我现在希望从特定平台边界删除除 clusterX 之外的每个集群。
我的目标是基本上将集群模块中的

for_each
设置为空集,只要我不这样做,它就不会循环遍历这个特定的集群,但如果它碰到它,我希望执行该模块。

我正在努力为此提出正确的条件,我最接近的解决方案如下:

locals{
    run_cluster_module = contains(keys(local.clusters), "clusterX")
}

module "cluster" {
    for_each = local.run_cluster_module ? local.clusters : {}
    #... other module attributes 

## terragrunt.hcl

这会以某种方式引发不一致的类型错误。有什么建议吗?

foreach terraform terragrunt
1个回答
0
投票
Terraform 中的

{ ... }

 语法生成对象类型的值。在某些情况下,Terraform 能够自动推断您打算使用地图值并对其进行转换,但在这种情况下,Terraform 不太确定您打算做什么,因此它不会执行任何自动转换。

错误消息随后描述了两种不同对象类型之间的不匹配情况,希望它能帮助您添加适当的类型转换或其他信息,以阐明您希望条件表达式生成什么数据类型。

在这种情况下,我建议将这两个值显式转换为地图。例如:

locals { #... other local vars clusters = tomap({ clusterA = { name = "clusterA" #... other cluster config }, clusterB = { name = "clusterB" #... other cluster config }, ... }) } module "cluster" { for_each = local.run_cluster_module ? local.clusters : tomap({}) # ... }
这告诉 Terraform 您希望 

local.clusters

 成为对象的地图而不是对象本身。我无法准确预测仅使用 
local.clusters
 的部分值的类型,但仅使用 
name
 属性,如您在代码片段中所示,
local.clusters
 将具有以下类型:

map(object({ name = string }))

tomap({})

 的特殊之处在于它生成“未知类型的映射”——这里没有足够的信息来推断元素类型应该是什么——但是条件表达式应该注意到一个结果具有已知的元素类型并且另一个则不然,因此它可以自动将未知元素类型的映射专门化为与 
local.clusters
 的类型匹配的已知元素类型的映射。


进行此更改可能会导致 Terraform 开始抱怨配置的不同部分。为 Terraform 提供更多信息将使其能够更具体地了解问题所在,因此新错误很可能与原始错误具有相同的根本原因,但通过附加信息,Terraform 可以对您的情况做出更自信的假设打算这样做,从而更具体地描述问题。

特别请注意,对象映射中的所有对象必须具有“相同的对象类型”,这意味着它们必须具有相同的属性名称和类型。如果某些属性仅适用于集群的子集,您可以将它们设置为

null 以使类型一致,同时仍表示某些属性未填充。

© www.soinside.com 2019 - 2024. All rights reserved.