使用带有for_each的资源,并为resource中的单个字符串条目使用字符串列表



我试图通过for_eah方法创建负载均衡器目标组附件,以确保自己大量的编码时间。然而,我似乎不能在for_each中使用for_each。有人能指点一下吗?


附加说明:

资源aws_lb_target_group_attachment只接受一个字符串形式的target_id,它指向一个实例ID。

所以在这种情况下,我希望资源被创建两次。对target_id列表中的每个target_id执行一次。


locals {
dev_alb_defaults = {
vpc_id      = local.dev_alb_vpc_id
health_check_enabled              = true
health_check_interval             = 30
health_check_timeout              = 5
health_check_healthy_threshold    = 2
health_check_unhealthy_threshold  = 2
health_check_matcher              = 200
}
dev_alb_targets = {
i-am-service = {
tg_port = 443
target_ids = [ "i-0123456789ab", "i-0123456789bc" ]
}
}
}
resource "aws_lb_target_group" "dev_lb_tg" {
for_each = { for k, v in local.dev_alb_targets : k => v }
name     = "${var.customer}-${var.dev_prefix}-${try(each.value.name, each.key)}-tg"
port     = try(each.value.tg_port, null)
protocol = try(each.value.tg_protocol, null)
vpc_id   = try(each.value.vpc_id,local.dev_alb_defaults.vpc_id, null)
health_check {
enabled             = try(each.value.health_check_enabled, local.dev_alb_defaults.health_check_enabled, false)
path                = try(each.value.health_check_path, local.dev_alb_defaults.health_check_path, null)
port                = try(each.value.health_check_port, each.value.tg_port, null)
protocol            = try(each.value.health_check_protocol, local.dev_alb_defaults.health_check_protocol, null)
interval            = try(each.value.health_check_interval, local.dev_alb_defaults.health_check_interval, null)
timeout             = try(each.value.health_check_timeout, local.dev_alb_defaults.health_check_timeout, null)
healthy_threshold   = try(each.value.health_check_healthy_threshold, local.dev_alb_defaults.health_check_healthy_threshold, null)
unhealthy_threshold = try(each.value.health_check_unhealthy_threshold, local.dev_alb_defaults.health_check_unhealthy_threshold, null)
matcher             = try(each.value.health_check_matcher, local.dev_alb_defaults.health_check_matcher, null)
}
}
resource "aws_lb_target_group_attachment" "dev_lb_tg" {
for_each = { for k, v in local.dev_alb_targets : k => v }
target_group_arn = aws_lb_target_group.dev_lb_tg["${try(each.value.name, each.key)}"].arn
port             = try(each.value.tg_port, null)
target_id        = try(each.value.target_ids, null)
}
}

我希望它的效果是:只创建1个目标组和创建2个aws_lb_target_group_attachments。它会创建1个目标组,但不会创建2个目标组附件。我已经尝试了变体,我使用tolist() tg_instances或tostring()但是我不能让它接受输入。

╷
│ Error: Incorrect attribute value type
│ 
│   on dev-alb.tf line 288, in resource "aws_lb_target_group_attachment" "dev_lb_tg":
│  288:   target_id        = each.value.target_ids
│     ├────────────────
│     │ each.value.target_ids is list of string with 2 elements
│ 
│ Inappropriate value for attribute "target_id": string required.
╵

我现在有一个中间解决方案,我不喜欢使用,我想浓缩成一个合适的解决方案:

locals {
dev_alb_defaults = {
target_id1 = "i-0123456789ab"
target_id2 = "i-0123456789bc"
}
dev_alb_targets = {
i-am-service = {
tg_port = 443
}
}
}
resource "aws_lb_target_group_attachment" "dev_lb_tg1" {
for_each = { for k, v in local.dev_alb_targets : k => v }
target_group_arn = aws_lb_target_group.dev_lb_tg["${try(each.value.name, each.key)}"].arn
port             = try(each.value.tg_port, null)
target_id        = local.dev_alb_defaults.target_id1
}
}
resource "aws_lb_target_group_attachment" "dev_lb_tg2" {
for_each = { for k, v in local.dev_alb_targets : k => v }
target_group_arn = aws_lb_target_group.dev_lb_tg["${try(each.value.name, each.key)}"].arn
port             = try(each.value.tg_port, null)
target_id        = local.dev_alb_defaults.target_id2
}
}

你必须把压平你的局部变量:

locals {
dev_alb_targets = {
i-am-service = {
tg_port = 443
target_ids = [ "i-0123456789ab", "i-0123456789bc" ]
}
}

flat_dev_alb_targets = merge([
for service, details in local.dev_alb_targets: {
for target in details.target_ids:
"${service}-${target}" => {
tg_port = details.tg_port
target_id = target
}
}
]...) # no NOT remove the dots 
}

然后

resource "aws_lb_target_group_attachment" "dev_lb_tg" {
for_each         = local.flat_dev_alb_targets
target_group_arn = aws_lb_target_group.dev_lb_tg["${try(each.value.name, each.key)}"].arn
port             = try(each.value.tg_port, null)
target_id        = try(each.value.target_id, null)
}
}

而且你的代码没有显示each.value.name是什么,所以很难推测如何使其扁平化的全部方面和要求。

最新更新