You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Terraform使用for_each创建SQS与DLQ时如何一一关联并解决索引报错

错误原因

你遇到的报错核心原因有两个:

  1. 你定义的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"就能验证这点。
  2. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 21:54:05