创建一个向 SNS 主题发送通知的 S3 存储桶

Create an S3 bucket that sends notification to SNS topic

我正在尝试创建一个 s3 存储桶,它会在每次将对象放入 s3 存储桶时向 SNS 主题发送通知。我的 S3 存储桶名为 foo-bucket,我的 SNS 主题名为 foo-topic。我知道如何在 aws 控制台中进行设置,但是我在尝试通过 cloudformation 进行设置时遇到了问题。

这是我目前拥有的代码

Resources:
  SNSTopic:
    Type: AWS::SNS::Topic
    Properties:
      TopicName: foo-topic
  SNSTopicPolicy:
    Type: AWS::SNS::TopicPolicy
    Properties:
      PolicyDocument:
        Id: MyTopicPolicy
        Version: '2012-10-17'
        Statement:
        - Sid: Statement-id
          Effect: Allow
          Principal:
            Service: s3.amazonaws.com
          Action: sns:Publish
          Resource:
            Ref: SNSTopic
          Condition:
            ArnLike:
              aws:SourceArn:
                Fn::Join:
                - ''
                - - 'arn:aws:s3:::'
                  - Ref: S3Bucket
      Topics:
      - Ref: SNSTopic
  S3Bucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: foo-bucket 
      AccessControl: BucketOwnerFullControl
      NotificationConfiguration:
        TopicConfigurations:
        - Topic:
            Ref: SNSTopic
          Event: s3:ObjectCreated:Put

由于以下错误,我尝试部署上述内容和 cfn 回滚

Unable to validate the following destination configurations (Service: Amazon S3; Status Code: 400; Error Code: InvalidArgument; Request ID: fooooo; S3 Extended Request ID: foooid; Proxy: null)

是的,你的问题是依赖关系 ;)

我遇到了同样的问题,如果您不指定依赖顺序,例如先创建 SNS,然后在 Bucket 部分获取使用 REF 创建的 ID,您将遇到有关目标配置的问题。

请按照此 link 解决您的问题,您将看到 DependsOn :

https://aws.amazon.com/premiumsupport/knowledge-center/unable-validate-destination-s3/?nc1=h_ls

我有一个 example cloudformation 创建存储桶、sns 主题和通知配置。如前所述,您需要确保正确的依赖顺序。

通知配置不检查资源是否存在,所以我们需要使用 DependsOn 属性 来检查

在创建 SNS 主题策略时,还要注意潜在的循环引用。我将存储桶名称定义为字符串,而不是引用。它允许在存储桶的通知配置之前使用其策略创建 SNS。

  IngestionBucketDev:
    Type: AWS::S3::Bucket
    DependsOn:
     - IngestionTopicDev
     - IngestionTopicPolicy
    Properties: 
      BucketName: "ingestion-codebucket-7832df8b-dev"
      NotificationConfiguration:
        TopicConfigurations:
         -  Topic: !Ref IngestionTopicDev
            Event: 's3:ObjectCreated:*'
            Filter:
              S3Key:
                Rules:
                 - Name: suffix
                   Value: ".json"
      PublicAccessBlockConfiguration:
        RestrictPublicBuckets: true
        BlockPublicPolicy: true
           
               
  IngestionTopicDev:
    Type: AWS::SNS::Topic
    Properties: 
      TopicName: "elearn-ingest-topic"
      DisplayName: "elearn-ingest-topic"
      
  IngestionTopicPolicy:
    Type: AWS::SNS::TopicPolicy
    Properties: 
      Topics:
       - !Ref IngestionTopicDev
      PolicyDocument:
        Version: 2012-10-17
        Statement:
          - Action:
              - 'sns:Publish'
            Effect: Allow
            Resource: !Ref IngestionTopicDev
            Principal: 
              Service: "s3.amazonaws.com"
            Condition:
              ArnEquals:
               "aws:SourceArn": "arn:aws:s3:::ingestion-codebucket-7832df8a-dev"