使用Terraform创建多组带不同IP目标的AWS ALB目标组报错求助
批量创建AWS ALB目标组及对应IP目标的Terraform实现方案
问题场景
需要创建多个AWS ALB目标组,每个目标组对应独立的IP目标集合。已完成目标组的批量创建,但在为每个目标组添加IP目标时遇到类型错误。
现有变量定义
variable "target_group_names" { type = list(string) default = ["tg1", "tg2", "tg3", "tg4"] } variable "target_ips" { type = list(list(string)) default = [ ["10.0.0.1", "10.0.0.2"], ["10.0.1.1", "10.0.1.2", "10.0.1.3"], ["10.0.2.1", "10.0.2.2"], ["10.0.3.1", "10.0.3.2"] ] }
已成功创建目标组的代码
resource "aws_lb_target_group" "target_groups" { count = length(var.target_group_names) name = var.target_group_names[count.index] port = 80 protocol = "HTTP" target_type = "ip" vpc_id = var.aws_vpc_id }
出错的目标附着代码及错误
尝试为每个目标组添加IP目标时使用以下代码:
resource "aws_lb_target_group_attachment" "tg_attachment" { count = length(var.target_group_names) target_group_arn = aws_lb_target_group.target_groups[count.index].arn target_id = var.target_ips[count.index] port = 80 availability_zone = "all" }
触发错误:
"Inappropriate value for attribute "target_id": string required."
原因是target_id需要单个字符串IP,而代码中传递了IP列表。
解决方案
需要为每个IP单独创建aws_lb_target_group_attachment资源,通过扁平化IP列表并关联对应目标组的方式实现批量创建。
方法一:使用局部变量扁平化关联关系
先定义局部变量,将每个IP与所属的目标组索引绑定:
locals { target_attachments = flatten([ for tg_idx, ips in var.target_ips : [ for ip in ips : { tg_idx = tg_idx ip = ip } ] ]) }
然后基于该局部变量创建附着资源:
resource "aws_lb_target_group_attachment" "tg_attachment" { count = length(local.target_attachments) target_group_arn = aws_lb_target_group.target_groups[local.target_attachments[count.index].tg_idx].arn target_id = local.target_attachments[count.index].ip port = 80 availability_zone = "all" }
方法二:使用for_each实现更清晰的资源标识
先将目标组名称与IP列表配对:
locals { target_group_ip_map = zipmap(var.target_group_names, var.target_ips) }
然后通过嵌套遍历生成唯一的资源键,创建附着资源:
resource "aws_lb_target_group_attachment" "tg_attachment" { for_each = { for tg_name, ips in local.target_group_ip_map : "${tg_name}-${ip}" => { tg_name = tg_name ip = ip } for ip in ips } target_group_arn = aws_lb_target_group.target_groups[index(var.target_group_names, each.value.tg_name)].arn target_id = each.value.ip port = 80 availability_zone = "all" }
两种方法都能实现批量创建目标组及对应IP目标,无需逐个编写资源块。for_each方式会生成带有目标组名称+IP的资源标识,更便于后续维护。
内容的提问来源于stack exchange,提问作者user17902257
相关产品推荐
相关产品推荐

