Amazon EventBridge Scheduler 用のCDK L2コンストラクトが一般提供されたので試してみた
お疲れさまです。とーちです。
Amazon EventBridge Scheduler 用の CDK L2 コンストラクトが一般提供されたというアップデートがありましたので、早速試してみました。
私は普段はもっぱら Terraform で構築しており、CDK を使うのはかなり久々です。私が CDK を使うのが久々だったからか、または私が TypeScript 開発経験に乏しいからかわかりませんが、公式ドキュメントのサンプルコードを動かすだけでも結構苦労したので、そのあたり解説しながら紹介したいと思います。CDK に慣れている方にとっては初歩の初歩な内容になると思いますのでご了承ください。
やってみた
今回一般提供が開始されたライブラリが以下です。
aws-cdk-lib.aws_scheduler module · AWS CDK
環境準備
まず、CDK のバージョンを上げましょう。
npm install -g cdk
で CDK のバージョンを上げました。Node および CDK のバージョンは以下で試しました。
> node --version
v22.14.0
> npm list -g --depth=0
<省略>
├── cdk@2.1007.0
また aws-cdk-lib のバージョンは 2025/4/4 時点で最新の 2.187.0
を使っています。
├── @types/jest@29.5.14
├── @types/node@22.7.9
├── aws-cdk-lib@2.187.0
├── aws-cdk@2.1007.0
├── constructs@10.4.2
├── jest@29.7.0
├── ts-jest@29.3.1
├── ts-node@10.9.2
└── typescript@5.6.3
Lambda 関数の作成
それではコードを書いてみましょう。とりあえず EventBridge Scheduler の呼び出し先がないとということで、適当な Lambda 関数を作りました。hello world と返すだけの Lambda なので Lambda 自体のコードは簡単なものです。
def handler(event, context):
print("Received event:", event)
return {
'statusCode': 200,
'body': 'Hello, World!'
}
CDK スタックのコードは以下のようになります。
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import { Duration } from 'aws-cdk-lib';
import * as lambda from 'aws-cdk-lib/aws-lambda';
import * as path from 'path';
export class CdkEventbridgeSchUpdateStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
const fn = new lambda.Function(this, 'MyPythonFunction', {
runtime: lambda.Runtime.PYTHON_3_9,
handler: 'index.handler',
code: lambda.Code.fromAsset(path.join(__dirname, '../lambda/hello_world')),
});
}
}
EventBridge Scheduler の設定
続いて、EventBridge Scheduler を作成するためには、公式ドキュメントの記載に倣うと target オブジェクトと schedule オブジェクトを作る必要があることがわかります。
公式ドキュメントのサンプルコードが以下です。
declare const fn: lambda.Function;
const target = new targets.LambdaInvoke(fn, {
input: ScheduleTargetInput.fromObject({
"payload": "useful",
}),
});
const schedule = new Schedule(this, 'Schedule', {
schedule: ScheduleExpression.rate(Duration.minutes(10)),
target,
description: 'This is a test schedule that invokes a lambda function every 10 minutes.',
});
CDK の記憶がほぼなくなっていた私は、targets とか、ScheduleTargetInput とか ScheduleExpression ってどこから参照するんだろうとなりました。
公式ドキュメントを見ると aws_scheduler_targets module
というモジュールがあることが分かったので、targets についてはこのモジュールを使うようだということがわかりました。
わからなかったのが ScheduleTargetInput で、私は最初これは、aws_scheduler_targets
モジュールに含まれているものと思っていたのですが、実際には違いました。
悩んだ結果、targets.LambdaInvoke のプロパティを見れば良いということに気付きました。私は VS Code を使っているのですが、LambdaInvoke にカーソルをあてると、プロパティとして、最初に呼び出す Lambda 関数を指定し、次に、props として、cdk.aws_scheduler_targets.ScheduleTargetBaseProps
を指定すれば良いということがわかります。
そこで公式ドキュメントの以下のページを見ると ScheduleTargetBaseProps
がどのようなプロパティで構成されているかがわかりました。input の値は ScheduleTargetInput
という型で与える必要があるようです。
公式ドキュメントの ScheduleTargetInput
の部分をクリックすると、この class は aws_scheduler
モジュールに含まれていることがわかりました。
完成したコード
ということで完成したコードが以下となります。
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import { Duration } from 'aws-cdk-lib';
import * as lambda from 'aws-cdk-lib/aws-lambda';
import * as path from 'path';
import { Schedule, ScheduleExpression, ScheduleTargetInput } from 'aws-cdk-lib/aws-scheduler';
import * as targets from 'aws-cdk-lib/aws-scheduler-targets';
export class CdkEventbridgeSchUpdateStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
const fn = new lambda.Function(this, 'MyPythonFunction', {
runtime: lambda.Runtime.PYTHON_3_9,
handler: 'index.handler',
code: lambda.Code.fromAsset(path.join(__dirname, '../lambda/hello_world')),
});
const target = new targets.LambdaInvoke(fn, {
input: ScheduleTargetInput.fromObject({
"payload": "useful",
}),
});
const schedule = new Schedule(this, 'Schedule', {
schedule: ScheduleExpression.rate(Duration.minutes(10)),
target,
description: 'This is a test schedule that invokes a lambda function every 10 minutes.',
});
}
}
デプロイ結果の確認
このコードをデプロイしてみると以下のような EventBridge Scheduler が作成されました。
なるほど、タイムゾーンはデフォルトだと UTC で作成されるんですね。
LambdaInvoke
で定義したペイロードがちゃんと反映されてますね。また CDK L2 コンストラクトということもあって、特に IAM ロールの定義はしていませんが、自動で IAM ロールも作成されています。このあたりが CDK の良いところですよね。
ポリシーはこんな形になっていました。Lambda のバージョン発行まで考えられたポリシーになっていますね。
また、デッドレターキューや暗号化はさすがにデフォルトだと未設定の状態でした。
スケジュールグループの作成
EventBridge Scheduler のスケジュールグループの作成もやってみます。InvocationAttemptCount などの EventBridge Scheduler の各種 CloudWatch メトリクスはスケジュールグループごとのカウントになるので、個人的には細かめな単位で作っておいたほうがいいかなと思っています。
追記したコードがこちらになります。
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import { Duration } from 'aws-cdk-lib';
import * as lambda from 'aws-cdk-lib/aws-lambda';
import * as path from 'path';
+ import { Schedule, ScheduleExpression, ScheduleTargetInput, ScheduleGroup } from 'aws-cdk-lib/aws-scheduler';
import * as targets from 'aws-cdk-lib/aws-scheduler-targets';
export class CdkEventbridgeSchUpdateStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
const fn = new lambda.Function(this, 'MyPythonFunction', {
runtime: lambda.Runtime.PYTHON_3_9,
handler: 'index.handler',
code: lambda.Code.fromAsset(path.join(__dirname, '../lambda/hello_world')),
});
const target = new targets.LambdaInvoke(fn, {
input: ScheduleTargetInput.fromObject({
"payload": "useful",
}),
});
+ const scheduleGroup = new ScheduleGroup(this, "ScheduleGroup", {
+ scheduleGroupName: "MyScheduleGroup",
+ });
const schedule = new Schedule(this, 'Schedule', {
schedule: ScheduleExpression.rate(Duration.minutes(10)),
target,
description: 'This is a test schedule that invokes a lambda function every 10 minutes.',
+ scheduleGroup,
});
}
}
追記してから再度 cdk deploy
をしたらエラーになりました。
Do you wish to deploy these changes (y/n)? y
CdkEventbridgeSchUpdateStack: deploying... [1/1]
CdkEventbridgeSchUpdateStack: creating CloudFormation changeset...
7:46:06 | UPDATE_FAILED | AWS::Scheduler::Schedule | Schedule83A77FD1
Resource handler returned message: "Resource of type 'AWS::Scheduler::Schedule' with identifier 'CdkEventbridgeSchUpdateStack-Schedule83A77FD1-1CN8R735G1P9S' was not found." (
RequestToken: 4f4c6a64-dafd-a80c-c55c-416cd255c702, HandlerErrorCode: NotFound)
❌ CdkEventbridgeSchUpdateStack failed: _ToolkitError: The stack named CdkEventbridgeSchUpdateStack failed to deploy: UPDATE_ROLLBACK_COMPLETE: Resource handler returned message: "Resource of type 'AWS::Scheduler::Schedule' with identifier 'CdkEventbridgeSchUpdateStack-Schedule83A77FD1-1CN8R735G1P9S' was not found." (RequestToken: 4f4c6a64-dafd-a80c-c55c-416cd255c702, HandlerErrorCode: NotFound)
どうやら CdkEventbridgeSchUpdateStack-Schedule83A77FD1-1CN8R735G1P9S
というスケジュールが存在しないといってるように見えますが、ちゃんと存在しているので何が原因なのかよく分からないですね。
EventBridge Scheduler は一度スケジュールを作成した後にスケジュールグループを変更することが出来ないので、そのあたりが原因かもしれませんね。
cdk destroy
(destroy 後も作成されたスケジュールグループが残っていたので手で削除しました)した後に cdk deploy
したらちゃんと正常に作成されました。
まとめ
ということで、Amazon EventBridge Scheduler 用の CDK L2 コンストラクトが一般提供されたというアップデートの紹介でした。この記事がどなたかの参考になれば幸いです。
以上、とーちでした。