skip to Main Content

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.

2

Answers


  1. 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

    Login or Signup to reply.
  2. 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.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search