😺
【AWS SAM】EventBridgeでLambdaを定期実行するテンプレートの書き方
背景
- EventBridgeを使ってLambdaを定期実行するときに、CloudFormationテンプレートでは主に2つの書き方がありどちらにするか迷ったため、それぞれのメリット・デメリットと記述方法を比較してみました。
比較
1. 組み合わせテンプレートの使用
Lambdaの定義中にEventBridgeRuleの定義を含める方法です。
メリット
- コードの記述量が少なく、管理するテンプレートも減らせる。
- YAML では、イベントパターンを定義するだけでよく、AWS SAMが必要なアクセス許可を持つ IAM ロールを自動的に作成してくれる。
デメリット
- LambdaとEventBridgeのコードが密結合になっているため、別々に管理できずリソース(特にEventBridgeRule)を認識しずらい。
- IAMロールなど細かい制御ができない。
- 一つのルールでは一つのLambdaしか指定できない。(ベストプラクティス)
コード例
template.yaml
Resources:
HelloWorldFunction: # Lambdaの定義
Type: AWS::Serverless::Function
Properties:
CodeUri: hello-world/
Handler: hello-world
Runtime: python3.10
Architectures:
- x86_64
Events: # Lambdaの定義内でEventBridgeRuleを定義
ScheduledFunction:
Type: ScheduleV2
Properties:
ScheduleExpression: cron(0/5 * * * ? *) # 5分毎にトリガー
ScheduleExpressionTimezone: "Asia/Tokyo" # 日本のタイムゾーンを考慮
State: ENABLED
Name: dev-hoge-hello-schedule-lambda
Description: hello schedule
2. 分離テンプレート
Lambdaの定義とEventBridgeRuleの定義を分離する方法です。
メリット
- LambdaとEventBridgeのコードが疎結合になっているため、リソース(EventBridgeRule)の数を把握しやすく、EventBridgeのスタックに統合したりと管理しやすい。
- 一つのルールから複数のLambdaを指定できる。
-AWS SAM テンプレートの外部のリソースに接続している場合でも対応できる。
デメリット
- コードの記述量と管理するテンプレートが増える。
- 必要なアクセス許可を持つ IAM ロールの定義を自分で行う必要がある。
コード例
template.yaml
Resources:
HelloWorldFunction: # Lambdaの定義
Type: AWS::Serverless::Function
Properties:
CodeUri: hello-world/
Handler: hello-world
Runtime: python3.10
Architectures:
- x86_64
EventBridgeRule: # Lambdaの定義とは別にEventBridgeRuleを定義
Type: AWS::Events::Rule
Properties:
EventBusName: default
Name: dev-hoge-hello-schedule-lambda
Description: hello schedule
ScheduleExpression: cron(0/5 * * * ? *) # 5分毎にトリガー
State: ENABLED
Targets:
- Arn: !GetAtt LambdaFunction.Arn # トリガー対象のLambdaのArnを指定
Id: LambdaFunction # トリガー対象のLambdaのidを指定
PermissionForEventsToInvokeLambda: # EventBridgeRuleからLambdaをトリガーするためのPermissionを定義
Type: AWS::Lambda::Permission
Properties:
FunctionName: !Ref HelloWorldFunction
Action: lambda:InvokeFunction
Principal: events.amazonaws.com
SourceArn: !GetAtt 'EventBridgeRule.Arn'
結論
- 1 つのルールによって 1 つの Lambda 関数が呼び出されるパターンでは、組み合わせテンプレートがお勧め。EventBridgeRuleを一か所でまとめて管理したいという要望がなければこの方法がシンプルで良さそう。
- 複雑なルーティングロジックがある場合、または AWS SAM テンプレートの外部のリソースに接続している場合には、分離テンプレートの利用が推奨されるようです。
補足
- 通常は"Events/Properties"には"Schedule"を設定するが、タイムゾーンを考慮する場合は"ScheduleExpression"を設定し、"ScheduleExpressionTimezone"に想定するタイムゾーンを記載する必要がある。
参考
Discussion
EventBridge Rule(Type: AWS::Events::Rule)はタイムゾーン設定(ScheduleExpressionTimezone)ができないためコード例の記載を修正。