Terraform使用for_each创建SQS与DLQ时如何一一关联并解决索引报错
错误原因
你遇到的报错核心原因有两个:
- 你定义的
sqs_queue_names变量类型是set(string),set是无序、无数字索引的集合结构,你写的{for idx, val in var.sqs_queue_names: idx => val}遍历set时,idx和val会是同一个值(也就是SQS队列名称),不是你预期的0、1这类数字索引,从报错里的each.key is "CloudTrail_SQS_Management_Event"就能验证这点。 aws_sqs_queue.CloudTrail_SQS_DLQ资源用toset(var.dead_queue_names)做for_each,它的实例key是DLQ的名称,你用SQS的名称去索引DLQ资源,自然找不到对应元素,触发无效索引报错。
修复方案
方案1:保持原有列表顺序配对逻辑的修改方式
- 第一步:修改
variables.tf中的变量类型,把set改为list,保证顺序固定、存在数字索引
variable "sqs_queue_names"{ description = "待创建的SQS队列名称列表" type = list(string) } variable "dead_queue_names"{ description = "待创建的死信队列名称列表,顺序需要和sqs_queue_names一一对应" type = list(string) }
- 第二步:修改DLQ资源的
for_each逻辑,用数字索引作为key,和SQS的索引对应
resource "aws_sqs_queue" "CloudTrail_SQS_DLQ"{ for_each = {for idx, val in var.dead_queue_names: idx => val} name = each.value tags = var.default_tags }
- 第三步:修改SQS资源的红rive策略引用方式,直接用索引取对应DLQ的ARN
resource "aws_sqs_queue" "CloudTrail_SQS"{ for_each = {for idx, val in var.sqs_queue_names: idx => val} name = each.value redrive_policy = jsonencode({ deadLetterTargetArn = aws_sqs_queue.CloudTrail_SQS_DLQ[each.key].arn maxReceiveCount = var.max_receive_count }) tags = var.default_tags }
方案2:更稳妥的Map配对方案(推荐)
避免列表顺序写错导致关联错队列的问题,直接显式定义SQS和DLQ的对应关系:
- 第一步:修改
terragrunt.hcl的inputs配置
inputs = { # key为SQS队列名,value为对应绑定的DLQ名称 sqs_dlq_map = { "CloudTrail_SQS_Management_Event" = "CloudTrail_DLQ_Management_Event" "CloudTrail_SQS_Data_Event" = "CloudTrail_DLQ_Data_Event" } max_receive_count = 5 # 替换为你实际配置的重试次数 }
- 第二步:修改
variables.tf的变量定义
variable "sqs_dlq_map" { description = "SQS队列名称和对应死信队列名称的映射关系" type = map(string) } variable "max_receive_count" { description = "消息最大重试次数,超过后转入死信队列" type = number default = 5 }
- 第三步:修改资源定义
# 先批量创建所有死信队列 resource "aws_sqs_queue" "CloudTrail_SQS_DLQ"{ for_each = toset(values(var.sqs_dlq_map)) name = each.value tags = var.default_tags } # 再批量创建SQS队列,直接绑定对应DLQ resource "aws_sqs_queue" "CloudTrail_SQS"{ for_each = var.sqs_dlq_map name = each.key redrive_policy = jsonencode({ deadLetterTargetArn = aws_sqs_queue.CloudTrail_SQS_DLQ[each.value].arn maxReceiveCount = var.max_receive_count }) tags = var.default_tags }
内容的提问来源于stack exchange,提问作者bibi
相关产品推荐
相关产品推荐

