如何解决Terraform使用for_each创建SQS配置redrive policy报错问题
问题根因
- AWS SQS的红rive策略中
deadLetterTargetArn字段仅接受单个ARN字符串,你当前配置通过values(aws_sqs_queue.CloudTrail_SQS_DLQ)[*].arn取出了所有DLQ的ARN组成数组传入,触发AWS参数校验报错。 - 你用两个独立的
set(string)类型变量分别存储队列名和DLQ名,set是无序集合,无法保证普通队列和对应DLQ的顺序匹配,即使强行按索引取值也容易出现配对错误。
解决方案
方案1:最小改动现有配置
无需修改.tfvars的内容,仅调整变量类型和ARN取值逻辑即可:
- 修改
variable.tf,将两个变量的类型从set(string)改为list(string)(list为有序列表,可保证你定义的队列顺序和DLQ顺序一一对应):
variable "sqs_queue_names"{ description = "The name of different SQS to be created" type = list(string) } variable "dead_queue_names"{ description = "The name of different Dead Queues to be created" type = list(string) }
- 修改
main.tf中aws_sqs_queue.CloudTrail_SQS资源的红rive策略,按当前队列的索引取对应DLQ的ARN:
resource "aws_sqs_queue" "CloudTrail_SQS"{ for_each = toset(var.sqs_queue_names) name = each.value redrive_policy = jsonencode({ deadLetterTargetArn = aws_sqs_queue.CloudTrail_SQS_DLQ[var.dead_queue_names[index(var.sqs_queue_names, each.value)]].arn maxReceiveCount = var.max_receive_count }) tags = var.default_tags } resource "aws_sqs_queue" "CloudTrail_SQS_DLQ"{ for_each = toset(var.dead_queue_names) name = each.value tags = var.default_tags }
方案2:显式映射方案(推荐)
直接用map结构绑定普通队列和对应DLQ的关系,完全避免配对错误,后续新增队列也更易维护:
- 修改
.tfvars为映射结构:
sqs_dlq_mapping = { "CloudTrail_SQS_Management_Event" = "CloudTrail_DLQ_Management_Event" "CloudTrail_SQS_Data_Event" = "CloudTrail_DLQ_Data_Event" }
- 修改
variable.tf的变量定义:
variable "sqs_dlq_mapping" { description = "Map of SQS queue name to its corresponding DLQ name" type = map(string) } variable "max_receive_count" { description = "Maximum number of retries before message is sent to DLQ" type = number default = 10 }
- 修改
main.tf的资源定义:
# 优先创建所有DLQ resource "aws_sqs_queue" "CloudTrail_SQS_DLQ" { for_each = toset(values(var.sqs_dlq_mapping)) name = each.value tags = var.default_tags } # 创建普通SQS并绑定对应DLQ resource "aws_sqs_queue" "CloudTrail_SQS" { for_each = var.sqs_dlq_mapping 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 }
注意:如果你的原有配置中未定义
max_receive_count变量,需要在variable.tf中补充该变量的定义,否则会触发变量缺失报错。
内容的提问来源于stack exchange,提问作者bibi
相关产品推荐
相关产品推荐

