[Serverless Framework入門]S3にアップロードされているオブジェクト名を取得するLambdaをデプロイしてみた

2022.02.24

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは、アノテーションの仲宗根です。

はじめに

Serverless Frameworkの使い方が今一つ理解できていなかったので、まずは簡単な構成から自分で作ってみました。

やってみた

セットアップするため以下のコマンドを実行しました。

npm install -g serverless
serverless create --template aws-python3 -n serverless-s3-demo

すると以下のようにhandler.pyとserverless.ymlが作成されていました。

handler.pyはLambda関数を書くことは推測できましたが、serverless.ymlがよくわからなかったので公式ドキュメントで調べてみると以下の説明がありました。

The newly created project should contain a serverless.yml file. This file defines everything that should be deployed to AWS: functions, events, resources and more.

serverless.ymlでAWSにデプロイする関数、イベント、リソースなどを定義するようです。

S3バケットを作成し、そのバケットにオブジェクトがアップロードされたらLambda関数を呼び出すようにserverless.ymlを書いてみました。

service: serverless-s3-demo
frameworkVersion: '2'

provider:
name: aws
runtime: python3.8
lambdaHashingVersion: 20201221
region: ap-northeast-1

functions:
  hello:
    handler: handler.hello
    events:
      - s3:
        bucket: serverless-s3-20220131
        event: s3:ObjectCreated:*

handler.pyでは、Lambdaがオブジェクトが作成された時刻を出力をした後に、S3に存在するオブジェクト名一覧を出力するようにしました。

import datetime
import boto3

def hello(event, context):
dt_now = datetime.datetime.now()
print('object created at ' + str(dt_now) + '.') # 時刻を出力

s3 = boto3.client('s3')

response = s3.list_objects_v2(Bucket="serverless-s3-20220131") # serverless.ymlで定義しているバケット名

for object in response['Contents']:
    print(object['Key']) #S3バケットにあるオブジェクト名を出力する

以下のコマンドでServerless FrameworkをAWS環境にデプロイします。

sls deploy -v

デプロイが完了するとターミナルにStack create finished.のログが出力されました。

serverless.ymlに記述した「serverless-s3-20220131」というバケット名でS3バケットが作成されていました。

試しにtest1.txtというテキストファイルをアップロードしてみました。

CloudWatch Log Groupが作成され、ログが出力されていました。

Pythonで時刻を出力することはできているのでLambda関数自体は想定通り呼び出せているようですが、S3のオブジェクト情報を取得する際にAccess Diniedエラーになっているようです。

原因は、Lambda関数にS3へアクセスするための権限を付与できていないことでした。 serverless.ymlを修正し、IAMの設定を追記しました。(今回は動作確認なので権限強めに設定しています)

service: serverless-s3-demo
frameworkVersion: '2'

provider:
name: aws
runtime: python3.8
lambdaHashingVersion: 20201221
region: ap-northeast-1
iam: # 追加
  role:
    statements:
      - Effect: "Allow"
        Action:
          - "S3:*"
        Resource:
          - "*"
functions:
  hello:
    handler: handler.hello
    events:
      - s3:
        bucket: serverless-s3-20220131
        event: s3:ObjectCreated:*

修正後に再度Serverless Frameworkをデプロイし、新しくtest2.txtというテキストファイルをS3にアップロードしました。

S3の状態は以下のようになっています。

CloudWatchを確認すると新しくログが出力されていました。

想定通りLambda関数が呼び出され、オブジェクト名一覧が取得できています。

まとめ

S3イベントをトリガーにLambdaを呼び出せたので、あとは要件に合わせてLambdaの処理を書くことでS3を活用したいろんな場面で柔軟に使えそうだと思いました。 少しずついろんな処理を試していきたいと思います。

アノテーション株式会社について

  • アノテーション株式会社は、クラスメソッド社のグループ企業として「オペレーション・エクセレンス」を担える企業を目指してチャレンジを続けています。「らしく働く、らしく生きる」のスローガンを掲げ、様々な背景をもつ多様なメンバーが自由度の高い働き方を通してお客様へサービスを提供し続けてきました。現在当社では一緒に会社を盛り上げていただけるメンバーを募集中です。少しでもご興味あれば、アノテーション株式会社WEBサイトをご覧ください。