I’m unsure what I’m doing wrong. I have terraform module code below ,I want to create 2 SQS with deadletter queue for each SQS together with necessary policy for SQS and DeadQueue.
resource "aws_sqs_queue" "CloudTrail_SQS"{
for_each = var.sqs_queue_names
name = each.value
visibility_timeout_seconds = var.visibility_timeout_seconds
max_message_size = var.max_message_size
message_retention_seconds = var.message_retention_seconds
delay_seconds = var.delay_seconds
receive_wait_time_seconds = var.receive_wait_time_seconds
redrive_policy = jsonencode({
deadLetterTargetArn = aws_sqs_queue.CloudTrail_SQS_DLQ[each.key].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
visibility_timeout_seconds = var.visibility_timeout_seconds
max_message_size = var.max_message_size
message_retention_seconds = var.message_retention_seconds
delay_seconds = var.delay_seconds
receive_wait_time_seconds = var.receive_wait_time_seconds
tags = var.default_tags
}
data "aws_iam_policy_document" "policy_document"{
statement{
actions = [
"sqs:DeleteMessage",
"sqs:GetQueueUrl",
"sqs:ReceiveMessage",
"sqs:SendMessage",
"sqs:SetQueueAttributes"
]
effect = "Allow"
resources =[
"${aws_sqs_queue.CloudTrail_SQS[each.key].arn}"
]
}
resource "aws_sqs_queue_policy" "Cloudtrail_SQS_Policy" {
queue_url = aws_sqs_queue.CloudTrail_SQS[each.key].id
policy = <<POLICY
{
"Version": "2012-10-17",
"Id": "sqspolicy"
"Statement": [
{
"Sid": "AllowSQSInvocation",
"Effect": "Allow",
"Principal": {"AWS":"*"},
"Action": "sqs:*",
"Resource": "${aws_sqs_queue.CloudTrail_SQS[each.key].arn}"
Below is my terragrunt.hcl
terraform {
source = "../../../../..//module"
}
include {
path = find_in_parent_folders()
}
inputs = {
cloudtrail_event_log_bucket_name = "aws-cloudtrailbucket-sqs-logs"
sqs_queue_names = ["CloudTrail_Event_One", "CloudTrail_SQS_Event_Two"]
dead_queue_names = ["CloudTrail_DLQ_Event_One", "CloudTrail_DLQ_Event_Two"]
}
My terragrunt plan returns this. it complains about for_each, but unsure what to do with it.
these are some of the error me:
1.....on iam.tf line 2, in resource "aws_sqs_queue_policy" "Cloudtrail_SQS_Policy":
│ 2: queue_url = aws_sqs_queue.CloudTrail_SQS.id
│
│ Because aws_sqs_queue.CloudTrail_SQS has "for_each" set, its attributes
│ must be accessed on specific instances.
│
│ For example, to correlate with indices of a referring resource, use:
│ aws_sqs_queue.CloudTrail_SQS[each.key]
2..... Missing resource instance key
│
│ on iam.tf line 14, in resource "aws_sqs_queue_policy" "Cloudtrail_SQS_Policy":
│ 14: "Resource": "${aws_sqs_queue.CloudTrail_SQS.arn}",
│
│ Because aws_sqs_queue.CloudTrail_SQS has "for_each" set, its attributes
│ must be accessed on specific instances.
│
│ For example, to correlate with indices of a referring resource, use:
│ aws_sqs_queue.CloudTrail_SQS[each.key]
3...Error: Missing resource instance key
│
│ on output.tf line 10, in output "sqs_queue_arn":
│ 10: value = aws_sqs_queue.CloudTrail_SQS.arn
│
│ Because aws_sqs_queue.CloudTrail_SQS has "for_each" set, its attributes
│ must be accessed on specific instances.
Hi @darekorex!
I tried to find in your code snippets the specific lines that are included in the error messages, but I couldn’t find it. Is there another part of the configuration you didn’t include, which these error messages are referring to?
Since Terragrunt isn’t a HashiCorp project we can’t directly help with that here, but fortunately in this case I don’t think that’s important because it seems like what you have is essentially equivalent to directly running Terraform CLI with a .tfvars
file containing the following:
cloudtrail_event_log_bucket_name = "aws-cloudtrailbucket-sqs-logs"
sqs_queue_names = ["CloudTrail_Event_One", "CloudTrail_SQS_Event_Two"]
dead_queue_names = ["CloudTrail_DLQ_Event_One", "CloudTrail_DLQ_Event_Two"]
I’m going to assume that’s true while we work on this, but if that doesn’t seem like a valid assumption based on what you know about Terragrunt then please let me know!
each.key can only be used in conjunction with for_each.
In your case, aws_sqs_queue_policy. Cloudtrail_SQS_Policy and aws_iam_policy_document. policy_document doesn’t have for_each, so you can’t use them there.
you may want to use keys function in those two resources.
my code snippet and the correspondent error message below
```
resource "aws_sqs_queue" "CloudTrail_SQS"{
for_each = var.sqs_queue_names
name = each.value
redrive_policy = jsonencode({
deadLetterTargetArn = aws_sqs_queue.CloudTrail_SQS_DLQ[each.key].arn
maxReceiveCount = var.max_receive_count
})
}
~~~ Error: Missing resource instance key on deadLetterTargetArn
```
resource "aws_sqs_queue" "CloudTrail_SQS_DLQ"{
for_each = var.dead_queue_names
name = each.value
}
~~~ Error: Missing resource instance key
~~~resource "aws_sqs_queue_policy" "Cloudtrail_SQS_Policy" {
queue_url = aws_sqs_queue.CloudTrail_SQS[each.key].id
policy = <<POLICY
{
"Version": "2012-10-17",
"Id": "sqspolicy",
"Statement": [
{
"Sid": "AllowSQSInvocation",
"Effect": "Allow",
"Principal": {"AWS":"*"},
"Action": "sqs:*",
"Resource": "${aws_sqs_queue.CloudTrail_SQS[each.key].arn}"
~~~on iam.tf line 14, in resource "aws_sqs_queue_policy" "Cloudtrail_SQS_Policy":
│ 14: "Resource": "${aws_sqs_queue.CloudTrail_SQS.arn}",
│
│ Because aws_sqs_queue.CloudTrail_SQS has "for_each" set, its attributes
│ must be accessed on specific instances.
~~~data "aws_iam_policy_document" "policy_document"{
statement{
actions = [
"sqs:ReceiveMessage",
"sqs:SendMessage"
]
effect = "Allow"
resources =[
"${aws_sqs_queue.CloudTrail_SQS[each.key].arn}"
error message:
~~~on iam_role.tf line 40, in data "aws_iam_policy_document" "policy_document":
│ 40: "${aws_sqs_queue.CloudTrail_SQS[each.key].arn}"
│
│ The "each" object can be used only in "module" or "resource" blocks, and
│ only when the "for_each" argument is set.
~~~output "sqs_queue_arn" {
value = aws_sqs_queue.CloudTrail_SQS.arn
description = "The ARN of the SQS queue."
}
Error message:
~~~.Error: Missing resource instance key
│
│ on output.tf line 10, in output "sqs_queue_arn":
│ 10: value = aws_sqs_queue.CloudTrail_SQS.arn
│
│ Because aws_sqs_queue.CloudTrail_SQS has "for_each" set, its attributes
│ mu
@ausmartway please if you don’t mind can you suggest how to use keys function in my case?and why I am getting the same error on my resource below
data "aws_iam_policy_document" "policy_document"{
statement{
actions = [
"sqs:DeleteMessage",
"sqs:GetQueueUrl",
"sqs:ReceiveMessage",
"sqs:SendMessage",
"sqs:SetQueueAttributes"
]
effect = "Allow"
resources =[
"${aws_sqs_queue.Trail_SQS.arn}"
]
```
resource "aws_sqs_queue_policy" "Cloudtrail_SQS_Policy" {
queue_url = aws_sqs_queue.CloudTrail_SQS[each.key].id
policy = <<POLICY
{
"Version": "2012-10-17",
"Id": "sqspolicy",
"Statement": [
{
"Sid": "AllowSQSInvocation",
"Effect": "Allow",
"Principal": {"AWS":"*"},
"Action": "sqs:*",
"Resource": "${aws_sqs_queue.CloudTrail_SQS[each.key].arn}
```
thanks indvance
@apparentlymart below is my complete code that terraform is complaining about accessing specific attribute of the instances and below my code is the error generated
Terragrunt.hcl == .tfvars
sqs_queue_name = ["CloudTrail_Event_One", "CloudTrail_SQS_Event_Two"]
dead_queue_names = ["CloudTrail_DLQ_Event_One", "CloudTrail_DLQ_Event_Two"]
variable.tf
variable "sqs_queue_names"{
description = "the name of queues to be created"
type = set(string)
}
variable "dead_queue_names"{
description = "the name of dead queues to be created"
type = set(string)
}
output.tf
output "dead_letter_queue_arn" {
value = aws_sqs_queue.CloudTrail_SQS_DLQ.arn
description = "The ARN of the dead queue."
}
output "sqs_queue_url"{
description = "The URL for the created Amazon SQS queue"
value = aws_sqs_queue.CloudTrail_SQS.url
}
output "dead_letter_queue_url"{
value = aws_sqs_queue.CloudTrail_SQS_DLQ.url
description = "The URL for the created dead letter queue"
}
output "sqs_queue_arn" {
value = aws_sqs_queue.CloudTrail_SQS.arn
description = "The ARN of the SQS queue."
}
resource "aws_sqs_queue_policy" "Cloudtrail_SQS_Policy" {
queue_url = aws_sqs_queue.CloudTrail_SQS.id
policy = <<POLICY
{
"Version": "2012-10-17",
"Id": "sqspolicy",
"Statement": [
{
"Sid": "AllowSQSInvocation",
"Effect": "Allow",
"Principal": {"AWS":"*"},
"Action": "sqs:*",
"Resource": "${aws_sqs_queue.CloudTrail_SQS.arn}"
resource "aws_sqs_queue_policy" "Cloudtrail_SQS_Policy" {
queue_url = aws_sqs_queue.CloudTrail_SQS.id
policy = <<POLICY
{
"Version": "2012-10-17",
"Id": "sqspolicy",
"Statement": [
{
"Sid": "AllowSQSInvocation",
"Effect": "Allow",
"Principal": {"AWS":"*"},
"Action": "sqs:*",
"Resource": "${aws_sqs_queue.CloudTrail_SQS.arn}"
resource "aws_sqs_queue" "CloudTrail_SQS"{
for_each = var.sqs_queue_names
name = each.value
redrive_policy = jsonencode({
deadLetterTargetArn = aws_sqs_queue.CloudTrail_SQS_DLQ[each.key].arn
maxReceiveCount = var.max_receive_count
})
}
resource "aws_sqs_queue" "CloudTrail_SQS_DLQ"{
for_each = var.dead_queue_names
name = each.value
}
Error messages generated
1.....Error: Missing resource instance key
│
│ on iam.tf line 2, in resource "aws_sqs_queue_policy" "Cloudtrail_SQS_Policy":
│ 2: queue_url = aws_sqs_queue.CloudTrail_SQS.id
│
│ Because aws_sqs_queue.CloudTrail_SQS has "for_each" set, its attributes
│ must be accessed on specific instances.
│
│ For example, to correlate with indices of a referring resource, use:
│ aws_sqs_queue.CloudTrail_SQS[each.key]
2...Error: Missing resource instance key
│
│ on iam.tf line 14, in resource "aws_sqs_queue_policy" "Cloudtrail_SQS_Policy":
│ 14: "Resource": "${aws_sqs_queue.CloudTrail_SQS.arn}",
│
│ Because aws_sqs_queue.CloudTrail_SQS has "for_each" set, its attributes
│ must be accessed on specific instances.
│
│ For example, to correlate with indices of a referring resource, use:
│ aws_sqs_queue.CloudTrail_SQS[each.key]
3.........
Error: Reference to "each" in context without for_each
│
│ on iam.tf line 27, in resource "aws_sqs_queue_policy" "CloudTrail_SQS_DLQ":
│ 27: queue_url = aws_sqs_queue.CloudTrail_SQS_DLQ[each.key].id
│
│ The "each" object can be used only in "module" or "resource" blocks, and
│ only when the "for_each" argument is set.
4...Error: Reference to "each" in context without for_each
│
│ on iam_role.tf line 40, in data "aws_iam_policy_document" "securonix_policy_document":
│ 40: "${aws_sqs_queue.CloudTrail_SQS[each.key].arn}"
│
│ The "each" object can be used only in "module" or "resource" blocks, and
│ only when the "for_each" argument is set.
thank you indvance for looking into this for me
your aws_sqs_queue_policy should look like this:
resource “aws_sqs_queue_policy” “Cloudtrail_SQS_Policy” {
for_each = var.sqs_queue_names
queue_url = aws_sqs_queue.CloudTrail_SQS**[each.key]**.id
policy = <<POLICY
{
“Version”: “2012-10-17”,
“Id”: “sqspolicy”,
“Statement”: [
{
“Sid”: “AllowSQSInvocation”,
“Effect”: “Allow”,
“Principal”: {“AWS”:""},
“Action”: "sqs:",
“Resource”: “${aws_sqs_queue.CloudTrail_SQS**[each_key]**.arn}”
Thank you so much,it worked.However,i am still receiving the same error message for :
data "aws_iam_policy_document" "policy_document"{
statement{
actions = [
"sqs:DeleteMessage",
"sqs:GetQueueUrl",
"sqs:ReceiveMessage",
"sqs:SendMessage",
"sqs:SetQueueAttributes"
]
effect = "Allow"
resources =[
"${aws_sqs_queue.Trail_SQS.arn}
is there a way I can call the value of aws_sqs_queue.Trail_SQS.arn in the resource element which will then return the 2 SQS created using for_each?
I guess you want this:
data "aws_iam_policy_document" "policy_document"{
for_each= var.sqs_queue_names
statement{
actions = [
"sqs:DeleteMessage",
"sqs:GetQueueUrl",
"sqs:ReceiveMessage",
"sqs:SendMessage",
"sqs:SetQueueAttributes"
]
effect = "Allow"
resources =[
"${aws_sqs_queue.Trail_SQS[each.key].arn},
"${aws_sqs_queue.Trail_SQS_DLQ[each.key].arn},
]
}