简体   繁体   中英

How to resolve the error message when adding SQS redrive policy for deadletter queue created using for_each

I want terraform to associate my SQS Management Event with my DLQ management event and i want the same thing done with SQS Data Event and DLQ Data Event.I am getting error messages when i run apply on my code below.please I need some help.

.tfvars

sqs_queue_names = ["CloudTrail_SQS_Management_Event", "CloudTrail_SQS_Data_Event"]

dead_queue_names = ["CloudTrail_DLQ_Management_Event", "CloudTrail_DLQ_Data_Event"]
variable.tf 

variable "sqs_queue_names"{
  description = "The name of different SQS to be created"
  type        = set(string)
}

variable "dead_queue_names"{
  description = "The name of different Dead Queues to be created"
  type        = set(string)
}
main.tf

resource "aws_sqs_queue" "CloudTrail_SQS"{

    for_each                   = var.sqs_queue_names
    name                       = each.value
    redrive_policy = jsonencode({
        deadLetterTargetArn    = values(aws_sqs_queue.CloudTrail_SQS_DLQ)[*].arn
        maxReceiveCount        = var.max_receive_count
    })

    tags = var.default_tags
    
}

resource "aws_sqs_queue" "CloudTrail_SQS_DLQ"{

    for_each                   = var.dead_queue_names
    name                       = each.value
   
    tags = var.default_tags
}
ERROR MESSAGES:
Error: error creating SQS Queue (CloudTrail_SQS_Management_Event): InvalidParameterValue: Value {"deadLetterTargetArn":["arn:aws:sqs:us-east-1:123456789012:CloudTrail_DLQ_Data_Event","arn:aws:sqs:us-east-1:123456789012:CloudTrail_DLQ_Management_Event"],"maxReceiveCount":10} for parameter RedrivePolicy is invalid. Reason: Invalid value for deadLetterTargetArn.
│       status code: 400, request id: 9663b896-d86f-569e-92e2-e17152c2db26
│ 
│   with aws_sqs_queue.CloudTrail_SQS["CloudTrail_SQS_Management_Event"],
│   on main.tf line 5, in resource "aws_sqs_queue" "CloudTrail_SQS":
│    5: resource "aws_sqs_queue" "CloudTrail_SQS"{
│ 
╵
╷
│ Error: error creating SQS Queue (CloudTrail_SQS_Data_Event): InvalidParameterValue: Value {"deadLetterTargetArn":["arn:aws:sqs:us-east-1:123456789012:CloudTrail_DLQ_Data_Event","arn:aws:sqs:us-east-1:123456789012:CloudTrail_DLQ_Management_Event"],"maxReceiveCount":10} for parameter RedrivePolicy is invalid. Reason: Invalid value for deadLetterTargetArn.
│       status code: 400, request id: 88b8e4c5-1d50-5559-92f8-bd2297fd231f
│ 
│   with aws_sqs_queue.CloudTrail_SQS["CloudTrail_SQS_Data_Event"],
│   on main.tf line 5, in resource "aws_sqs_queue" "CloudTrail_SQS":
│    5: resource "aws_sqs_queue" "CloudTrail_SQS"{

The problem here is that you are not associating the dead letter queue with the corresponding SQS queue. values(aws_sqs_queue.CloudTrail_SQS_DLQ)[*].arn - this essentially passes every dead letter queue ARN for each SQS queue, it does not passes to correct ARN only.

In order to overcome this, I suggest creating a module where we can tie together the SQS queue and its DLQ. We can name for now my_sqs :

my_sqs/variables.tf :

variable "sqs_queue_name"{
  description = "The name of different SQS to be created"
  type        = string
}

variable "dead_queue_name"{
  description = "The name of different Dead Queues to be created"
  type        = string
}

variable "max_receive_count" {
    type = number
}


my_sqs/main.tf :

resource "aws_sqs_queue" "sqs" {
  name  = var.sqs_queue_name

  redrive_policy = jsonencode({
    deadLetterTargetArn = aws_sqs_queue.dlq.arn
    maxReceiveCount     = var.max_receive_count
  })
}

resource "aws_sqs_queue" "dlq" {
  name  = var.dead_queue_name
}

Now we can use this module like this:

variables.tf :

# Please not, we are tying the SQS and the DQL together here as well.
variable "queue_names" {
  default = [
    {
      sqs_name = "CloudTrail_SQS_Management_Event"
      dlq_name = "CloudTrail_DLQ_Management_Event"
    },
    {
      sqs_name = "CloudTrail_SQS_Data_Event"
      dlq_name = "CloudTrail_DLQ_Data_Event"
    }
  ]
}

From the main.tf we call the module we created above:

main.tf :

module "my_sqs" {
  source = "./my_sqs"
  for_each = {
    for sqs, dlq in var.queue_names : sqs => dlq
  }
  sqs_queue_name    = each.value.sqs_name
  dead_queue_name   = each.value.dlq_name
  max_receive_count = 4
}

Please note, this example may work with the latest Terraform versions. It may not work with an older version which does not support having a for_each on a module .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM