CloudFormationでSNSトピックへの複数のイベント通知を設定したS3バケットを作成する

2021.10.05

データアナリティクス事業本部の鈴木です。

CloudFormation(以降CFn)でSNSトピックへの複数のイベント通知を設定したS3バケットを作成してみました。

やりたいこと

CFnテンプレートでSNSトピックへのイベント通知を設定したS3バケットを作成するために、そのような設定に対応するテンプレートの書き方を知りたかったので試してみました。

S3のイベント通知は、データ連携のようなイベントをトリガーとして取り込み処理などを起動できるため、データ基盤でもとても重宝する機能です。

例えば、オブジェクトの作成に使用された API に関係なく通知をリクエストしたい場合は、ワイルドカードを使ったs3:ObjectCreated:*イベントタイプを設定できます。

今回は、s3:ObjectCreated:Puts3:ObjectCreated:Copyの2つだけ通知したいときってどう書くんだっけ?と疑問を持ちました。

イベント通知のタイプおよび送信先 - Amazon Simple Storage Service

解決策

以下のように、NotificationConfigurationTopicConfigurationsに複数の値を設定することで、実現できました。

AWSTemplateFormatVersion: 2010-09-09
Description: Event Bucket

Parameters:
  EventBucketName:
    Description: BucketName of Event Bucket.
    Type: String
  DestinationSNSTopicArn:
    Description: Arn of nortification destination SNS ARN.
    Type: String

Resources:
  EventBucket:
    Type: 'AWS::S3::Bucket'
    Properties:
      BucketName: !Sub ${EventBucketName}
      PublicAccessBlockConfiguration:
        BlockPublicAcls: true
        BlockPublicPolicy: true
        IgnorePublicAcls: true
        RestrictPublicBuckets: true
      NotificationConfiguration:
        TopicConfigurations:
          - Event: "s3:ObjectCreated:Put"
            Topic: !Sub ${DestinationSNSTopicArn}
          - Event: "s3:ObjectCreated:Copy"
            Topic: !Sub ${DestinationSNSTopicArn}

Outputs:
  EventBucket:
    Value: !Ref EventBucket

なお、イベント通知は記事執筆時点で100個までのサービスクォータがあります。

Amazon Simple Storage Service エンドポイントとクォータ - AWS 全般のリファレンス

やってみる

以下のような構成をCFnで作成してみます。その際、イベント通知には以下の2種類のイベントタイプを設定してみます。

  • s3:ObjectCreated:Put
  • s3:ObjectCreated:Copy

CFnで作成する構成

1.通知先のSNSトピックを作成する

まず、通知先のSNSトピックを作成します。 以下のCFnテンプレートをデプロイしておきます。

AWSTemplateFormatVersion: 2010-09-09
Description: SNS Topic for S3Event

Parameters:
  S3EventTopicName:
    Description: Name of SNS Topic for S3Event.
    Type: String

Resources:
  S3EventTopic:
    Type: AWS::SNS::Topic
    Properties:
      TopicName: !Sub ${S3EventTopicName}
        
  S3EventTopicPolicy:
    Type: "AWS::SNS::TopicPolicy"
    Properties:
      Topics:
        - !Ref S3EventTopic
      PolicyDocument:
        Version: 2012-10-17
        Statement:
          - Sid: TopicPolicy
            Effect: Allow
            Principal:
              Service: s3.amazonaws.com
            Action:
              - "sns:Publish"
            Resource: !Ref S3EventTopic

Outputs:
  S3EventTopic:
    Value: !Ref S3EventTopic

2.S3バケットを作成する

次に、イベント通知を設定したS3バケットのCFnテンプレートをデプロイします。

#######
# 再掲 #
#######
AWSTemplateFormatVersion: 2010-09-09
Description: Event Bucket

Parameters:
  EventBucketName:
    Description: BucketName of Event Bucket.
    Type: String
  DestinationSNSTopicArn:
    Description: Arn of nortification destination SNS Topic.
    Type: String

Resources:
  EventBucket:
    Type: 'AWS::S3::Bucket'
    Properties:
      BucketName: !Sub ${EventBucketName}
      PublicAccessBlockConfiguration:
        BlockPublicAcls: true
        BlockPublicPolicy: true
        IgnorePublicAcls: true
        RestrictPublicBuckets: true
      NotificationConfiguration:
        TopicConfigurations:
          - Event: "s3:ObjectCreated:Put"
            Topic: !Sub ${DestinationSNSTopicArn}
          - Event: "s3:ObjectCreated:Copy"
            Topic: !Sub ${DestinationSNSTopicArn}

Outputs:
  EventBucket:
    Value: !Ref EventBucket

3.イベント通知を確認する

S3バケットができたので、設定が反映されているか確認してみました。

作成されたイベント通知

手動で一つづつ登録した際と同じように、s3:ObjectCreated:Puts3:ObjectCreated:Copyは別のイベント通知として登録されました。

また、名前はXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXXのようにUUIDが自動的に振られていました。

最後に

今回はCFnを使って、SNSトピックへの複数のイベント通知を設定したS3バケットを作成してみました。

イベント通知は設定が簡単なので、手動で設定してしまうことも多いかもしれませんが、CFnを使うと設定の手間も省け、設定もYAMLで管理できるので便利です。

イベント通知を使った開発の参考になれば幸いです。