Search code examples
amazon-s3amazon-sns

Unable to validate the following destination configurations (s3 to SNS)


I am trying to setup an event Notification system on s3 to publish notifications to SNS when a file is being uploaded to s3. Here 's how I implemented it via CDK :

import * as sns from "monocdk/aws-sns";
import * as iam from "monocdk/aws-iam";
import {
  GAMMA_ACCOUNT,
  PROD_ACCOUNT,
  UAT1_ACCOUNT,
  UAT2_ACCOUNT,
  PERFECT_MILE_ACCOUNT,
} from "../utils/constants/awsAccounts";
import { Construct } from "monocdk";
import * as s3 from "monocdk/aws-s3";
import * as s3n from "monocdk/aws-s3-notifications";
import { CommonResourceStackProps, Stage } from "../stack/CommonResourcesStack";

export class S3NotificationToSNSCustomResource extends Construct {
  constructor(
    scope: Construct,
    id: string,
    bucket: s3.IBucket,
    stackProps: CommonResourceStackProps
  ) {
    super(scope, id);
    const topic = new sns.Topic(this, "Topic", {
      displayName: "Sherlock-s3-Event-Notifications-Topic",
      topicName: "Sherlock-s3-Event-Notifications-Topic",
    });
    const topicPolicy = new sns.TopicPolicy(this, "TopicPolicy", {
      topics: [topic],
    });

    const s3ServicePrincipal = new iam.ServicePrincipal("s3.amazonaws.com");

    topicPolicy.document.addStatements(
      new iam.PolicyStatement({
        sid: "0",
        actions: ["sns:Publish"],
        principals: [s3ServicePrincipal],
        resources: [topic.topicArn],
        conditions: {
          StringEquals: {
            "AWS:SourceOwner":
              stackProps.stage == Stage.Prod
                ? PROD_ACCOUNT
                : stackProps.stage == Stage.Gamma
                ? GAMMA_ACCOUNT
                : stackProps.stage == Stage.UAT1
                ? UAT1_ACCOUNT
                : UAT2_ACCOUNT,
          },
          ArnLike: { "AWS:SourceArn": bucket.bucketArn },
        },
      }),
      new iam.PolicyStatement({
        sid: "1",
        actions: ["sns:Subscribe"],
        principals: [new iam.AccountPrincipal(PERFECT_MILE_ACCOUNT)],
        resources: [topic.topicArn],
      })
    );

    bucket.addEventNotification(
      s3.EventType.OBJECT_CREATED,
      new s3n.SnsDestination(topic),
      { prefix: "output/reportingData/openItems/", suffix: "_SUCCESS" }
    );
  }
}

But, when I try to deploy this, I am getting the following error : An error occurred (InvalidArgument) when calling the PutBucketNotificationConfiguration operation: Unable to validate the following destination configurations

Can anyone help me with it?

I read this post(https://aws.amazon.com/premiumsupport/knowledge-center/unable-validate-destination-s3/) but its resolution is using the templates and I am implementing using the CDK package. Also I have added all the access policies to publish and subscribe.


Solution

  • aws:SourceAccount and aws:SourceOwner are condition keys which are not supported by all services. Amazon S3 notifications use aws:SourceAccount Refer - https://docs.aws.amazon.com/sns/latest/dg/sns-access-policy-use-cases.html#source-account-versus-source-owner