Serverless Frameworkを使ってLambdaをS3にアクセスさせてみたいと思います。
まずserverless.ymlを以下のように書きました。
service: serverless-tutorial frameworkVersion: '2' provider: name: aws runtime: python3.8 versionFunctions: false lambdaHashingVersion: 20201221 memorySize: 128 region: ap-northeast-1 functions: hello: handler: handler.hello events: - http: path: echo/hello method: get s3test: handler: s3test.handler events: - s3: bucket: photos20220120 event: s3:ObjectCreated:*
そしてs3test.pyを以下のように書きました。
import datetime import boto3 def handler(event, context): dt_now = datetime.datetime.now() print('object created at ' + str(dt_now) + '.') # 時刻を出力 s3 = boto3.client('s3') response = s3.list_objects_v2(Bucket="photos20220120") # serverless.ymlで定義しているバケット名 for object in response['Contents']: print(object['Key']) #S3バケットにあるオブジェクト名を出力する
動作確認用に時刻を出力した後、S3にあるオブジェクト一覧を出すようにしています。
そして以下のコマンドでデプロイしました。
sls deploy -v
-vをつけると詳細なログが出力できるようです。
--verbose or -v Shows all stack events during deployment, and display any Stack Output.
あと、以前はdeployコマンドに--regionオプションをつけてap-northeast-1を指定していたのですが、serverless.ymlでリージョンを書いておけばデフォルトがそのリージョンになるようです。
無事デプロイできたのでS3にファイルをアップロードしてみました。(GUIでアップロードしましたが、そろそろ慣れてきたのでCLIも使っていきたい)
するとCloudWatch Logs groupにログが出力されていましたが、時刻は出力されているもののS3のオブジェクト名はAccess Deniedになってエラーが出力されていました。
時刻の出力はLambda関数の中で完結しているので問題ないが、S3からオブジェクトの情報を取得するにはS3バケットにアクセスする必要があるので、その権限が無くエラーになっているようです。
IAMの設定方法についてはこちらのページを読みました。
まずは細かい設定はせずにS3への全アクションを許可してみました。
serverless.ymlのproviderプロパティにiamを追加しています。
service: serverless-tutorial frameworkVersion: '2' provider: name: aws runtime: python3.8 versionFunctions: false lambdaHashingVersion: 20201221 memorySize: 128 region: ap-northeast-1 iam: role: statements: - Effect: "Allow" Action: - "S3:*" Resource: - "*" functions: hello: handler: handler.hello events: - http: path: echo/hello method: get s3test: handler: s3test.handler events: - s3: bucket: photos20220120 event: s3:ObjectCreated:*
再度デプロイしました。
sls deploy -v
改めてS3にファイルをアップロードすると、今度は無事オブジェクト名が取得できていました。
ちなみにIAMは実際どう設定されているか探してみると「serverless-tutorial-dev-ap-northeast-1-lambdaRole」が設定されていました。
ポリシーにはS3へのアクセスを許可する設定がありました。
以上です。