I want to create a policy so a specific aws role (not in the same account) let's say arn:aws:iam::123123123123:role/sns-read-role can subscribe and receive messages from my SNS topic in AWS.

From the official terraform docs about aws_sns_topic_policy example it would be

resource "aws_sns_topic" "test" {name = "my-topic-with-policy"}resource "aws_sns_topic_policy" "default" {arn = aws_sns_topic.test.arnpolicy = data.aws_iam_policy_document.sns_topic_policy.json}data "aws_iam_policy_document" "sns_topic_policy" {statement {actions = ["SNS:Subscribe","SNS:Receive"]condition {test = "StringEquals"variable = "AWS:SourceOwner"values = [123123123123]}effect = "Allow"principals {type = "AWS"identifiers = ["*"]}resources = [aws_sns_topic.test.arn]}}

But this would translate to arn:aws:iam::123123123123:root and filter only on account-id.

From AWS JSON policy elements: Principal I understand the AWS syntax is

"Principal": { "AWS": "arn:aws:iam::AWS-account-ID:role/role-name" }

Adding the role in the condition like this

condition {test = "StringEquals"variable = "AWS:SourceOwner"values = [arn:aws:iam::123123123123:role/sns-read-role]}

does not work.

It would make sense to add the role to the principal like this

principals {type = "AWS"identifiers = ["arn:aws:iam::123123123123:role/sns-read-role"]}

When I try to subscribe, I get an AuthorizationError: "Couldn't subscribe to topic..."

Do I need the condition together with the principal? Why even bother with the condition if you can use the principal in the first place?

1

Best Answer


After some experimenting, I found that I don't need the condition. This works for me:

resource "aws_sns_topic" "test" {name = "my-topic-with-policy"}resource "aws_sns_topic_policy" "default" {arn = aws_sns_topic.test.arnpolicy = data.aws_iam_policy_document.sns_topic_policy.json}data "aws_iam_policy_document" "sns_topic_policy" {statement {actions = ["SNS:Subscribe","SNS:Receive"]effect = "Allow"principals {type = "AWS"identifiers = ["arn:aws:iam::123123123123:role/sns-read-role"]}resources = [aws_sns_topic.test.arn]}}

In case you want to use parameters for your module:

principals {type = "AWS"identifiers = ["${var.account_arn}:role/${var.role}"]}