【问题标题】:Terraform filter based on map's minor key on lists of maps基于地图列表中地图次要键的 Terraform 过滤器
【发布时间】:2021-07-07 09:22:05
【问题描述】:

我有 2 个地图列表。请允许我向您展示。 让我们称之为values_default

 [{A="abc", B="10"}]

new_config:

[
  {A="abc", B="9"},
  {A="cdea", B="1000"},
  {A="asd", B="otra cosa"},
]

然后我需要合并或连接它们,但以一种特殊的方式。 我需要做的是过滤掉A的重复项,取A的最小值为B这就是最终想要的结果,也许还有其他方法可以做这是我正在尝试的,但只要我得到这两个输入和预期的结果,就可以了。对于上面的示例,结果应该是:

[
  {A="abc", B="9"},
  {A="cdea", B="1000"},
  {A="asd", B="otra cosa"},
]

在这里,我们采用了具有较低 B 值的 A。 到目前为止我是这样做的:

locals {
  tmp_cluster_parameters = concat(var.new_config, var.values_default)
  final_cluster_parameters = distinct([for i in local.tmp_cluster_parameters: {
     name = i.A
     value = i.B
  }])
}

这意味着我只能在地图完全相同时过滤掉 (A & B)。我尝试了更多的东西,但无法弄清楚如何更接近我的目标。对于上面的示例,这不会过滤掉任何内容。结果是这样的:

 [
  {A="abc", B="10"},
  {A="abc", B="9"},
  {A="cdea", B="1000"},
  {A="asd", B="otra cosa"}
 ]

理想情况下它应该删除{A="abc", B="10"}

编辑 1: 回答来自@macin 的问题。这是今天的实际字段和一些进一步的解释

variable "cluster_parameters_default" {
  description = ""
  type = list(map(string))
  default = [
        {
            name = "wait_timeout"
            value = "800" 
        }
    ]
}

我以后会有一些默认参数。这些是 MySQL 参数组的默认值。这里cluster_parameters_defaultvalues_defaultnameAvalue 是B。我们的想法是有一些ENFORCEABLE MySQL 配置默认值,我们可以根据允许的值覆盖更大或更小的值。此默认设置将为许多 DB 的许多配置创建一个允许的围墙花园。例如,安全团队可能要求我们将wait_timeout 设置为小于 15 分钟。现在,我们还应该能够始终拥有一个不同的值,该值小于安全团队要求的 15 分钟。除此之外,还有更多来自new_config 的值。我不想解释这一切,因为这是一个更大项目的一部分。这意味着它将更加复杂。这就是为什么values_defaultAB。我可以更改此变量 values_default 的格式,因为它是我自己的变量,但我无法更改 new_config,因为它被我无法控制的许多其他事物使用。

Edit2:其他数据集(DSx)。

DS1: values_default:

[{A="abc", B="10"}]

然后new_config:

[
  {A="cdea", B="1000"},
  {A="asd", B="otra cosa"},
]

这里想要的输出应该是:

[
  {A="abc", B="10"},
  {A="cdea", B="1000"},
  {A="asd", B="otra cosa"},
]

DS2:

values_default:

[
{A="abc", B="10"},
{A="cdea", B="111"},
]

然后new_config:

[
  {A="abc", B="8"},
  {A="cdea", B="1000"},
  {A="asd", B="otra cosa"},
]

在这种情况下,所需的输出是:

[
  {A="abc", B="8"},
  {A="cdea", B="111"},
  {A="asd", B="otra cosa"},
]

DS3:

values_default:

[
{A="abc", B="10"},
{A="cdea", B="111"},
]

那么 new_config 在这种情况下不会被声明。

在这种情况下,所需的输出是values_default

[
{A="abc", B="10"},
{A="cdea", B="111"},
]

【问题讨论】:

  • 你能提供更好的例子吗? values_default 没有任何重复的开头,所以我不明白你想要完成什么。
  • 添加了一个编辑@Marcin。谢谢你的提问。
  • 我不明白-“取最小的B”?最小的什么,怎么做?你能举个例子来选择这样的“最小”值吗?
  • 我们有一个重复的键 A 在这种情况下 A="abc" 用于该键,如果在 values_default new_config 中都存在重复,那么我们将选择其中一个。较小的一个基于B 的值。在上面的例子中{A="abc", B="9"}。我将进行编辑以使其更清晰。
  • @Marcin 添加了有关您的问题的更多详细信息。再次非常感谢!

标签: terraform maps


【解决方案1】:

不确定我是否完全理解,但仅基于您的示例,您可以使用(ps min 仅适用于数字,我不知道您想如何使用 min 比较字符串):



variable "values_default" {
  default = [
{A="abc", B="10"},
{A="cdea", B="111"},
]
}

# FOR CASE 3, but works for other cases as well
variable "new_config" {
    default = []
}


  locals {
  
    # get keys avaiable in our vars
    keys_default =   [for v in var.values_default: v.A]
    keys_new =   [for v in var.new_config: v.A]
    keys_all = distinct(concat(local.keys_default, local.keys_new))
    
    # find common keys that need to be potentailly overwritten
    # using min of B values
    keys_common = setintersection(local.keys_default, local.keys_new)

    # construct overwritten values, if there are any
    # keys must be unique in both vars (no duplicates present)
    overwritten_values = [ for idx, key in local.keys_common:
       {
              A = key
              B = min([for v in var.values_default: v.B if v.A == key][0], 
                      [for v in var.new_config: v.B if v.A == key][0])
       }
    ]
    
    keys_different = setsubtract(local.keys_all, local.keys_common) 

    new_values =  [ for idx, key in local.keys_different:
       {
              A = key
              B = concat([for v in var.values_default: v.B if v.A == key], 
                        [for v in var.new_config: v.B if v.A == key])
       }
    ]
}

output "test" {
 value = concat(local.overwritten_values, local.new_values)
}


给予:

test = [
  {
    "A" = "abc"
    "B" = [
      "10",
    ]
  },
  {
    "A" = "cdea"
    "B" = [
      "111",
    ]
  },
]

【讨论】:

  • 我认为这正是我想要的。它适用于我所做的一些测试。我现在只处理数字。
  • @Abel 给我一点时间。我看到如果values_default 有两个值(不是示例中的一个),就会有重复。
  • 我会测试并提供反馈。
  • @Abel 感谢您告诉我。您可以使用新示例更新问题,或创建特定于它的新示例。可悲的是,目前我无法检查它。明天我可以再看看。
  • @Abel 我修改了代码以处理新案例。答案中的示例适用于 DS3。但是由于您的输入数据(列表而不是地图,B 中字符串的使用等),这变得非常复杂。这可能会在未来导致更多问题,因此我建议重新考虑您的设计选择,因为 TF 在对输入数据进行复杂操作方面非常差。
猜你喜欢
  • 2021-05-03
  • 2015-04-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多