Terraform 嵌套 for 循环产生意外结果

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

鉴于此模块输入:

variable "port_mapping_metadata" {
  type = map(object({
    target_type                       = optional(string, "instance")
    ssl_policy                        = optional(string)
    listener_cert_arn                 = optional(string)
    additional_SNI_listener_cert_arns = optional(list(string),[])
    ...

我正在尝试为

port_mapping_metadata
中的每个项目(如果不为空)创建一个资源(如果不为空,则键可能在资源中重复)。因此对于以下输入:
additional_SNI_listener_cert_arns

我期望以下 for_each 结果:

"bar" = { vpc_name = "foo" name = "bar" type = "application" port_mapping_metadata = { "forward" = { instance_names = ["inst"] listener_cert_arn = "arn:aws:acm:us-east-1:1234:certificate/abcd" additional_SNI_listener_cert_arns = ["arn:aws:acm:us-east-1:1234:certificate/defg", "arn:aws:acm:us-east-1:1234:certificate/hijk"] "bax" = { vpc_name = "foo" name = "bax" type = "application" port_mapping_metadata = { "forward" = { instance_names = ["inst2"] listener_cert_arn = "arn:aws:acm:us-east-1:1234:certificate/abcd" additional_SNI_listener_cert_arns = ["arn:aws:acm:us-east-1:1234:certificate/zle"] (under another key) "bar" = { vpc_name = "foo" name = "bar" type = "application" port_mapping_metadata = { "forward" = { instance_names = ["inst"] listener_cert_arn = "arn:aws:acm:us-east-1:1234:certificate/abcd"

我尝试使用 for_each 编写资源,如下所示:

{ "bar-0" = "arn:aws:acm:us-east-1:1234:certificate/defg" "bar-1" = "arn:aws:acm:us-east-1:1234:certificate/hijk" "bax-0" = "arn:aws:acm:us-east-1:1234:certificate/zle" }

但由于某种原因我收到错误:

resource "aws_lb_listener_certificate" "additional_SNI_listener_certs" { for_each = { for k, v in var.port_mapping_metadata : k => { for index, cert_arn in try(v.additional_SNI_listener_cert_arns, []) : "${k}-${index}" => cert_arn } if try(v.additional_SNI_listener_cert_arns, []) != [] && try(v.additional_SNI_listener_cert_arns, null) != null } ##this _should_ be "{ "listener_name-0" = "arn1" , ... }" listener_arn = aws_lb_listener.all[element(split("-", each.key), 0)].arn ##this should be "listener_name" certificate_arn = each.value ##this should be "arn1" }

我不明白为什么资源中的
│ Error: Incorrect attribute value type │ │ on .terraform/modules/load_balancer/load_balancer.tf line 235, in resource "aws_lb_listener_certificate" "additional_SNI_listener_certs": │ 235: certificate_arn = each.value │ ├──────────────── │ │ each.value is object with no attributes │ │ Inappropriate value for attribute "certificate_arn": string required.

不是单个字符串

each.value
。我确信我错过了一些简单的东西,但我不知道它是什么。也欢迎任何其他方式来做到这一点。
    

terraform
1个回答
0
投票
arn1

正在获取以下地图作为输入。但是,您必须通过添加 terraform 输出来打印表达式的结果来验证它。

for_each

现在根据您的要求,将以下地图输入到
{ bar = { "bar-0" = "arn:aws:acm:us-east-1:1234:certificate/defg" "bar-1" = "arn:aws:acm:us-east-1:1234:certificate/hijk" } bax = { "bax-0" = "arn:aws:acm:us-east-1:1234:certificate/zle" } }

for_each

需要将代码修改为以下

{ "bar-0" = "arn:aws:acm:us-east-1:1234:certificate/defg" "bar-1" = "arn:aws:acm:us-east-1:1234:certificate/hijk" "bax-0" = "arn:aws:acm:us-east-1:1234:certificate/zle" }

此外,正如我之前建议的那样,添加 
locals { original_for_each_expr = { for k, v in var.port_mapping_metadata : k => { for index, cert_arn in try(v.additional_SNI_listener_cert_arns, []) : "${k}-${index}" => cert_arn } if try(v.additional_SNI_listener_cert_arns, []) != [] && try(v.additional_SNI_listener_cert_arns, null) != null } desired_for_each_expr = zipmap( flatten( [ for i in local.original_for_each_expr : keys(i) ] ), flatten( [ for i in local.original_for_each_expr : values(i) ] ) ) } resource "aws_lb_listener_certificate" "additional_SNI_listener_certs" { for_each = local.desired_for_each_expr ... }

来查看是否从表达式中获取所需的值并将其传递给

terraform outputs
for_each

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