You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

CDK部署S3至SNS事件通知时出现‘无法验证目标配置’错误的排查求助

Fixing "Unable to validate the following destination configurations" in CDK S3-SNS Event Notifications

I’ve run into this exact issue before when setting up S3 event notifications to SNS with CDK. The error usually boils down to permission policy ordering issues, incorrect condition logic, or CDK’s implicit dependency handling not lining up correctly. Let’s walk through the fixes and optimized code:

1. Fix Permission Policy Ordering & Dependencies

CDK sometimes creates the S3 event notification before the SNS topic policy is fully applied, which causes AWS to reject the notification configuration. We need to explicitly ensure the topic policy exists before the bucket notification is created. Additionally, using CDK’s built-in grantPublish method simplifies policy creation and avoids manual statement errors.

2. Simplify Account Condition Logic

Your nested ternary for AWS:SourceOwner is error-prone—switching to an object map makes it easier to read and maintain, reducing the chance of a misconfigured account ID.

3. Verify All Required Conditions

Ensure the ArnLike condition correctly references your bucket’s ARN, and consider adding the AWS:SourceAccount condition for extra validation (though SourceOwner works, this aligns with AWS’s recommended practices).

Optimized Code Implementation

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",
    });

    // Simplify account mapping for SourceOwner condition
    const accountMap: Record<Stage, string> = {
      [Stage.Prod]: PROD_ACCOUNT,
      [Stage.Gamma]: GAMMA_ACCOUNT,
      [Stage.UAT1]: UAT1_ACCOUNT,
      [Stage.UAT2]: UAT2_ACCOUNT,
    };
    const sourceOwnerAccount = accountMap[stackProps.stage] || UAT2_ACCOUNT;

    // Grant S3 permission to publish to the topic (CDK handles policy creation)
    const s3ServicePrincipal = new iam.ServicePrincipal("s3.amazonaws.com");
    topic.grantPublish(s3ServicePrincipal, {
      conditions: {
        StringEquals: {
          "AWS:SourceOwner": sourceOwnerAccount,
          "AWS:SourceAccount": sourceOwnerAccount // Optional but recommended
        },
        ArnLike: {
          "AWS:SourceArn": bucket.bucketArn
        },
      }
    });

    // Add subscription permission for the external account
    const topicPolicy = new sns.TopicPolicy(this, "TopicPolicy", {
      topics: [topic],
    });
    topicPolicy.document.addStatements(
      new iam.PolicyStatement({
        sid: "AllowCrossAccountSubscription",
        actions: ["sns:Subscribe"],
        principals: [new iam.AccountPrincipal(PERFECT_MILE_ACCOUNT)],
        resources: [topic.topicArn],
      })
    );

    // Explicitly set dependency: bucket notification depends on topic policy
    bucket.node.addDependency(topicPolicy);

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

Key Changes Explained

  • grantPublish Method: Replaces manual policy statement creation for publish permissions, ensuring CDK handles proper dependency ordering between the policy and the bucket notification.
  • Account Map: Eliminates nested ternary logic, making account ID lookup clearer and less error-prone.
  • Explicit Dependency: bucket.node.addDependency(topicPolicy) guarantees the topic policy is deployed before the bucket notification configuration is applied.
  • Optional SourceAccount Condition: Adds an extra layer of validation to ensure the S3 bucket belongs to the expected account.

These changes should resolve the validation error by ensuring all permissions are in place before AWS tries to validate the S3 notification destination.

内容的提问来源于stack exchange,提问作者anonymous

火山引擎 最新活动