- LocalStackを用いて、S3バケットにオブジェクト登録を行うAPIをAPI Gateway + Lambdaで作成する方法についてメモする。
LocalStack及びS3 準備
-
こちらの手順でLocalStackとオブジェクト登録先のバケット(
sample-bucket
)を準備しておく。
API Gateway 準備
-
REST API を作成する
- リソースID(
id
)を控える
aws apigateway create-rest-api --name 'LambdaS3TestAPI' --endpoint-url=http://localhost:4567 --region us-east-1 --profile localstack { "id": "A-Z2699261A-Z3", "name": "'LambdaS3TestAPI'", "createdDate": "2021-10-09T04:56:42.976000+00:00" }
- リソースID(
ルートリソースID取得
aws apigateway get-resources --rest-api-id A-Z2699261A-Z3 --endpoint-url=http://localhost:4567 --region us-east-1 --profile localstack
{
"items": [
{
"id": "8955626A-Z80",
"path": "/",
"resourceMethods": {
"GET": {}
}
}
]
}
- 子リソース追加
パス名:lambda_s3_test
aws apigateway create-resource --rest-api-id A-Z2699261A-Z3 --parent-id 8955626A-Z80 --path-part lambda_s3_test --endpoint-url=http://localhost:4567 --region us-east-1 --profile localstack
{
"id": "5A-Z12A-Z75998",
"parentId": "8955626A-Z80",
"pathPart": "lambda_s3_test",
"path": "/lambda_s3_test",
"resourceMethods": {
"GET": {}
}
}
- HTTPメソッド追加
aws apigateway put-method --rest-api-id A-Z2699261A-Z3 --resource-id 5A-Z12A-Z75998 --http-method POST --authorization-type "NONE" --endpoint-url=http://localhost:4567 --region us-east-1 --profile localstack
{
"httpMethod": "POST",
"authorizationType": "NONE"
}
Lambda 準備
lambda_s3_test.py
S3バケットsample-bucket
にJSONファイルをオブジェクトとして配置する。
import boto3
from boto3.session import Session
from datetime import datetime
session = Session(aws_access_key_id='dummy',
aws_secret_access_key='dummy',
region_name='ap-northeast-1'
)
s3 = session.resource(
service_name='s3',
endpoint_url='http://localhost:4572'
)
def lambda_handler(event, context):
bucket_name = 'sample-bucket'
key = 'sample_' + datetime.now().strftime('%Y-%m-%d-%H-%M-%S') + '.json'
body = '{"sample_key":"sample_value"}'
s3.Bucket(bucket_name).put_object(Key=key, Body=body)
return 's3 put JSON_FILE'
上記ファイルを
lambda_s3_test.zip
にzip化する。アップロード
aws lambda create-function --function-name="sample-function" --runtime=python3.8 --role="arn:aws:iam::123456789012:role/service-role/lambda-sample-role" --handler=lambda_s3_test.lambda_handler --zip-file fileb://lambda_s3_test.zip --endpoint-url=http://localhost:4574 --profile=localstack
- 起動
aws lambda invoke --cli-binary-format raw-in-base64-out --function-name sample-function result.log --endpoint-url=http://localhost:4574 --profile=localstack
{
"StatusCode": 200
}
- 確認
aws s3 ls s3://sample-bucket --endpoint-url=http://localhost:4572 --profile=localstack
2021-10-09 11:25:03 29 sample_2021-10-09-02-25-03.json
※ファイルが配置されている。
API Gateway - Lambda設定
- Lambda ARN確認
aws lambda list-functions --endpoint-url=http://localhost:4574 --profile=localstack
{
"Functions": [
{
"FunctionName": "sample-function",
"FunctionArn": "arn:aws:lambda:us-east-1:000000000000:function:sample-function",
"Runtime": "python3.8",
"Handler": "lambda_s3_test.lambda_handler",
"Timeout": 60,
"Version": "$LATEST"
}
]
}
- API Gateway - Lambda設定
aws apigateway put-integration --rest-api-id A-Z2699261A-Z3 --resource-id 5A-Z12A-Z75998 --http-method POST --type AWS_PROXY --integration-http-method POST --uri arn:aws:apigateway:us-east-1:lambda:path/2015-03-31/functions/arn:aws:lambda:us-east-1:000000000000:function:sample-function/invocations --passthrough-behavior WHEN_NO_MATCH --endpoint-url=http://localhost:4567 --region us-east-1 --profile localstack
{
"type": "AWS_PROXY",
"httpMethod": "POST",
"uri": "arn:aws:apigateway:us-east-1:lambda:path/2015-03-31/functions/arn:aws:lambda:us-east-1:000000000000:function:sample-function/invocations",
"integrationResponses": {
"200": {
"statusCode": 200,
"responseTemplates": {
"application/json": null
}
}
}
}
- 設定デプロイ
aws apigateway create-deployment --rest-api-id A-Z2699261A-Z3 --stage-name test --endpoint-url=http://localhost:4567 --region us-east-1 --profile localstack
{
"id": "6271136713",
"description": "",
"createdDate": "2021-10-09T05:08:40.688000+00:00"
}
動作確認
- APIリクエスト
パス:/restapis/${REST_API_ID}/test/_user_request_/${登録したAPIパス名}
POST /restapis/A-Z2699261A-Z3/test/_user_request_/lambda_s3_test HTTP/1.1
Host: localhost:4567
Content-Type: application/json
Content-Length: 2
{}
- APIレスポンス
"s3 put JSON_FILE"
- S3オブジェクト確認
aws s3 ls s3://sample-bucket --endpoint-url=http://localhost:4572 --profile=localstack
2021-10-09 11:25:03 29 sample_2021-10-09-02-25-03.json
2021-10-09 13:43:27 29 sample_2021-10-09-04-43-27.json
2021-10-09 14:14:53 29 sample_2021-10-09-05-14-53.json
※オブジェクトが追加されている。