Momento Topic → Webhook → Amazon EventBridge → Amazon S3

2024/06/05に公開

https://zenn.dev/momentobigfun/articles/28382c05d9def7
前回の記事ではEventBridgeのEventBusにデータができているところまでを作成しました。
Momentoが提供しているドキュメントの内容はここまでです。
https://docs.momentohq.com/topics/integrations/lambda-handler

EventBridgeではEventバスの中に投入されたデータを確認する機能が提供されていません。これを確認するためにはS3にデータを一度吐き出す、などを行う必要があります。
EventBridgeのイベントバスにデータが投入されたことをイベントとしてAWS Lambdaを起動させることはできますので、そこからAmazon S3にデータを書き込みます。

さっそくやってみる

IAM ロールの作成

まずLambda関数用IAMロールを作成します。IAMマネージメントコンソールからCreate roleをクリックします。

AWS ServiceLambdaを選択しNextをクリックします。


CloudWatchLogsFullAccessAmazonS3FullAccessにチェックを付けてNextをクリックします。


eventbustos3と名前を付けます。


Roleが完了したら次はLambda関数の作成です。
なおより厳密な権限を付ける場合は以下になります。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "logs:CreateLogGroup",
        "logs:CreateLogStream",
        "logs:PutLogEvents"
      ],
      "Resource": "arn:aws:logs:*:*:*"
    },
    {
      "Effect": "Allow",
      "Action": [
        "s3:PutObject"
      ],
      "Resource": "arn:aws:s3:::your-s3-bucket-name/*"
    }
  ]
}

S3 バケットの作成

S3 バケットの作成は全てデフォルトなので詳細な説明は割愛しますが、必ずオレゴンで作業を行ってください。

バケット名はfromeventbusにしていますが皆さん任意のものをお願いします。S3バケット名はAWS全ユーザーで一意である必要があります。

あとは全てデフォルトでCreate bucketをクリックします。

Lambda 関数 + EventBridge Rule の作成

次にLambda関数です。この関数でやることですが1) EventBusにメッセージがパブリッシュされたイベントを取得し起動する 2) EventBusからメッセージを読み込む 3)指定したS3バケットに値を含んだJSONファイルをPutObjectする、です。

Create a functionをクリックします。

fromeventbusと名前を付けます

先ほど作成したIAMロールを付与しCreate functionをクリックします。

ブラウザの別タブでEventBridgeのマネージメントコンソールを開きます。
defaultのEventBus管理詳細画面でRulesタブを押しCreate ruleを押します。


tos3と名前を付けNextを押します。

All eventsを選択しその他設定は全てデフォルトのままNextをクリックします。

Lambda関数をセットします。

NextNextCreate ruleと順にクリックします。これでEventbusに入ったメッセージは全てLambda関数に飛ばされます。Lambda関数の画面を再読み込みすると以下の通りTriggerが追加されています。

コードをいかに置き換えます。

const { S3Client, PutObjectCommand } = require('@aws-sdk/client-s3');
const s3 = new S3Client({});

const bucketName = 'fromeventbus';

exports.handler = async (event) => {
    // EventBridgeイベントの情報を取得
    const eventDetail = JSON.stringify(event, null, 2);
    
    // ファイル名を生成
    const timestamp = new Date().toISOString();
    const fileName = `event-${timestamp}.json`;
    
    // S3バケットにイベントを保存
    const params = {
        Bucket: bucketName,
        Key: fileName,
        Body: eventDetail
    };
    
    try {
        const command = new PutObjectCommand(params);
        await s3.send(command);
        return {
            statusCode: 200,
            body: JSON.stringify('Event saved to S3')
        };
    } catch (error) {
        console.error(error);
        return {
            statusCode: 500,
            body: JSON.stringify('Error saving event to S3')
        };
    }
};

your-s3-bucket-nameは先ほど作成したS3バケットに置換します。

ファイル名をindex.mjsからindex.jsに変更してDeployボタンをおします。
Momentoコンソールからデータをテスト用にPublishし、暫く待つとS3バケットにJSONファイルが出来上がるはずです。

{
  "version": "0",
  "id": "31950bcd-d501-472d-315a-89f43b3ed646",
  "detail-type": "default-cache#toaws",
  "source": "Momento",
  "account": "968281453546",
  "time": "2024-06-05T05:29:54Z",
  "region": "us-west-2",
  "resources": [],
  "detail": {
    "cache": "default-cache",
    "topic": "toaws",
    "event_timestamp": 1717565394683,
    "publish_timestamp": 1717565394683,
    "topic_sequence_number": 37,
    "token_id": "",
    "text": "message from momento to event bus to S3"
  }
}

Discussion