Help us understand the problem. What is going on with this article?

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

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

bandainamcostudios
バンダイナムコスタジオは、家庭用ゲームソフト、モバイルコンテンツ、の企画・開発・運営、ゲームに関する技術研究・開発を行っている会社です。
https://www.bandainamcostudios.com
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした