はじめに
AWS を勉強のために触りたいが、課金が怖くてなかなか試せない。
そういった方向けに、ローカル開発環境でAWSサービスを実行できるのが、LocalStack です。
今回は、LocalStackを使って簡単なAPIをデプロイしてみようと思います。
前提条件
docker(docker compose コマンドを実行できること)を使用できる状態にしておいてください。
下準備
AWS CLIのインストール
$ sudo apt install awscli
プロファイルの設定
$ aws configure --profile localstack
AWS Access Key ID [None]: dummy
AWS Secret Access Key [None]: dummy
Default region name [None]: us-east-1
Default output format [None]: json
LocalStackのclone
$ git clone https://github.com/localstack/localstack.git
$ cd localstack
※私の環境では、エラーになったため、docker-compose.yml に以下を記載した。
environment:
- LAMBDA_DOCKER_NETWORK=host
LocalStackの起動
docker-compose up -d
Lambdaのデプロイ
1. サンプルファイルの準備
Lambda.py
import json
def lambda_handler(event, context):
return {
'statusCode': '200',
'body': json.dumps('Hello LocalStack API'),
'headers': {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*'
},
}
2. zipにする
$ zip lambda.zip lambda.py
3. Lambda作成
$ aws lambda create-function \
--function-name test-api-lambda \
--runtime python3.8 \
--handler lambda.lambda_handler \
--memory-size 128 \
--zip-file fileb://lambda.zip \
--role arn:aws:iam::000000000000:role/lambda-role \
--profile localstack \
--region us-east-1 \
--endpoint-url=http://localhost:4566
以下については、ダミーで問題ありません。
--role arn:aws:iam::000000000000:role/lambda-role
ただし、
--role test
のようにすると、エラーとなるため、以下の形式にする必要があります。
--role arn:aws:iam::xxx:role/xxx
4. Lambdaの確認
$ aws --endpoint-url=http://localhost:4566 lambda list-functions --profile localstack
この時点で Lambdaが作成できているかどうか確認します。
API Gatewayデプロイ
1. APIの作成
$ aws apigateway create-rest-api --name 'Sample API' --endpoint-url=http://localhost:4566
# 結果
{
"id": "xxx",
"name": "Sample API",
"createdDate": "2023-04-25T10:17:35+09:00",
"apiKeySource": "HEADER",
"endpointConfiguration": {
"types": [
"EDGE"
]
},
"disableExecuteApiEndpoint": false
}
2. ルートリソース ID取得
$ aws apigateway get-resources --rest-api-id {api-id} --endpoint-url=http://localhost:4566
# 結果
{
"items": [
{
"id": "xxx",
"path": "/"
}
]
}
{api-id}
は 1. APIの作成 で取得できるidを使用する
3. 子リソースを追加
$ aws apigateway create-resource --rest-api-id {api-id} \
--parent-id {parent-id} \
--path-part sample \
--endpoint-url=http://localhost:4566
# 結果
{
"id": "xxx",
"parentId": "xxx",
"pathPart": "sample",
"path": "/sample"
}
{parent-id}
は 2. ID取得 で取得できるidを使用します。
4. GETメソッドを参照できるように設定
$ aws apigateway put-method \
--rest-api-id {api-id} \
--resource-id {resource-id} \
--http-method GET \
--authorization-type "NONE" \
--endpoint-url=http://localhost:4566
# 結果
{
"httpMethod": "GET",
"authorizationType": "NONE",
"apiKeyRequired": false
}
{resource-id}
は 3. 子リソースを追加 で取得できるidを使用します。
5. API Gateway と Lambda の設定
$ aws apigateway put-integration \
--rest-api-id {api-id} \
--resource-id {resource-id} \
--http-method GET \
--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:test-api-lambda/invocations \
--passthrough-behavior WHEN_NO_MATCH \
--endpoint-url=http://localhost:4566
# 結果
{
"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:test-api-lambda/invocations",
"requestParameters": {},
"passthroughBehavior": "WHEN_NO_MATCH",
"cacheNamespace": "ui91214dss",
"cacheKeyParameters": []
}
6. API デプロイ
$ aws apigateway create-deployment \
--rest-api-id {api-id} \
--stage-name dev \
--endpoint-url=http://localhost:4566
# 結果
{
"id": "xxx",
"createdDate": "2023-04-25T10:32:39+09:00"
}
実行確認
$ curl http://localhost:4566/restapis/{api-id}/dev/_user_request_/sample
うまくいかない時
APIが作成されているか確認してみてください。
$ aws apigateway get-rest-apis --endpoint-url=http://localhost:4566
$ aws apigateway get-resources --rest-api-id {api-id} --endpoint-url=http://localhost:4566
LocalStackを使用してみて
メリット
- 動作確認のたびにAWSにデプロイする手間が省ける
- 動作確認の都度課金を心配しなくて良い
- 何かをまず試してみる時に便利
デメリット
- コンソールで設定ができない(CLIに慣れていないと効率は落ちそう)
- Community 版(無料)だと使えないサービスもある
参照URL