はじめに
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 版(無料)だと使えないサービスもある