Serverless Framework での最近の AWS Lambda + Go ローカル開発事情について紹介します。
はじめに
Lambda 開発という面では公式の SAM CLI の登場以降影が薄くなりつつある Serverless Framework (以下 serverless)ですが、serverless 特有の便利機能や豊富なプラグインは魅力的ですし、過去に serverless でシステムを組んでしまったために今更 SAM に移行できない等の理由などからまだまだ使われるケースはあるのではないでしょうか。
とは言えやはり今から Lambda でサーバレスアプリケーションの新規開発をしようというケースでは中々 serverless は採用しにくいものがあります。
というのも Lambda 開発において最も重要視される要素の1つであるローカル実行機能という面において、serverless は SAM CLI に劣っているためです。
特に Go 言語で開発された Lambda 関数のローカル実行機能は長らく serverless ではサポートされておらず、Go で serverless 開発をしたい人たちにとっては大きな悩みのタネでした。
しかし、2020年3月現在その状況は変わりつつあるということをこの記事で紹介したいと思います。
sls invoke local --docker
sls invoke local
というと SAM CLI で言うところの sam local invoke
に相当する serverless のローカル実行コマンドですが、v1.39.0 からこのコマンドに --docker
オプションが追加されました。
--docker
オプションをつけて実行することにより、SAM CLI と同様に Docker の lambci/lambda image から立ち上げたコンテナ内で Lambda 関数が実行されるようになります。これにより Lambda でサポートされている全ての runtime のローカル実行が可能となりました。
Lambda + Go の実行例
動作させるには以下を満たす環境が必要です。
- Node.js 10 以上
- Go 1.12 以上
-
docker
コマンドがsudo
なしで使えること
node のプロジェクトを作って serverless
をインストールします。
$ npm init
$ npm install --save-dev serverless
Go のプロジェクトを作ります。serverless のテンプレート機能を使います。
$ npx sls create --template aws-go-mod
$ ls
gomod.sh hello Makefile node_modules package.json package-lock.json serverless.yml world
ローカル実行前にビルドしておきます。
$ make
invoke local
を実行します。
初回は docker pull
などが走るので時間がかかります。
$ npx sls invoke local --docker -f hello -d {}
実行に成功すると次のような出力が得られるはずです。
START RequestId: f74e55a3-cf4d-1306-4e4b-5d6fbf5b4f01 Version: $LATEST
END RequestId: f74e55a3-cf4d-1306-4e4b-5d6fbf5b4f01
REPORT RequestId: f74e55a3-cf4d-1306-4e4b-5d6fbf5b4f01 Init Duration: 294.93 ms Duration: 2.32 ms Billed Duration:
100 ms Memory Size: 1024 MB Max Memory Used: 20 MB
{"statusCode":200,"headers":{"Content-Type":"application/json","X-MyCompany-Func-Reply":"hello-handler"},"multiValueHeaders":null,"body":"{\"message\":\"Go Serverless v1.0! Your function executed successfully!\"}"}
sls offline --useDocker
serverless-offline はローカル環境で API Gateway のエミュレートを行ってくれる serverless のプラグインです。sls offline
コマンドでローカルサーバが立ち上がり、Lambda + API Gateway 構成の動作確認をローカルで行うことができます。SAM CLI で言うところの sam local start-api
コマンドに相当する機能を提供してくれるプラグインですね。
この serverless-offline、v5.xでは Go のサポートを謳っているのですが実際にはバグで動作しません。そして現在開発が進められている v6-alpha では Go サポートの文言が削除されてしまっています。
しかし、v6.0.0-alpha.54 から本家 serverless 同様 Docker のサポート(--useDocker
オプション)が追加され、これによりひっそりと Go 製 Lambda を実行できるようになっています(こちらは .NET や Java はサポートされていないのですが、近いうちにサポートされる見込みです)。
Lambda + Go の実行例
動作させるには以下を満たす環境が必要です。
- Node.js 10 以上
- Go 1.12 以上
-
docker
コマンドがsudo
なしで使えること
node のプロジェクトを作って serverless
と serverless-offline
をインストールします。
2020/03/20 v6.0.0 がリリースされましたserverless-offline
は alpha 版を入れる必要があるので @next
が必要なことに注意してください。
$ npm init
$ npm install --save-dev serverless serverless-offline
Go のプロジェクトを作ります。serverless のテンプレート機能を使います。
$ npx sls create --template aws-go-mod
$ ls
gomod.sh hello Makefile node_modules package.json package-lock.json serverless.yml world
serverless.yml
に serverless-offline の設定を書きます。
次のように plugins
と custom
を書き加えてください。custom
はなくても問題ありませんが書いておくことで実行時に --useDocker
オプションが不要になります。
service: sls-offline-test
provider:
name: aws
runtime: go1.x
package:
exclude:
- ./**
include:
- ./bin/**
# 追加
plugins:
- serverless-offline
# 追加
custom:
serverless-offline:
useDocker: true
functions:
hello:
handler: bin/hello
events:
- http:
path: hello
method: get
world:
handler: bin/world
events:
- http:
path: world
method: get
ローカル実行前にビルドしておきます。
$ make
sls offline
を実行します。
$ npx sls offline
offline: Starting Offline: dev/us-east-1.
offline: Offline [http for lambda] listening on http://localhost:3002
┌───────────────────────────────────────────┐
│ │
│ GET | http://localhost:3000/dev/hello │
│ GET | http://localhost:3000/dev/world │
│ │
└───────────────────────────────────────────┘
offline:
offline: [HTTP] server ready: http://localhost:3000 �🚀
offline:
offline: Enter "rp" to replay the last request
offline:
これでローカルサーバが起動しました。アクセス可能なパスの一覧が表示されるのでリクエストを送ってみましょう。
初回リクエスト時は docker pull
などが走るので時間がかかりますが、正しく実行できていれば次のようにレスポンスが返ってくるはずです。
$ curl localhost:3000/dev/hello
{"message":"Go Serverless v1.0! Your function executed successfully!"}
まとめ
Serverless Framework とそのプラグインである serverless-offline に Docker サポートが追加され、Go 言語製 Lambda のローカル開発環境がかなり改善されたことを紹介しました。
Lambda 開発というとやはり公式の SAM CLI に乗っかるのが一番ではあるのですが、Serverless Framework もまだまだ捨てたものじゃないということがお分かりいただけたらと思います。