Serverless Framework入門(8) S3と連携する

今回はS3に関連するイベントを動かしてみたいと思います。
主に公式ドキュメントを読みながらコード書きました。

www.serverless.com

デプロイしているserverlessスタックは以下のコマンドで削除することができました。

sls remove --region ap-northeast-1

まずS3が作成されることを確認したかったので、serverless.ymlを以下のようにしてみました。

service: serverless-tutorial

frameworkVersion: '2'

provider:
  name: aws
  runtime: python3.8
  versionFunctions: false
  lambdaHashingVersion: 20201221
  memorySize: 128
  region: ap-notheast-1

functions:
  hello:
    handler: handler.hello
    events:
      - http:
          path: echo/hello
          method: get
      - s3: photos20220120

以下のデプロイコマンドを実行しました。

sls deploy --region ap-northeast-1

すると指定したバケット名(photos20220120)でS3バケットが作成されていました。 f:id:JunpeiNakasone:20220120063419p:plain

とりあえずS3バケット作れることが体験できたので、次はS3に何かオブジェクトが追加されたらログを出力するコードを書いてみたいと思います。

Serverless Frameworkの公式ドキュメントに以下の文言があるので、eventの構文はAWSのドキュメントを参照すると良さそうです。

Check out the AWS documentation to learn more about all the different event types that can be configured.

たぶんAWSのドキュメントはこのページの「Supported event types for SQS, SNS, and Lambda」あたりかと

docs.aws.amazon.com

serverless.ymlにs3testというfunctionを追加してみました。

service: serverless-tutorial

frameworkVersion: '2'

provider:
  name: aws
  runtime: python3.8
  versionFunctions: false
  lambdaHashingVersion: 20201221
  memorySize: 128
  region: ap-notheast-1

functions:
  hello:
    handler: handler.hello
    events:
      - http:
          path: echo/hello
          method: get
  s3test:
    handler: handler.s3test
    events:
      - s3:
          bucket: photos20220120
          event: s3:ObjectCreated:*

Pythonのファイルも新しくs3test.py作成し、とりあえずログを出力するようにしてみました。(ログがどこに出力されるかはよくわかっていない。たぶんこの書き方だとCloudWatchではなくLambdaのコンソールでログが確認できる?)

# s3test.py
def handler(event, context):
  print('object created on S320220120.')

以下のコマンドでデプロイし

sls deploy --region ap-northeast-1

ターミナルに以下のように表示され、functionsが二つになっていることが確認できました。

Serverless: Stack update finished...
Service Information
service: serverless-tutorial
stage: dev
region: ap-northeast-1
stack: serverless-tutorial-dev
resources: 15
api keys:
  None
endpoints:
  GET - https://tgwgwpfxgl.execute-api.ap-northeast-1.amazonaws.com/dev/echo/hello
functions:
  hello: serverless-tutorial-dev-hello
  s3test: serverless-tutorial-dev-s3test
layers:
  None

S3バケットが作成されているので適当に画像をアップロードしてみます。
f:id:JunpeiNakasone:20220120065329p:plain f:id:JunpeiNakasone:20220120065355p:plain

調べてみるとCloudWatchにログが出力されているようで、コンソールから見てみるとエラーになっているようでした。   f:id:JunpeiNakasone:20220120065924p:plain

「 missing on module 'handler'」ということなので、きっとコードの書き方がおかしいと思い見直してみるとserverless.ymlで「handler: handler.s3test」と書くべきところを「handler: s3test.handler」と書いていました。

serverless.ymlを以下のように修正しました。

service: serverless-tutorial

frameworkVersion: '2'

provider:
  name: aws
  runtime: python3.8
  versionFunctions: false
  lambdaHashingVersion: 20201221
  memorySize: 128
  region: ap-notheast-1

functions:
  hello:
    handler: handler.hello
    events:
      - http:
          path: echo/hello
          method: get
  s3test:
    handler: s3test.handler
    events:
      - s3:
          bucket: photos20220120
          event: s3:ObjectCreated:*

再度デプロイし、画像をアップロードしました。

CloudWatch Logsを確認するとログが出力されていました!
f:id:JunpeiNakasone:20220120070627p:plain

S3と繋げるといろいろ実装する幅が広がり楽しいです。