I am getting the following error when performing terraform apply:
Error: creating S3 Bucket (aws-solution-associate) Notification: operation error S3: PutBucketNotificationConfiguration, https response error StatusCode: 400, RequestID: VPV6DW8AMS2NS31S, HostID: QavFpP5mW+8RR8nexKcwwsytg+2gXe3cwAuyQqv9GzpD8OMIXZT8Y9EDHMtN+WZwC8lhAqFwkcA=, api error InvalidArgument: Unable to validate the following destination configurations
with aws_s3_bucket_notification.s3_sns_notification,
on main.tf line 249, in resource "aws_s3_bucket_notification" "s3_sns_notification":
249: resource "aws_s3_bucket_notification" "s3_sns_notification" {
I am not sure what went wrong and the error message is not helpful at all. Need someone advise please
Please refer to my terraform script below:
terraform{
backend "s3" {
bucket = "aws-solution-associate"
key = "lab4-create_sns_sqs"
region = "us-east-1"
}
}
provider "aws" {
region = "us-east-1"
}
# Inject caller ID for being able to use the account ID
data "aws_caller_identity" "current" {}
resource "aws_sns_topic" "resize-image-topic" {
name = "resize-image-topic-1451"
policy = data.aws_iam_policy_document.sns-topic-policy.json
}
resource "aws_sqs_queue" "thumbnail-queue" {
name = "thumbnail-queue"
policy = data.aws_iam_policy_document.sqs-queue-policy-thumbnail-queue.json
}
resource "aws_sns_topic_subscription" "resize-image-topic-sub-1" {
topic_arn = aws_sns_topic.resize-image-topic.arn
protocol = "sqs"
endpoint = aws_sqs_queue.thumbnail-queue.arn
}
resource "aws_sqs_queue" "web-queue" {
name = "web-queue"
policy = data.aws_iam_policy_document.sqs-queue-policy-web-queue.json
}
resource "aws_sns_topic_subscription" "resize-image-topic-sub-2" {
topic_arn = aws_sns_topic.resize-image-topic.arn
protocol = "sqs"
endpoint = aws_sqs_queue.web-queue.arn
}
resource "aws_sqs_queue" "mobile-queue" {
name = "mobile-queue"
policy = data.aws_iam_policy_document.sqs-queue-policy-mobile-queue.json
}
resource "aws_sns_topic_subscription" "resize-image-topic-sub-3" {
topic_arn = aws_sns_topic.resize-image-topic.arn
protocol = "sqs"
endpoint = aws_sqs_queue.mobile-queue.arn
}
# Create a topic policy. This will allow for the SQS queue to be able to subscribe to the topic
data "aws_iam_policy_document" "sns-topic-policy" {
statement {
sid = "lab4-sns-topic-policy-sqs"
effect = "Allow"
principals {
type = "AWS"
identifiers = ["*"]
}
actions = [
"SNS:GetTopicAttributes",
"SNS:SetTopicAttributes",
"SNS:AddPermission",
"SNS:RemovePermission",
"SNS:DeleteTopic",
"SNS:Subscribe",
"SNS:ListSubscriptionsByTopic",
"SNS:Publish",
"SNS:Receive"
]
condition {
test = "StringLike"
variable = "SNS:Endpoint"
# In order to avoid circular dependencies, we must create the ARN ourselves
values = [
"arn:aws:sqs:${var.region}:${data.aws_caller_identity.current.account_id}:mobile-queue",
"arn:aws:sqs:${var.region}:${data.aws_caller_identity.current.account_id}:thumbnail-queue",
"arn:aws:sqs:${var.region}:${data.aws_caller_identity.current.account_id}:web-queue",
]
}
resources = [
"arn:aws:sns:${var.region}:${data.aws_caller_identity.current.account_id}:resize-image-topic-1451"
]
}
statement {
sid = "lab4-sns-topic-policy-s3"
effect = "Allow"
principals {
type = "Service"
identifiers = ["s3.amazonaws.com"]
}
actions = [
"SNS:Publish",
]
condition {
test = "StringEquals"
variable = "AWS:SourceAccount"
values = ["arn:aws:sns:${var.region}:${data.aws_caller_identity.current.account_id}:resize-image-topic-1451"]
}
resources = [
"arn:aws:sns:${var.region}:${data.aws_caller_identity.current.account_id}:resize-image-topic-1451"
]
}
}
# Create a queue policy. This allows for the SNS topic to be able to publish messages to the SQS queue
data "aws_iam_policy_document" "sqs-queue-policy-mobile-queue" {
policy_id = "arn:aws:sqs:${var.region}:${data.aws_caller_identity.current.account_id}:mobile-queue/SQSDefaultPolicy"
statement {
sid = "example-sns-topic"
effect = "Allow"
principals {
type = "AWS"
identifiers = ["*"]
}
actions = [
"SQS:SendMessage",
]
resources = [
"arn:aws:sqs:${var.region}:${data.aws_caller_identity.current.account_id}:mobile-queue",
]
condition {
test = "ArnEquals"
variable = "aws:SourceArn"
values = [
"arn:aws:sns:${var.region}:${data.aws_caller_identity.current.account_id}:resize-image-topic-1451"
]
}
}
}
# Create a queue policy. This allows for the SNS topic to be able to publish messages to the SQS queue
data "aws_iam_policy_document" "sqs-queue-policy-thumbnail-queue" {
policy_id = "arn:aws:sqs:${var.region}:${data.aws_caller_identity.current.account_id}:thumbnail-queue/SQSDefaultPolicy"
statement {
sid = "example-sns-topic"
effect = "Allow"
principals {
type = "AWS"
identifiers = ["*"]
}
actions = [
"SQS:SendMessage",
]
resources = [
"arn:aws:sqs:${var.region}:${data.aws_caller_identity.current.account_id}:thumbnail-queue",
]
condition {
test = "ArnEquals"
variable = "aws:SourceArn"
values = [
"arn:aws:sns:${var.region}:${data.aws_caller_identity.current.account_id}:resize-image-topic-1451"
]
}
}
}
# Create a queue policy. This allows for the SNS topic to be able to publish messages to the SQS queue
data "aws_iam_policy_document" "sqs-queue-policy-web-queue" {
policy_id = "arn:aws:sqs:${var.region}:${data.aws_caller_identity.current.account_id}:web-queue/SQSDefaultPolicy"
statement {
sid = "example-sns-topic"
effect = "Allow"
principals {
type = "AWS"
identifiers = ["*"]
}
actions = [
"SQS:SendMessage",
]
resources = [
"arn:aws:sqs:${var.region}:${data.aws_caller_identity.current.account_id}:web-queue",
]
condition {
test = "ArnEquals"
variable = "aws:SourceArn"
values = [
"arn:aws:sns:${var.region}:${data.aws_caller_identity.current.account_id}:resize-image-topic-1451"
]
}
}
}
data "aws_s3_bucket" "s3_sns" {
bucket = "aws-solution-associate"
}
data "aws_iam_policy_document" "s3_bucket_to_sns_topic_policy" {
statement {
sid = "AllowSNSPublish"
effect = "Allow"
actions = ["s3:PutObject"]
resources = ["arn:aws:s3:::aws-solution-associate/*"]
condition {
test = "StringEquals"
variable = "aws:SourceArn"
values = ["arn:aws:sns:${var.region}:${data.aws_caller_identity.current.account_id}:resize-image-topic-1451"]
}
}
}
resource "aws_s3_bucket_policy" "bucket_policy" {
bucket = data.aws_s3_bucket.s3_sns.id
policy = data.aws_iam_policy_document.s3_bucket_to_sns_topic_policy.json
}
resource "aws_s3_bucket_notification" "s3_sns_notification" {
bucket = data.aws_s3_bucket.s3_sns.id
topic {
topic_arn = "arn:aws:sns:${var.region}:${data.aws_caller_identity.current.account_id}:resize-image-topic-1451"
events = ["s3:ObjectCreated:*"]
filter_suffix = ".jpg"
filter_prefix = "ingest/"
}
depends_on = [ data.aws_s3_bucket.s3_sns ]
}
I initially thought that the access policy was not granted to the S3 bucket and only to realise the error still persist after I granted S3 bucket to access the SNS
I am not sure why the dependencies was overly focused. I realise that the issue was because the S3 arn is not being specified in the statement with the action as publish.
# Create a topic policy. This will allow for the SQS queue to be able to subscribe to the topic
data "aws_iam_policy_document" "sns-topic-policy" {
statement {
sid = "lab4-sns-topic-policy-sqs"
effect = "Allow"
principals {
type = "AWS"
identifiers = ["*"]
}
actions = [
"SNS:GetTopicAttributes",
"SNS:SetTopicAttributes",
"SNS:AddPermission",
"SNS:RemovePermission",
"SNS:DeleteTopic",
"SNS:Subscribe",
"SNS:ListSubscriptionsByTopic",
"SNS:Publish",
"SNS:Receive"
]
condition {
test = "StringLike"
variable = "SNS:Endpoint"
# In order to avoid circular dependencies, we must create the ARN ourselves
values = [
"arn:aws:sqs:${var.region}:${data.aws_caller_identity.current.account_id}:mobile-queue",
"arn:aws:sqs:${var.region}:${data.aws_caller_identity.current.account_id}:thumbnail-queue",
"arn:aws:sqs:${var.region}:${data.aws_caller_identity.current.account_id}:web-queue",
]
}
resources = [
"arn:aws:sns:${var.region}:${data.aws_caller_identity.current.account_id}:resize-image-topic-1451"
]
}
statement {
sid = "lab4-sns-topic-policy-s3"
effect = "Allow"
principals {
type = "Service"
identifiers = ["s3.amazonaws.com"]
}
actions = [
"SNS:Publish",
]
condition {
test = "StringEquals"
variable = "AWS:SourceAccount"
values = ["arn:aws:sns:${var.region}:${data.aws_caller_identity.current.account_id}:resize-image-topic-1451"] #This should be changed to refer to the S3 bucket
}
resources = [
"arn:aws:sns:${var.region}:${data.aws_caller_identity.current.account_id}:resize-image-topic-1451"
]
}
}