鉴于此模块输入:
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
。我确信我错过了一些简单的东西,但我不知道它是什么。也欢迎任何其他方式来做到这一点。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