AWS CDK で EventBridge + Lambda で定期実行処理(バッチ処理)を実装してみた
はじめに
プロフィールビューアーサービスProflly(プロフリー)の開発にて、定期的にデータを集計して、集計結果を保存しておく処理を、AWS CDK(TypeScript) を使って EventBridge + Lambda にて実装してみました。その定期実行処理(バッチ処理)の実装方法を紹介させていただきます。
作成するアーキテクチャ
EventBridgeを利用して月初の AM 1:00 (JST)
に Lambda を定期的に実行するように作成します。
環境
- AWS CDK
1.121.0
- TypeScript
3.9.7
実装内容
利用するパッケージをインストール
今回作成するアーキテクチャに必要なパッケージをインストールします。
npm install --save-dev @aws-cdk/aws-dynamodb @aws-cdk/aws-lambda-nodejs @aws-cdk/aws-events @aws-cdk/aws-events-targets
スタックの実装
スタックの中で各 Construt を定義して、リソースを作成します。
import * as cdk from '@aws-cdk/core'; import {RemovalPolicy} from '@aws-cdk/core'; import {NodejsFunction} from "@aws-cdk/aws-lambda-nodejs"; import {Table, BillingMode, AttributeType} from '@aws-cdk/aws-dynamodb'; import * as events from "@aws-cdk/aws-events"; import * as targets from '@aws-cdk/aws-events-targets'; export class CdkEventBridgeBatchSampleStack extends cdk.Stack { constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) { super(scope, id, props); // 集計結果を保存する DynamoDB テーブル const batchSampleTable = new Table(this, "batchSampleTable", { billingMode: BillingMode.PAY_PER_REQUEST, partitionKey: { name: "sample_id", type: AttributeType.NUMBER, }, removalPolicy: RemovalPolicy.DESTROY }); // 定期実行する Lambda 関数 const sampleLambda = new NodejsFunction(this, "sampleLambda", { entry: "src/index.ts", handler: "handler", environment: { TABLE_NAME: batchSampleTable.tableName } }); batchSampleTable.grantReadWriteData(sampleLambda); // EventBridge のルール new events.Rule(this, "sampleRule", { // JST で毎月1日の AM1:00 に定期実行 // see https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/events/ScheduledEvents.html#CronExpressions schedule: events.Schedule.cron({minute: "0", hour: "16", day: "L"}), targets: [new targets.LambdaFunction(sampleLambda, {retryAttempts: 3})], }); } }
デプロイ後の確認
以下のコマンドでデプロイを実行し、実行結果を確認してみます。
cdk deploy
各リソースが作成されていることを確認できました。
EventBridge のルールについても、意図した通りに作成されていることを確認できました。
JSTで月末と月初の指定方法
今回は月初の AM 1:00 (JST)
に定期実行したかったのですが、 Cron 式では UTC タイムゾーンで指定する必要があります。指定の際に少し迷いましたので、JSTで月初と月末を指定する際の Cron 式の例を記載しておきます。(時差を利用できる範囲で有効な方法となります)
月または週の最終日を表すワイルドカード L
があるので、こちらを使うのがシンプルで楽でした。
指定方法については、公式ドキュメントにも記載がありますので、詳細はこちらをご確認下さい。
毎月1日のAM0:00に実行する場合
0 15 L * ? *
毎月月末のPM23:00に実行する場合
0 14 L * ? *
設定の確認
設定した値がいつトリガーされるのか?を確認したい場合、マネジメントコンソール上でルールを作成する際に確認することもできますので、意図した日時にトリガーされるのか?を確認することもできます。
さいごに
Lambda 関数で定期実行したい処理を作成する際は、CDK を使って Lambda + EventBridge で実装するのも手軽でいいなぁと思いました。どなたかの参考になれば幸いです。
今回サンプルで作成したソース一式は以下に配置してありますので、興味を持たれた方は実際に動かしてみてください。