Rick james
Rick james

Reputation: 854

Whats the right way to create multiple elements using terraform variables?

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.

directory structure

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",
  ]
}

Upvotes: 3

Views: 2195

Answers (2)

Andrii
Andrii

Reputation: 21

You can also use module for that

module "sqs" {
  source  = "zahornyak/multiple-sqs/aws"
  version = "0.0.3"

  sqs_queues = {

    simple_sqs = {
      name = "simple"
    }

    foo = {
      name = "bar"
    }
    deadletter_sqs = {
      name              = "deadletter_sqs"
      create_deadletter = true
      maxReceiveCount   = 100
    }
}

Or you can take a look how it works : https://registry.terraform.io/modules/zahornyak/multiple-sqs/aws/latest

Upvotes: 0

Max Ivanov
Max Ivanov

Reputation: 6581

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:

enter image description here

Upvotes: 5

Related Questions