LoginSignup
18
14

More than 3 years have passed since last update.

Serverless Framework での AWS Lambda + Go ローカル開発事情

Last updated at Posted at 2020-03-11

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 のプロジェクトを作って serverlessserverless-offline をインストールします。
serverless-offline は alpha 版を入れる必要があるので @next が必要なことに注意してください。 2020/03/20 v6.0.0 がリリースされました

$ 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 の設定を書きます。
次のように pluginscustom を書き加えてください。custom はなくても問題ありませんが書いておくことで実行時に --useDocker オプションが不要になります。

serverless.yml
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 もまだまだ捨てたものじゃないということがお分かりいただけたらと思います。

18
14
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
18
14