タイトルの通りです。はい。

AWS Lambdaでは関数あたり最大15分(900秒)の処理が実行できます。
そして、いまやコンテナイメージもサポートしてるようです。

コンテナイメージをサポートした、といってもこれまで通りのハンドラ関数は必要なのですが、 だとしてもこれは結構便利じゃないかしら、と思ったのです。

PythonでLambda関数を作ろうとすると、virtualenvとか使って必要なライブラリと合わせてzipにパッケージングするみたいな手順が必要だったと思いますが、このパッケージング作業をDockerfileにまとめることができる。ついでに(?)開発環境と実行環境を統一できちゃう。

さらに、sam cliでプロジェクトのテンプレがさくっと作れるのでとってもイージー。

$ sam init
Which template source would you like to use?
        1 - AWS Quick Start Templates
        2 - Custom Template Location
Choice: 1
What package type would you like to use?
        1 - Zip (artifact is a zip uploaded to S3)
        2 - Image (artifact is an image uploaded to an ECR image repository)
Package type: 2

Which base image would you like to use?
        1 - amazon/nodejs14.x-base
        2 - amazon/nodejs12.x-base
        3 - amazon/nodejs10.x-base
        4 - amazon/python3.8-base
        5 - amazon/python3.7-base
        6 - amazon/python3.6-base
        7 - amazon/python2.7-base
        8 - amazon/ruby2.7-base
        9 - amazon/ruby2.5-base
        10 - amazon/go1.x-base
        11 - amazon/java11-base
        12 - amazon/java8.al2-base
        13 - amazon/java8-base
        14 - amazon/dotnet5.0-base
        15 - amazon/dotnetcore3.1-base
        16 - amazon/dotnetcore2.1-base
Base image: 4

Project name [sam-app]: my_batch_function

Cloning app templates from https://github.com/aws/aws-sam-cli-app-templates

AWS quick start application templates:
        1 - Hello World Lambda Image Example
        2 - PyTorch Machine Learning Inference API
        3 - Scikit-learn Machine Learning Inference API
        4 - Tensorflow Machine Learning Inference API
        5 - XGBoost Machine Learning Inference API
Template selection: 1

    -----------------------
    Generating application:
    -----------------------
    Name: my_batch_function
    Base Image: amazon/python3.8-base
    Dependency Manager: pip
    Output Directory: .

    Next steps can be found in the README file at ./my_batch_function/README.md
$ tree .
.
└── my_batch_function
    ├── README.md
    ├── __init__.py
    ├── events
    │   └── event.json
    ├── hello_world
    │   ├── Dockerfile
    │   ├── __init__.py
    │   ├── app.py
    │   └── requirements.txt
    ├── template.yaml
    └── tests
        ├── __init__.py
        └── unit
            ├── __init__.py
            └── test_handler.py

さて、上記手順で作成するとテンプレートは API Gateway -> Lambda という普通の構成で作成されるのですが、
定期バッチ処理としては、
EventBridge(cron) -> SQS -> Lambda
という感じで定義しておくと、いざというときの手動実行にも対応できるので良さそうです。
(※バッチ処理のキックをAPIとして公開して外部サービスからコントロールしたいなどの要求があるなら、たとえば IFTTT -> API Gateway -> Lambdaとかでも良いかもしれません)

書き換えたテンプレートはこんな感じです。

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: my_batch_function

Globals:
  Function:
    Timeout: 900
    Environment:
      Variables:
        API_KEY: '****'

Resources:
  MyFunction:
    Type: AWS::Serverless::Function
    Properties:
      PackageType: Image
      MemorySize: 512
      Events:
        MySQSEvent:
          Type: SQS
          Properties:
            Queue: !GetAtt MySqsQueue.Arn
            BatchSize: 1
    Metadata:
      Dockerfile: Dockerfile
      DockerContext: './my_batch_function'
      DockerTag: python3.8-v1

  MySqsQueue:
    Type: AWS::SQS::Queue
    Properties: 
      VisibilityTimeout: 900
      MessageRetentionPeriod: 3600

  MyQueuePolicy: 
    Type: AWS::SQS::QueuePolicy
    Properties: 
      PolicyDocument: 
        Id: !Ref MySqsQueue
        Statement: 
          - Sid: QueuePolicy-MySqsQueue
            Effect: Allow
            Principal: '*'
            Action: 'SQS:*'
            Resource: 
              !GetAtt MySqsQueue.Arn
      Queues:
        - !Ref MySqsQueue

  MyEventRule:
    Type: AWS::Events::Rule
    Properties:
      Name: myBatchFunctionCron
      ScheduleExpression: 'cron(0 0 ? * SUN *)'
      State: ENABLED
      Targets:
        - Arn: !GetAtt MySqsQueue.Arn
          Id: myBatchFunctionSchedule
          Input: |
            {
              "type": "cron",
              "params": ["hoge", "fuga"]
            }            

参考