ServerlessFrameworkのローカル環境を実践投入した

技術ネタ
この記事は約6分で読めます。

お久しぶりです、hisayukiです。

先月、先々月と継続していた月1回更新を落としてしまい、久々の更新です!

というわけで、お題はタイトルどおりServerlessネタでお送りします!

スポンサーリンク

TL;DR

とりあえず、ローカルだけで済ませないこと!
必ずAWS環境にデプロイして検証すること!

大まかな伝えたいことはこれだけです。
ローカル環境は豊富につくれますが、特に初めてだとAWSに実際にデプロイしてから挙動が違うことに出くわすと思います。

以前の投稿

以前の投稿でとりあえず触ってみた感の記事はアップしてます。

今回は実務で得た経験も書いてみようと思います。
ちなみに言語はTypescriptでやりました。

ServerlessFrameworkはグローバルでなくてもよい

どうしてもグローバルに入れる必要があるとしたらnodeだけだと思います。

他のモノは大概npm isntallで入れたらpackage.jsonがあるディレクトリで起動すればOK。
ServerlessFrameworkも同じで、npx sls <コマンド>で起動させることができます。

あとはコマンドをpackage.json内でScript化しておけばよいかなと思いますね。
package.jsonのScriptならnpxではなく、npm runで動かせます。
こんな感じ

"scripts": {
    "db:local": "sls dynamodb start",
    "server:local": "sls offline",
    "deploy": "sls deploy"
 },

開発環境はローカルのみでも”一応”揃う

Serverless Offline

Serverless FrameworkのPluginで使用可能です。
ローカル開発をするときには便利なので、使ってみるのはありかなと思います。

開発当初はこれで満足してました。
同時にDynamoDB-localも起動するし、RESTClientからlocalhostに対してテストも出来たので。

これが結構重要で、handler層のテストはAPI GatewayからのEventを送る必要があるのでローカルでのテストは困難です。
その部分をServerless Offlineはやってくれるのでテストがやりやすくなりました。

ただ、ここでうまく言ったから大丈夫とは思わないようにしてください

DynamoDBもローカルで起動する

ServerlessFrameworkのPluginでダウンロード可能です。
最初の頃はこれでもいいかなって思ってました。

Serverless Offline起動と同時に起動してテストデータも吸い上げてくれるので、ローカル環境でのテストをする分にはちょうどよかったです。

ただ、ここでうまく言ったから大丈夫とは思わないようにしてください

RESTClientでlocalhostへ検証可能

こちらのVSCodeプラグインを使ってます。

○○.httpというファイルを作ります。
内容は例えばこんな感じ

POST https://localhost:3000/dev/sample
Content-Type: application/json

{
  "id": "1",
  "user_name": "test_user",
}

プラグインが入っていると、POSTの上にSend Requestという文字があるのでクリックするとPOSTを送ることができて、Responseを確認することができます。

コンテナに開発環境作るもあり

今まさに、このブログを書いてて思ったのはコンテナ用意すればいいんじゃないかと。
VSCodeにはこちらのプラグインがあります。

このプラグインを使えば、Dockerfileを書いてコンテナを立ち上げて、その中をVSCodeから操作できるというもの。

開発環境に必要なモノはDockerfileに書いて、コンテナ内で立ち上がるVSCodeに予め入れておきたいプラグインも書いておけるのでありかもしれない。

今回は思いついただけで試してないので、また別の機会に書こう。
結局作って今はContainer内で開発してます
詳細はまた別の記事にします

handler一つに詰め込まなくてもいい

むしろコアロジックを呼び出すだけにするほうがよいです。

今回は詳細を書きませんが、Lambdaの性質上handlerにあれこれ詰め込むべきではないです。
できる限り、コアロジックを呼び出すだけの処理が好ましいです。
そしてコアロジック部分のinstanceはhandlerの外で初期化しておくことをオススメします。

僕の場合Application層の仕事まで入れてしまったので、受け取ったRequestをコアロジックが受け取れる形にしたり、バリデーション掛けたり、最後には返したいResponseの形にしたりもやらせてしまいましたが。。。

ただ、その部分もApplication層は別クラスで作ってそっちにやらせたほうがよかったと今は思ってます。

ハマったとこ

IAMは必須

ローカルDynamoはIAMの概念ないのでなくてもデータ投入できますが、AWSにデプロイしたらLambdaがDynamoDBを操作するロールが必要なのでserverless.ymlに設定書きます。

こんな感じ

provider
  iamRoleStatements:
    - Effect: Allow
      Action:
        - dynamodb:DescribeTable
        - dynamodb:Query
        - dynamodb:Scan
        - dynamodb:GetItem
        - dynamodb:PutItem
        - dynamodb:UpdateItem
        - dynamodb:DeleteItem
      Resource: "arn:aws:dynamodb:${self:provider.region}:*:table/*"

DynamoLocalPluginがContainer内で動作しない

途中で書きましたが、今はContainer内で開発してます。
ただ、Container化したことでDynamoLocalPluginが動作しなくなりました

正確にはstartコマンドが動かないけど、migrateコマンドは生きてます。

これは結局解決できなかったので、今はDynamoDBのContainer使ってます。
migrateコマンドは生きてるので、向き先をlocalhostからcomposeで立ててるContainerに変えました。

まとめ

久々のブログを書いたので、雑な気もしますが・・・w
まずは何か更新しなければ感強めですw

結局スタートラインはDynamoLocalPluginやServerlessOfflineでやってましたが、今は環境変わってDynamoLocalのContainerのみで、ServerlessOfflineは起動確認くらいしかしてないです。

結局最後にはAWS上にデプロイして確認しないとです。

ローカル環境はあくまで仮想環境なので、実際にデプロイしたら挙動違ったってことはザラにあると思っていただけたらと思います。

コメント

  1. よっぽどハマったんだなあw