概要
IaC 化の一環で aws SAM を触り始めました。
lambda のスケジュール設定を入れる際に、戸惑ったので備忘として残します。
やること
- aws SAM にて、時限起動の設定を実施する。
- SAM での EventBrigeScheduler の記述方法を記載します。
- ベースの Lambda と yaml は、AWS Quick Start Templates の"1 - Hello World Example"を利用します。
利用するコードについて
- "Type: AWS::Scheduler::Schedule"で指定しているセクションが該当します。
- https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-scheduler-schedule.html
- 対象のリソース(今回は Lambda)を叩くための IAMRole をつけ忘れることが多いので、注意です。
実際のyaml
AWSTemplateFormatVersion: "2010-09-09"
Transform: AWS::Serverless-2016-10-31
Description: >
  sam-app
  Sample SAM Template for sam-app
Globals:
  Functions:
    Timeout: 3
    MemorySize: 128
    LoggingConfig:
      LogFormat: JSON
Resources:
  HelloWorldFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: hello_world/
      Handler: app.lambda_handler
      Runtime: python3.9
      Architectures:
        - x86_64
      Events:
        HelloWorld:
          Type: Api
          Properties:
            Path: /hello
            Method: get
  # EventBridge Scheduler
  EventBridgeScheduler:
    Type: AWS::Scheduler::Schedule
    Properties:
      Name: "event-bridge-scheduler"
      ScheduleExpression: "cron(00 00 * * ? *)"
      ScheduleExpressionTimezone: "Asia/Tokyo"
      FlexibleTimeWindow:
        Mode: "OFF"
      Target:
        Arn: !GetAtt HelloWorldFunction.Arn
        RoleArn: !GetAtt EventBridgeSchedulerRole.Arn
      State: "ENABLED"
  # EventBridge IAM Role
  EventBridgeSchedulerRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: "event-bridge-schedule-role"
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service: scheduler.amazonaws.com
            Action: "sts:AssumeRole"
      Policies:
        - PolicyName: "EventBridgeInvokeFunction"
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - lambda:InvokeFunction
                Resource:
                  - !GetAtt HelloWorldFunction.Arn
Outputs:
  HelloWorldApi:
    Description: API Gateway endpoint URL for Prod stage for Hello World function
    Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/hello/"
  HelloWorldFunction:
    Description: Hello World Lambda Function ARN
    Value: !GetAtt HelloWorldFunction.Arn
  HelloWorldFunctionIamRole:
    Description: Implicit IAM Role created for Hello World function
    Value: !GetAtt HelloWorldFunction.Arnコードの説明
EventBridge Scheduler の設定
Type: AWS::Scheduler::Schedule:
EventBridge Schedulerリソースを定義します。
ScheduleExpression: "cron(00 00 * * ? *)":
毎日午前0時に実行するcron式です。
ScheduleExpressionTimezone:"Asia/Tokyo":
タイムゾーンを東京に設定し上記のCronが確実に日本時間(JST)で実行されるようにしています。
State: "ENABLED"
EventBridge Schedulerは、実行した後にそのスケジュールを永続化するかを選ぶ仕様のため、明示的に永続化するようにしています。
おまけ:CloudwatchEvent がまだ内部的に残っている
AWS Quick Start Templates の"5 - Scheduled task"で生成される template.yaml を見ると"CloudWatchEvent"の記述があります。
CloudwatchEvent は、EventBrige scheduler にシフトし、管理コンソールには存在しなくなりましたが、内部的には残っているようです。
以下の方が Lambda のセクションに付随する形で記述できるので、こちらの方が楽ではありますね。
Resources:
  ScheduledEventLogger:
    Type: AWS::Serverless::Function
    Properties:
      Description: A Lambda function that logs the payload of messages sent to an associated SQS queue.
      Runtime: nodejs20.x
      Architectures:
        - x86_64
      Handler: src/handlers/scheduled-event-logger.scheduledEventLoggerHandler
      Events:
        CloudWatchEvent:
          Type: Schedule
          Properties:
            Schedule: cron(0 * * * ? *)
      MemorySize: 128
      Timeout: 100- "Type: Schedule"のドキュメント
- 他にも"ScheduleV2"という指定方法もあるようです。わかりづらいですね。
最後に
最近 SAM を触り始めましたが、これはかなり楽しいですね。
ドキュメントが少しわかりづらいのと、クイックスタートのランタイムが古く更新があまりないので初心者が詰みやすいですが、一度デプロイできれば存外さっくり理解できますね。
以上、どなたかのお役に立てば幸いです。
