APIGateway + Lambda + Go(Echo)で開発するためのローカル環境をServerlessFrameworkで再現する
はじめに
以前の記事で APIGW + Lambdaで GoのフレームワークであるEchoを動かす検証を実施しました。 実際にデプロイすることができたので今回は開発を行うためにローカル環境をServerlessFrameworkで構築しました。
構成
Client --> APIGW --> Lambda(Goコンテナ)
をローカル環境に構築します。ServerlessFrameworkで実行すれば、この構成を簡単に用意できます。
ローカル環境
serverless-offline
をインストールする
npm install --save-dev serverless-offline
- プロジェクトを作成する
sls create -t <テンプレート> -n <プロジェクト名>
sls create -t aws-go -n serverless-echo-lambda
*) テンプレートについては以下が対応していました。色々ありますね。
Supported templates are: "aws-clojure-gradle", "aws-clojurescript-gradle", "aws-nodejs", "aws-nodejs-docker", "aws-nodejs-typescript", "aws-alexa-typescript", "aws-nodejs-ecma-script", "aws-python", "aws-python3", "aws-python-docker", "aws-groovy-gradle", "aws-java-maven", "aws-java-gradle", "aws-kotlin-jvm-maven", "aws-kotlin-jvm-gradle", "aws-kotlin-jvm-gradle-kts", "aws-kotlin-nodejs-gradle", "aws-scala-sbt", "aws-csharp", "aws-fsharp", "aws-go", "aws-go-dep", "aws-go-mod", "aws-ruby", "aws-provided", "tencent-go", "tencent-nodejs", "tencent-python", "tencent-php", "azure-csharp", "azure-nodejs", "azure-nodejs-typescript", "azure-python", "cloudflare-workers", "cloudflare-workers-enterprise", "cloudflare-workers-rust", "fn-nodejs", "fn-go", "google-nodejs", "google-nodejs-typescript", "google-python", "google-go", "kubeless-python", "kubeless-nodejs", "knative-docker", "openwhisk-java-maven", "openwhisk-nodejs", "openwhisk-php", "openwhisk-python", "openwhisk-ruby", "openwhisk-swift", "spotinst-nodejs", "spotinst-python", "spotinst-ruby", "spotinst-java8", "twilio-nodejs", "aliyun-nodejs", "plugin", "hello-world".
プロジェクト作成コマンドを実行すると自動で以下が作成されました。
❯ tree . . ├── Makefile ├── hello │ └── main.go ├── serverless.yml └── world └── main.go
今回は、前回の記事で作成したコードを利用するので、サンプルで自動作成された hello/
と world
のディレクトリを削除しました。
今回用意したディレクトリ構成は以下になります。Echoで ヘルスチェックのAPIを実装しており、ソースコードはこちらのGitHubにあります。
- ディレクトリ構成
❯ tree . . ├── Makefile ├── README.md ├── api │ └── healthcheck │ └── healthcheck.go ├── bin │ └── main ├── conf │ └── config.go ├── go.mod ├── go.sum ├── handler │ └── auth │ └── auth.go ├── main.go └── serverless.yml
- serverless.ymlも自動で作成されますが、以下のとおりに変更しました。
- "追記" の部分を追加しています。自動作成されたコメント部分は削除しています。
plugins
でserverless-offline
を指定しますcustom
でuseDocker
で trueを指定しますtimeout
はデフォルト値では timeoutになってしまったので定義しました- 主な原因は、Lambda(go) のコンテナを起動するのに時間がかかるためでした
- 利用されるコンテナイメージ: https://hub.docker.com/r/lambci/lambda
service: serverless-echo-lambda frameworkVersion: '3' # 追記 custom: serverless-offline: useDocker: true provider: name: aws runtime: go1.x stage: v1 #追記 timeout: 30 #追記 package: patterns: - '!./**' - ./bin/** functions: main: handler: bin/main events: - http: # RESTAPI path: /api/{proxy+} method: get # 追記 plugins: - serverless-offline
デプロイと動作確認
.PHONY: build clean deploy deploy-local build: env GOARCH=amd64 GOOS=linux go build -ldflags="-s -w" -o bin/main ./main.go clean: rm -rf ./bin deploy-local: build sls offline deploy: clean build sls deploy --verbose
- ローカル環境を起動します。
sls offline
- goのコードをコンパイルしてデプロイする場合は
make deploy-local
でもOK
❯ sls offline Starting Offline at stage v1 (us-east-1) Offline [http for lambda] listening on http://localhost:3002 Function names exposed for local invocation by aws-sdk: * main: serverless-echo-lambda-v1-main ┌────────────────────────────────────────────────────────────────────────┐ │ │ │ GET | http://localhost:3000/v1/api/{proxy*} │ │ POST | http://localhost:3000/2015-03-31/functions/main/invocations │ │ │ └────────────────────────────────────────────────────────────────────────┘ Server ready: http://localhost:3000 🚀
- ヘルスチェックAPIをコールする
❯ curl http://localhost:3000/v1/api/healthcheck {"status":200,"message":"Success to connect echo"}
リクエストを投げると Dockerイメージを起動してからリクエストを受け付けてくれました。リクエスト終了後に確認したら割とすぐにコンテナは停止していました。
❯ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES ❯ curl http://localhost:3000/v1/api/healthcheck {"status":200,"message":"Success to connect echo"}% ❯ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 8179a26361e2 lambci/lambda:go1.x "/var/runtime/aws-la…" 4 seconds ago Up 3 seconds 0.0.0.0:53718->9001/tcp great_grothendieck
- APIGWの機能はServerlessFrameworkで再現してくれています。
- serverlessFrameworkが 3000番Listenして apigw --> lambdaコンテナに接続されています
❯ sudo lsof -i -P | grep "LISTEN" | grep 3000 node 44358 hidetoshi 32u IPv6 0x8764e5xxxxxxxxxx 0t0 TCP localhost:3000 (LISTEN)
さいごに
今回は、ServerlessFrameworkで Client --> APIGW --> Lambda(Echo)
の環境をローカルに再現しました。
ローカルでAWS環境を再現して開発できるのはとても便利ですね。