I am creating AWS SQS queues using Terraform. for each service, i need to create two queues, one normal queue and one error queue. The settings for each are mostly the same, but i need to create the error queue first so i can pass its ARN to the normal queue as part of its redrive policy. Instead of creating 10 modules there has to be a better way to loop through replacing just the names. So programming logic... foreach queue in queue_prefixes, create error module, then regular module. Im sure im just not searching right or asking the right question.
sandbox/main.tf
provider "aws" {
region = "us-west-2"
}
module "hfd_sqs_error_sandbox" {
source = "../"
for_each = var.queue_prefixes
name= each.key+"_Error"
}
module "hfd_sqs_sandbox" {
source = "../"
name=hfd_sqs_error_sandbox.name
redrive_policy = jsonencode({
deadLetterTargetArn = hfd_sqs_error_sandbox_this_sqs_queue_arn,
maxReceiveCount = 3
})
}
variables.tf
variable "queue_prefixes" {
description = "Create these queues with the enviroment prefixed"
type = list(string)
default = [
"Clops",
"Document",
"Ledger",
"Log",
"Underwriting",
"Wallet",
]
}
You may want to consider adding a wrapper module that creates both Normal Queue and Dead-Letter Queue. That would make creating resources in order much easier.
Consider this example (with null resources for easy testing):
Root module creating all queues:
# ./main.tf
locals {
queue_prefixes = [
"Queue_Prefix_1",
"Queue_Prefix_2",
]
}
module queue_set {
source = "./modules/queue_set"
for_each = toset(local.queue_prefixes)
name = each.key
}
Wrapper module creating a set of 2 queues: normal + dlq:
# ./modules/queue_set/main.tf
variable "name" {
type = string
}
module dlq {
source = "../queue"
name = "${var.name}_Error"
}
module queue {
source = "../queue"
name = var.name
redrive_policy = module.dlq.id
}
Individual queue resource suitable to create both types of queues:
# ./modules/queue/main.tf
variable "name" {
type = string
}
variable "redrive_policy" {
type = string
default = ""
}
resource "null_resource" "queue" {
provisioner "local-exec" {
command = "echo \"Created queue ${var.name}, redrive policy: ${var.redrive_policy}\""
}
# this is irrelevant to the question, it's just to make null resource change every time
triggers = {
always_run = timestamp()
}
}
output "id" {
value = null_resource.queue.id
}
Now if we run this stack, we can see the resources created in the correct order: