【问题标题】:Create an SNS message from an existing buckets S3 create event using cloudformation/serverless从现有存储桶创建 SNS 消息 S3 使用 cloudformation/serverless 创建事件
【发布时间】:2020-09-07 02:47:51
【问题描述】:

我有一个现有的 s3 存储桶不是由 serverless/cloudformation 堆栈创建的。我还有一个无服务器堆栈,其中包含一堆由 s3 创建的具有不同前缀的事件触发的 lambda。我需要通过 SNS 发送一些 s3 创建事件,以便它可以在另一个系统中使用。

在我的 serverless.yaml 中,我有一个资源部分,我可以在其中创建 SNS 主题和策略。这似乎工作正常:

resources:
  Resources:
    # Create a topic for the created s3 documents to be published on.
    MyS3ToSnsTopic:
      Type: AWS::SNS::Topic
      Properties:
        DisplayName: 'Topic to notify new s3-to-sns s3 document was created'
        TopicName: s3-to-sns
    # Policy for Bucket to publish sns messages to `s3-to-sns` topic
    MyS3ToSnsTopicPolicy:
      Type: AWS::SNS::TopicPolicy
      Properties:
        PolicyDocument:
          Id: MyS3ToSnsTopicPolicy
          Version: '2012-10-17'
          Statement:
          - Sid: s3-to-sns-id
            Effect: Allow
            Principal:
              AWS: "*"
            Action: sns:Publish
            Resource: !Join [':', ['arn:aws:sns:us-west-2', Ref: 'AWS::AccountId', 's3-to-sns']]
            Condition:
              ArnLike:
                "aws:SourceArn": "arn:aws:s3:*:*:${self:custom.bucketName.${self:provider.stage}}"
        Topics:
        - !Ref MyS3ToSnsTopic

当我转到存储桶 -> 属性 -> 事件时,我可以手动添加一个监听前缀/后缀的事件,并可以发布到该主题。所以最后一点是使用 cloudformation 创建事件,而不是手动创建。

当我让无服务器基于 create 事件创建 lambda 触发器时,它会生成以下内容:

SomeFunctionNameCustomS31:
  Type: Custom::S3
  Version: 1
  DependsOn:
  - SomeFunctionNameLambdaFunction
  - CustomDashresourceDashexistingDashs3LambdaFunction
  Properties:
    ServiceToken:
      Fn::GetAtt:
      - CustomDashresourceDashexistingDashs3LambdaFunction
      - Arn
    FunctionName: some-function-name
    BucketName: some-bucket-name
    BucketConfigs:
    - Event: s3:ObjectCreated:*
      Rules:
      - Prefix: metrics/
      - Suffix: ".json"

有没有办法为 SNS 做类似的事情,但不是使用FunctionName,而是使用类似TopicName 的东西?还需要添加或更改哪些其他属性?当您使用堆栈创建存储桶时,我看到了有关 NotificationConfiguration 的建议,但我的存储桶不是使用我的堆栈创建的。

【问题讨论】:

  • @OleksiiDonoha 我提到最后看到了 NotificationConfiguration,但是当之前手动创建存储桶时,我不确定如何利用它。
  • 我看到了 2 种方法:a) 将存储桶导入堆栈,半手动 (aws.amazon.com/blogs/aws/…); b)编写自定义资源 lambda(类似于您在问题中的内容),将主题名称作为选项并利用 SDK 订阅主题到事件
  • 没有办法制作自定义s3事件资源来发送sns消息吗?我真的不想运行 lambda 来发布消息。
  • 这就是自定义资源。这是一个可以完成工作的 lambda。我不熟悉无服务器框架,也许有人有更好的洞察力。我所说的一般适用于 Cloudformation

标签: amazon-web-services amazon-s3 amazon-cloudformation amazon-sns serverless-framework


【解决方案1】:

该框架允许您自定义它创建的资源,并且您始终可以通过Resources 块配置您手动创建的任何资源。两者都允许您设置NotificationConfiguration,它允许订阅 SNS。

resources:
  Resources:
    MyBucket:
      Type: AWS::S3::Bucket
      Properties:
        BucketName: ${self:custom.bucketName}
        NotificationConfiguration:
          TopicConfigurations:
            - Event: s3:ObjectCreated:*
              Topic:
                Ref: MySnsTopic

documentation 还详细说明了如何自定义框架创建的 S3 存储桶。

【讨论】:

  • 我希望能读到这篇文章,但它不适用于不是由堆栈创建的现有存储桶。我收到一个错误ServerlessError: An error occurred: DeviceBucket - <bucketName> already exists.
  • S3 通知配置必须在 AWS::S3::Bucket 资源上完成。您将永远无法在外部添加它。
猜你喜欢
  • 2020-07-29
  • 2016-08-23
  • 2020-02-08
  • 2022-10-04
  • 2021-09-17
  • 2016-12-09
  • 2021-08-14
  • 1970-01-01
  • 2020-07-23
相关资源
最近更新 更多