无法让 S3 通知 yaml/stack 工作

Can't get S3 notification yaml/stack to work

如果 运行 没有以 NotificationConfiguration 开头的 4 行,则下面的代码一切正常。我认为这可能是因为在对存储桶设置通知之前需要主题策略。因此,尝试在没有 NotificationConfiguration 行的情况下进行初始创建,然后将它们添加进来并更新堆栈。 但是收到错误无法验证以下目标配置(服务:Amazon S3;状态代码:400;错误代码:InvalidArgument;。我已经尝试过将实际主题 arn not using !Ref 但没有快乐。谢谢!

Resources:
  DeletionSNSTopic:
    Type: AWS::SNS::Topic
    Properties:
       DisplayName: 
         !Join [" ",[Data has been deleted from,!Sub '${ServiceName}-${Stage}-${AWS::AccountId}']
               ]
       Subscription:
           - Endpoint: !Sub '${DeleteNotifyEmail}'
             Protocol: email
       TopicName: !Sub 'delete-from-${ServiceName}-bucket'

  DataBucket:
    Type: AWS::S3::Bucket
    DependsOn: DeletionSNSTopic
    Description: Create Amazon S3 bucket from CloudFormation
    Properties:
      BucketName: !Sub '${ServiceName}-${Stage}-${AWS::AccountId}' 
      AccessControl: Private
      BucketEncryption: 
        ServerSideEncryptionConfiguration: 
          - ServerSideEncryptionByDefault:
              SSEAlgorithm: AES256
      VersioningConfiguration:
        Status: Enabled
      PublicAccessBlockConfiguration:
        BlockPublicAcls: true
        BlockPublicPolicy: true
        IgnorePublicAcls: true
        RestrictPublicBuckets: true
      NotificationConfiguration:
        TopicConfigurations:
          - Topic: !Ref DeletionSNSTopic
            Event: 's3:ObjectRemoved:*'
             
  BucketToSNSPermission:
    Type: AWS::SNS::TopicPolicy
    Properties:
      PolicyDocument:
        Id: 'deletionTopicPolicy'
        Version: '2012-10-17'
        Statement:
        - Sid: 'deletionTopic-statement-id'
          Effect: Allow
          Principal: 
             Service: s3.amazonaws.com
          Action: sns:Publish
          Resource: !Ref DeletionSNSTopic
          Condition: 
             StringEquals: 
                aws:SourceAccount: !Sub '${AWS::AccountId}'
             ArnLike: 
                aws:SourceArn: !Ref DataBucket
      Topics:
      - !Ref DeletionSNSTopic

您的代码中有循环依赖。在应用主题策略之前,您可以创建带有通知的存储桶。显然不能在存储桶之前创建策略,因为由于!Ref DataBucket.

,存储桶必须已经存在

要解决必须首先知道存储桶名称的问题,在您的情况下这是可能的:

Resources:
  DeletionSNSTopic:
    Type: AWS::SNS::Topic
    Properties:
       DisplayName: 
         !Join [" ",[Data has been deleted from,!Sub '${ServiceName}-${Stage}-${AWS::AccountId}']
               ]
       Subscription:
           - Endpoint: !Sub '${DeleteNotifyEmail}'
             Protocol: email
       TopicName: !Sub 'delete-from-${ServiceName}-bucket'

  DataBucket:
    Type: AWS::S3::Bucket
    DependsOn: BucketToSNSPermission
    Description: Create Amazon S3 bucket from CloudFormation
    Properties:
      BucketName: !Sub '${ServiceName}-${Stage}-${AWS::AccountId}' 
      AccessControl: Private
      BucketEncryption: 
        ServerSideEncryptionConfiguration: 
          - ServerSideEncryptionByDefault:
              SSEAlgorithm: AES256
      VersioningConfiguration:
        Status: Enabled
      PublicAccessBlockConfiguration:
        BlockPublicAcls: true
        BlockPublicPolicy: true
        IgnorePublicAcls: true
        RestrictPublicBuckets: true
      NotificationConfiguration:
        TopicConfigurations:
          - Topic: !Ref DeletionSNSTopic
            Event: 's3:ObjectRemoved:*'
             
  BucketToSNSPermission:
    Type: AWS::SNS::TopicPolicy
    Properties:
      PolicyDocument:
        Id: 'deletionTopicPolicy'
        Version: '2012-10-17'
        Statement:
        - Sid: 'deletionTopic-statement-id'
          Effect: Allow
          Principal: 
             Service: s3.amazonaws.com
          Action: SNS:Publish
          Resource: !Ref DeletionSNSTopic
          Condition: 
             StringEquals: 
                aws:SourceAccount: !Ref AWS::AccountId
             ArnLike: 
                aws:SourceArn: !Sub "arn:aws:s3:::${ServiceName}-${Stage}-${AWS::AccountId}"
      Topics:
      - !Ref DeletionSNSTopic

一般情况签入: