AWS SAM(Serverless Application Model)を使用すると、AWS LambdaとS3を組み合わせて簡単にサーバーレスアプリケーションを構築できます。
この記事では、S3バケットにファイルがアップロードされたときに自動的に起動するLambda関数を作成し、ファイル名とそのバケット名を取得してみました。
実際に作成する中でエラーも出たので合わせて対応を書いていきます。
事前準備
AWS SAM をインストールしておきます
> pip install aws-sam-cli
SAM プロジェクトの作成
> sam init
Which template source would you like to use?
1 - AWS Quick Start Templates
Choose an AWS Quick Start application template
1 - Hello World Example
Use the most popular runtime and package type? (Python and zip) [y/N]: y
Would you like to enable X-Ray tracing on the function(s) in your application? [y/N]: N
Would you like to enable monitoring using CloudWatch Application Insights?
For more info, please view https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/cloudwatch-application-insights.html [y/N]: N
Would you like to set Structured Logging in JSON format on your Lambda functions? [y/N]: N
Project name [sam-app]: 好きなプロジェクト名
Lambda 関数を修正
import json
# import requests
def lambda_handler(event, context):
for rec in event["Records"]:
print("アップロードされたファイルは: " + rec["s3"]["object"]["key"])
print("アップロードされたバケットは: " + rec["s3"]["bucket"]["name"])
ローカルテスト
イベントの作成
sam コマンドでS3 サンプルイベントが作成できるか確認
> sam local generate-event
Commands:
alexa-skills-kit
alexa-smart-home
...
s3
S3サービスに対してput サンプルイベントを生成できるか確認
> sam local generate-event s3
Commands:
batch-invocation Generates an Amazon S3 Batch Operations Invocation Event
delete Generates an Amazon S3 Delete Event
put Generates an Amazon S3 Put Event
S3 put サンプルイベントを確認
> sam local generate-event s3 put
{
"Records": [
{
"eventVersion": "2.0",
"eventSource": "aws:s3",
"awsRegion": "us-east-1",
...
このままでは使えないので json ファイルとして作成
> sam local generate-event s3 put | tee events/s3-local-event.json
コマンドの説明
- sam local generate-event s3 put: S3バケットへのputイベントにトリガーされるイベント作成
- tee events/s3-local-event.json: イベントを標準出力と event/s3-local-event.jsonに出力
作成された event/s3-local-event.json
{
"Records": [
{
"eventVersion": "2.0",
"eventSource": "aws:s3",
"awsRegion": "us-east-1",
"eventTime": "1970-01-01T00:00:00.000Z",
"eventName": "ObjectCreated:Put",
"userIdentity": {
"principalId": "EXAMPLE"
},
"requestParameters": {
"sourceIPAddress": "127.0.0.1"
},
"responseElements": {
"x-amz-request-id": "EXAMPLE123456789",
"x-amz-id-2": "EXAMPLE123/5678abcdefghijklambdaisawesome/mnopqrstuvwxyzABCDEFGH"
},
"s3": {
"s3SchemaVersion": "1.0",
"configurationId": "testConfigRule",
"bucket": {
"name": "example-bucket",
"ownerIdentity": {
"principalId": "EXAMPLE"
},
"arn": "arn:aws:s3:::example-bucket"
},
"object": {
"key": "test/key",
"size": 1024,
"eTag": "0123456789abcdef0123456789abcdef",
"sequencer": "0A1B2C3D4E5F678901"
}
}
}
]
}
※サンプルイベントを変更したい場合は以下のhelpコマンドに沿って調整してください(今回はデフォルトのまま)
https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/using-sam-cli-local-generate-event.html
> sam local generate-event s3 put --help
Usage: sam local generate-event s3 put [OPTIONS]
Options:
--region TEXT Specify the region name you'd like, otherwise the default = us-east-1
--partition TEXT Specify the partition name you'd like, otherwise the default = aws
--bucket TEXT Specify the bucket name you'd like, otherwise the default = example-bucket
--key TEXT Specify the key name you'd like, otherwise the default = test/key
--debug Turn on debug logging to print debug message generated by AWS SAM CLI and display timestamps.
--config-file TEXT Configuration file containing default parameter values. [default: samconfig.toml]
--config-env TEXT Environment name specifying default parameter values in the configuration file. [default:
default]
-h, --help Show this message and exit.
構築
Build の実行
> sam build --use-container
: python3.9 metadata: {}
architecture: x86_64 functions: HelloWorldFunction
Build Failed
Error: Docker is unreachable. Docker needs to be running to build inside a container.
エラーが出てしまいました。
Docker が 起動していないよとの事。
Docker Desktop を起動して再実行
> sam build --use-container
Build Succeeded
ローカル環境で Lambda を実行
s3-local-event.json に対して HelloWorldFuncion を実行
> sam local invoke -e events/s3-local-event.json HelloWorldFunction
Error: 'utf-8' codec can't decode byte 0xff in position 0: invalid start byte
またまたエラー。
utf-8 コードを使用していないからダメっぽい。
作成した s3-locla-evnet.json が utf-16 となっていたため utf-8 に変更。
再度実行
> sam local invoke -e events/s3-local-event.json HelloWorldFunction
Invoking app.lambda_handler (python3.11)
Local image was not found.
Removing rapid images for repo public.ecr.aws/sam/emulation-python3.11
Building image.........................................................................................................................................................................................
Using local image: public.ecr.aws/lambda/python:3.11-rapid-x86_64.
Mounting C:\~\Project\.aws-sam\build\HelloWorldFunction as /var/task:ro,delegated,
inside runtime container
START RequestId: 9b97556a-10c2-4840-aac8-f50b5182fe4d Version: $LATEST
アップロードされたファイルは: test/key
アップロードされたバケットは: example-bucket
END RequestId: cb70f32b-6d80-41de-9492-6515f3f4d843
REPORT RequestId: cb70f32b-6d80-41de-9492-6515f3f4d843 Init Duration: 0.03 ms Duration: 39.65 ms Billed Duration: 40 ms Memory Size: 128 MB Max Memory Used: 128 MB
出力されました。
出力されるファイル名とバケット名を変更してみる
{
"Records": [
{
"eventVersion": "2.0",
"eventSource": "aws:s3",
"awsRegion": "us-east-1",
"eventTime": "1970-01-01T00:00:00.000Z",
"eventName": "ObjectCreated:Put",
"userIdentity": {
"principalId": "EXAMPLE"
},
"requestParameters": {
"sourceIPAddress": "127.0.0.1"
},
"responseElements": {
"x-amz-request-id": "EXAMPLE123456789",
"x-amz-id-2": "EXAMPLE123/5678abcdefghijklambdaisawesome/mnopqrstuvwxyzABCDEFGH"
},
"s3": {
"s3SchemaVersion": "1.0",
"configurationId": "testConfigRule",
"bucket": {
"name": "example-bucket-oreore",
"ownerIdentity": {
"principalId": "EXAMPLE"
},
"arn": "arn:aws:s3:::example-bucket"
},
"object": {
"key": "test/key/oreore",
"size": 1024,
"eTag": "0123456789abcdef0123456789abcdef",
"sequencer": "0A1B2C3D4E5F678901"
}
}
}
]
}
s3 buket name に oreore を追加
s3 object key に oreore を追加
再度HelloWorldFunctionを実行
> sam local invoke -e events/s3-local-event.json HelloWorldFunction
Invoking app.lambda_handler (python3.11)
Local image is up-to-date
Using local image: public.ecr.aws/lambda/python:3.11-rapid-x86_64.
Mounting C:\Users\kutin\Desktop\Program\python\AWS_SAM_Hands-On\AWS_SAM_CheckProject\.aws-sam\build\HelloWorldFunction as
/var/task:ro,delegated, inside runtime container
START RequestId: b399de95-79e5-4d1f-97ea-23888467134b Version: $LATEST
アップロードされたファイルは: test/key/oreore
アップロードされたバケットは: example-bucket-oreore
END RequestId: 52e205a7-a3e7-45de-affe-3b7734859552
REPORT RequestId: 52e205a7-a3e7-45de-affe-3b7734859552 Init Duration: 0.03 ms Duration: 32.08 ms Billed Duration: 33 ms Memory Size: 128 MB Max Memory Used: 128 MB
オレオレが追加されているのが確認できました。
これでS3 put イベントに対して Lambda がLocalで実行されるのが確認できました。
次回は実際にAWS上で実行するように設定を変更して動作確認を行う予定です。