- 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取得
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
※オブジェクトが追加されている。