Error regarding collection value (whatever that is)

Sorry to trouble everyone again, but have inherited some TF scripts and need to make an amendment and at a loss as to what is going on.

An AWS policy document is declared, with a fixed set of permissions:

data "aws_iam_policy_document" "sqs_task_policy" {
  dynamic "statement" {
    for_each = var.queues
    content {
      actions = [
        "sqs:SendMessage",
        "sqs:ReceiveMessage"
      ]
      effect  = "Allow"
      resources = [
        "arn:aws:sqs:${data.aws_region.current.name}:${data.aws_caller_identity.current.account_id}:${join("_", [var.name, statement.value["name"], statement.value["purpose"]])}"
      ]
    }
  }
}

The variable queue is declared from a local variable in the calling module (and includes a number of SQS queue names), i.e. queue = local.sqs_queues:

  sqs_queues = {
    create_company_check_sqs = {
      name        = "create_company_check_queue"
      purpose     = "start"
    }
    }
    create_person_check_sqs = {
      name        = "create_person_check_queue"
      purpose     = "start"
    }
}

All is working fine at this point, but some of the queues now need to have additional permissions. I set the local variable to:

  sqs_queues = {
    create_company_check_sqs = {
      name        = "create_company_check_queue"
      purpose     = "start"
      permissions = ["sqs:SendMessage", "sqs:ReceiveMessage"]
    }
    create_person_check_sqs = {
      name        = "create_person_check_queue"
      purpose     = "start"
      permissions = ["sqs:SendMessage", "sqs:ReceiveMessage"]
    }
}

Updated the data declaration to include:

actions = statement.value["permissions"]

This works perfectly well in my sandbox/test AWS account, but have issues reported in QA account:

╷
│ Error: Invalid index
│
│   on modules/services/sqs/data.tf line 23, in data "aws_iam_policy_document" "sqs_task_policy":
│   23:       actions = statement.value["permissions"]
│     ├────────────────
│     │ statement.value is object with 2 attributes
│
│ The given key does not identify an element in this collection value.

I’ve not been able to work out exactly what’s wrong, or what the correct syntax is to get this to work in the QA account.

Any help would be gratefully received.

Hi @glenn.comiskey,

In your first example I see for_each = var.queues, and so I’m inferring that your module has a variable declaration something like this:

variable "queues" {
  type = map(object({
    name        = string
    purpose     = string
    permissions = set(string)
  }))
}

I don’t know enough about how the configurations vary between your environments to guess why it might be behaving differently in QA vs. sandbox, but I think I’d start debugging here by making sure the variable declaration’s type constraint seems correct, since your error message says that the object only has two attributes, whereas a type constraint like the one I showed above would cause the object to have three attributes.

As always @apparentlymart, thanks for the prompt reply and help.

FYI, the original variable declaration was simply:
variable "queues" {}

This seemed to work perfectly well, even given that one of the queue declarations had three values rather than simply two:

    hard_delete_diff_file_sqs = {
      name        = "hard_delete_diff_file_queue"
      purpose     = "start"
    }
    add_notification_sqs = {
      name        = "add_notification_queue"
      purpose     = "start.fifo"
      is_fifo     = true
    }

However, having added a variable declaration, and accounting for four values, all appears to be working:

variable "queues" {
  type = map(object({
    name        = string
    purpose     = string
    is_fifo     = bool
    permissions = set(string)
  }))
}
    add_notification_sqs = {
      name        = "add_notification_queue"
      purpose     = "start.fifo"
      is_fifo     = true
      permissions = ["sqs:SendMessage", "sqs:ReceiveMessage"]
    }
    check_callback = {
      name        = "check",
      purpose     = "callback"
      is_fifo     = false
      permissions = ["sqs:GetQueueUrl", "sqs:GetQueueAttributes", "sqs:ListQueueTags", "sqs:SendMessage", "sqs:ReceiveMessage"]
    }

Was a little reluctant to mess around too much with the files given that some highly paid devops engineers prepared the TF scripts, and I’m still learning Terraform.

Again, thanks for the help. Very much appreciate it.