I am trying to create multiple SNS topic subscription in the SQS. I do have the config file like below in json format
"snsSubscriptionArns": [
"arn:aws:sns:<region>:<accountno>:test1",
"arn:aws:sns:<region>:<accountno>:test2",
"arn:aws:sns:<region>:<accountno>:test3"
]
Above mentioned Arns will be based on the requirement. It's dynamic. It can be 0, can be 5.. I am trying to create policy using the below
locals {
# Load all of the data from json
config = jsondecode(file("testsqs.json"))
}
data "aws_iam_policy_document" "sns_policy" {
for_each = lookup(local.config, "snsSubscriptionArns", null) == null ? toset([]) : [ for i in local.config.snsSubscriptionArns : i ]
statement {
sid = "topic-subscription-${each.key}"
effect = "Allow"
actions = [
"sqs:SendMessage"
]
resources = [
"test-arn"
]
condition {
test = "ArnLike"
variable = "aws:SourceArn"
values = [
"${each.key}"
]
}
}
policy = data.aws_iam_policy_document.sns_policy[each.key].json
}
I need to collect all the policies and then I will use resource block to create SQS with above policy like below
resource "aws_sqs_queue_policy" "sqs_queue_policy" {
queue_url = aws_sqs_queue.queue.id
policy = data.aws_iam_policy_document.sns_policy.json
}
But I am getting the below error msg.
Error: Unsupported argument
on main.tf line 36, in data "aws_iam_policy_document" "sns_policy":
36: policy = data.aws_iam_policy_document.sns_policy[each.key].json
An argument named "policy" is not expected here.
It looks my approach is wrong in terraform. Could someone please guide me to achieve? Thanks in advance.
CodePudding user response:
policy
is not a valid attribute for iam_policy_document
data source see : https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document
It is expected on aws_iam_policy
data source, you must create aws_iam_policy
resources with a foreach loop
CodePudding user response:
As you can see from the docs for data source aws_iam_policy_document, there is no policy
attribute. I believe either of these two options should work. You are very close.
Given the source json file testsqs.json:
{
"snsSubscriptionArns": [
"arn:aws:sns:<region>:<accountno>:test1",
"arn:aws:sns:<region>:<accountno>:test2",
"arn:aws:sns:<region>:<accountno>:test3"
]
}
and main.tf:
locals {
config = jsondecode(file("testsqs.json"))
arns = lookup(local.config, "snsSubscriptionArns", [])
}
data "aws_iam_policy_document" "sns_policy_one_statement" {
statement {
actions = ["sqs:SendMessage"]
resources = ["test-arn"]
condition {
test = "ArnLike"
variable = "aws:SourceArn"
values = local.arns
}
}
}
data "aws_iam_policy_document" "sns_policy_many_statements" {
dynamic "statement" {
for_each = local.arns
content {
sid = "topic-subscription-${statement.key}"
actions = ["sqs:SendMessage"]
resources = ["test-arn"]
condition {
test = "ArnLike"
variable = "aws:SourceArn"
values = [statement.value]
}
}
}
}
output "sns_policy_one_statement" {
value = data.aws_iam_policy_document.sns_policy_one_statement.json
}
output "sns_policy_many_statements" {
value = data.aws_iam_policy_document.sns_policy_many_statements.json
}
You get outputs like:
Changes to Outputs:
sns_policy_many_statements = jsonencode(
{
Statement = [
{
Action = "sqs:SendMessage"
Condition = {
ArnLike = {
"aws:SourceArn" = "arn:aws:sns:<region>:<accountno>:test1"
}
}
Effect = "Allow"
Resource = "test-arn"
Sid = "topic-subscription-0"
},
{
Action = "sqs:SendMessage"
Condition = {
ArnLike = {
"aws:SourceArn" = "arn:aws:sns:<region>:<accountno>:test2"
}
}
Effect = "Allow"
Resource = "test-arn"
Sid = "topic-subscription-1"
},
{
Action = "sqs:SendMessage"
Condition = {
ArnLike = {
"aws:SourceArn" = "arn:aws:sns:<region>:<accountno>:test3"
}
}
Effect = "Allow"
Resource = "test-arn"
Sid = "topic-subscription-2"
},
]
Version = "2012-10-17"
}
)
sns_policy_one_statement = jsonencode(
{
Statement = [
{
Action = "sqs:SendMessage"
Condition = {
ArnLike = {
"aws:SourceArn" = [
"arn:aws:sns:<region>:<accountno>:test1",
"arn:aws:sns:<region>:<accountno>:test2",
"arn:aws:sns:<region>:<accountno>:test3",
]
}
}
Effect = "Allow"
Resource = "test-arn"
Sid = ""
},
]
Version = "2012-10-17"
}
)
You only need for_each at the resource level if you want to create multiple of that resource. In your case, I think you only need one policy. You can decide which works for aws_sqs_queue_policy
. This uses the dynamic block.