如何解决Terraform创建SQS与DLQ时集合元素索引无效报错
错误原因
报错是因为aws_sqs_queue.CloudTrail_SQS资源的for_each键集合,和你用于队列策略for_each的toset(var.sqs_queue_names)集合元素不匹配,导致你用each.key索引SQS资源时找不到对应元素。另外你提供的代码还存在两处语法问题:HEREDOC格式的policy没有闭合标记,手写的JSON结构缺少收尾的括号、引号,也会导致执行报错。
修复方案
你需要统一所有相关资源的for_each键,同时实现SQS和DLQ的一一绑定,不需要单独手动配对每个队列,示例配置如下:
1. 调整变量定义
将原本分开的SQS队列名、DLQ队列名变量合并为映射结构,直接在变量中配置每个SQS对应的DLQ属性:
variable "sqs_config" { type = map(object({ dlq_name = string max_receive_count = number })) default = { "CloudTrail_SQS_Management_Event" = { dlq_name = "CloudTrail_Management_Event_DLQ" max_receive_count = 3 } "CloudTrail_SQS_Data_Event" = { dlq_name = "CloudTrail_Data_Event_DLQ" max_receive_count = 3 } } }
2. 定义DLQ资源
直接使用上述变量作为for_each源,保证键和后续SQS资源完全一致:
resource "aws_sqs_queue" "CloudTrail_SQS_DLQ" { for_each = var.sqs_config name = each.value.dlq_name }
3. 定义主SQS资源
直接关联对应DLQ,自动完成配对:
resource "aws_sqs_queue" "CloudTrail_SQS" { for_each = var.sqs_config name = each.key redrive_policy = jsonencode({ deadLetterTargetArn = aws_sqs_queue.CloudTrail_SQS_DLQ[each.key].arn maxReceiveCount = each.value.max_receive_count }) }
4. 定义队列策略
直接引用SQS、DLQ资源作为for_each源,避免索引不匹配问题,同时用jsonencode生成策略避免手写JSON语法错误:
# 主SQS策略 resource "aws_sqs_queue_policy" "Cloudtrail_SQS_Policy" { for_each = aws_sqs_queue.CloudTrail_SQS queue_url = each.value.id policy = jsonencode({ Version = "2012-10-17" Id = "sqspolicy" Statement = [ { Sid = "AllowSQSInvocation" Effect = "Allow" Principal = { AWS = "*" } Action = "sqs:*" Resource = each.value.arn } ] }) } # DLQ策略 resource "aws_sqs_queue_policy" "CloudTrail_SQS_DLQ" { for_each = aws_sqs_queue.CloudTrail_SQS_DLQ queue_url = each.value.id policy = jsonencode({ Version = "2012-10-17" Id = "sqspolicy" Statement = [ { Sid = "DLQ Policy" Effect = "Allow" Principal = { AWS = "*" } Action = "sqs:*" Resource = each.value.arn } ] }) }
上述配置所有资源共用同一套键,完全消除索引不匹配的报错,同时自动实现每个主SQS和对应DLQ的绑定,不需要手动单独指定每个资源的配对关系。
内容的提问来源于stack exchange,提问作者bibi
相关产品推荐
相关产品推荐

