6
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Ateam Lifestyle Inc. Advent Calendar 2021の25日目は、
@masatomasato1224が担当します。

AWS CDKを利用してサーバーレスアプリケーションを構築できるフレームワークであるServerless Stackを触ったところ、Live Lambda Developmentがとっても便利だったので紹介したいと思います。

モチベーション

最近、業務でサーバーレスアプリケーションを構築する機会がありました。
その際は、ServerlessFrameworkを利用したのですが、インフラ関連の業務経験が少ないこともありCloudFormationのテンプレートを利用したインフラ定義に苦戦しました。
そこで、AWS CDKをラップして簡単にサーバーレスアプリケーションを構築できるフレームワークであるServerless Stackに興味を持ちチュートリアルを触ってみました。

ServerlessStackについて

特徴

  • インフラ定義がラクラク
    • AWS CDKをラップした独自のコンストラクタが用意されているのでコードの記載量が少ない
    • 単体のAWSリソースはもちろん、Reactの静的サイトをホスティングするリソースセットのコンストラクタが用意されていたりする
  • 開発とデバッグがラクラク
    • Webpack、Babel、TypeScript、テストフレームワーク、リンターがデフォルトで入っているのですぐにコードを書き始めることができる
    • Live Lambda DevelopmentによりLambda関数をローカルで実行できる
      • Visual Studio Codeでのブレークポイントを設定してデバックができる
      • Lambdaの変更のみであれば、デプロイなしで結果を確認することができる

LiveLambdaDevelopmentについて

  • Lambda関数をローカルでデバッグ、テストできる
  • sst startコマンドで実行

ざっくりとした仕組み

sst startコマンドを実行すると以下のことが行われる

  1. WebSocketAPIを持つデバッグスタックをデプロイする
  2. アプリケーションスタックをデプロイする
  3. アプリケーションスタック内のLambdaをスタブに置き換える
  4. スタブがWebSocket APIを呼び出しだすことでローカル版のLambdaを実行する


※ イメージは公式サイトより引用

LiveLambdaDevelopmentを試してみる

Node.jsのインストール、AWSアカウント及びプロファイルの設定を事前に行って下さい

新規プロジェクトの作成

新規作成コマンド
npx create-serverless-stack@latest\
    2021-advent-calendar\
    --language typescript --use-yarn
実行後のディレクトリ構造
├── README.md
├── node_modules
├── package.json
├── src
├── sst.json
├── stacks
├── test
├── tsconfig.json
└── yarn.lock

VSCodeのデバッグ設定

デバック実行時に、AWSプロファイルを指定してsst startコマンドを実行できるようにする

設定ファイルの生成
mkdir .vscode && touch .vscode/launch.json

公式サイトで公開されている設定をコピペ

.vscode/launch.json
{
   "version": "0.2.0",
   "configurations": [
     {
       "name": "Debug SST Start",
       "type": "node",
       "request": "launch",
       "runtimeExecutable": "${workspaceRoot}/node_modules/.bin/sst",
       "runtimeArgs": ["start", "--increase-timeout"],
       "console": "integratedTerminal",
       "skipFiles": ["<node_internals>/**"]
     },
     {
       "name": "Debug SST Tests",
       "type": "node",
       "request": "launch",
       "runtimeExecutable": "${workspaceRoot}/node_modules/.bin/sst",
       "args": ["test", "--runInBand", "--no-cache", "--watchAll=false"],
       "cwd": "${workspaceRoot}",
       "protocol": "inspector",
       "console": "integratedTerminal",
       "internalConsoleOptions": "neverOpen",
       "env": { "CI": "true" },
       "disableOptimisticBPs": true
     }
   ]
}

環境変数にAWSのプロファイルを追加

.vscode/launch.json
{
   "version": "0.2.0",
   "configurations": [
     {
       "name": "Debug SST Start",
       "type": "node",
       "request": "launch",
       "runtimeExecutable": "${workspaceRoot}/node_modules/.bin/sst",
       "runtimeArgs": ["start", "--increase-timeout"],
       "console": "integratedTerminal",
       "skipFiles": ["<node_internals>/**"],
+      "env": { "AWS_PROFILE": "private-aws" }
     },
     {
       "name": "Debug SST Tests",
       "type": "node",
       "request": "launch",
       "runtimeExecutable": "${workspaceRoot}/node_modules/.bin/sst",
       "args": ["test", "--runInBand", "--no-cache", "--watchAll=false"],
       "cwd": "${workspaceRoot}",
       "protocol": "inspector",
       "console": "integratedTerminal",
       "internalConsoleOptions": "neverOpen",
-      "env": { "CI": "true" },
+      "env": { "CI": "true", "AWS_PROFILE": "private-aws" }
       "disableOptimisticBPs": true
     }
   ]
}

実行

Debug SST Startが選択されているこを確認して、F5キーで実行

初回実行のみスタックのプレフィックスを尋ねられるので入力
※ 今回はmasa10Devを指定

ログの抜粋
Look like you’re running sst for the first time in this directory. 
Please enter a stage name you’d like to use locally. 
Or hit enter to use the one based on your AWS credentials 
(xxxxx):masa10Dev

プレフィックスの命名は「Pascal」もしくは「Camel」で指定してください
「-」や「_」を使うと怒られます

プレフィックスの入力が終わるとデプロイが始まるので、Debug session started. Listening for requests...が表示されるまで待つ

ログの抜粋
Preparing your SST app
=======================
 Deploying debug stack
=======================
・・・

 ✅  masa10Dev-2021-advent-calendar-debug-stack

Stack masa10Dev-2021-advent-calendar-debug-stack
  Status: deployed
  Outputs:
    BucketArn: arn:aws:s3:::masa10dev-2021-advent-calendar-deb-bucket83908e77-xxxxx
    BucketName: masa10dev-2021-advent-calendar-deb-bucket83908e77-xxxxx
    Endpoint: wss://xxxxx.execute-api.us-east-1.amazonaws.com/masa10Dev
    
・・・

===============
 Deploying app
===============

 ✅  masa10Dev-2021-advent-calendar-my-stack

Stack masa10Dev-2021-advent-calendar-my-stack
  Status: deployed
  Outputs:
    ApiEndpoint: https://xxxxx.execute-api.us-east-1.amazonaws.com
...

==========================
 Starting Live Lambda Dev
==========================

# これが出るまで待つ
Debug session started. Listening for requests...

動作確認

アプリケーションスタックのApiEndpointに対して、リクエストを実行

curl https://xxxxx.execute-api.us-east-1.amazonaws.com
実行結果
> af6dab28-94f2-4d51-9449-8c672d5dd927 REQUEST masa10Dev-2021-advent-calenda-ApiLambdaGETB1714EF3-1oAEhE3VA39G [src/lambda.handler] invoked by API GET /
Debugger attached.
Debugger attached.
af6dab28-94f2-4d51-9449-8c672d5dd927 RESPONSE 
{"statusCode":200,"headers":{"Content-Type":"text/plain"},"body":"Hello, World! Your request was received at 22/Dec/2021:21:25:51 +0000."}

Lambdaの編集をして動作確認

src/lambda.ts
import { APIGatewayProxyHandlerV2 } from "aws-lambda";

export const handler: APIGatewayProxyHandlerV2 = async (event) => {

+ console.log('ローカルのLambdaが実行されよー!!!')

  return {
    statusCode: 200,
    headers: { "Content-Type": "text/plain" },
-   body: `Hello, World! Your request was received at ${event.requestContext.time}.`,
+   body: `Hello, Masa10! Your request was received at ${event.requestContext.time}.`,
  };
};

もう一回リクエストを飛ばす

curl https://xxxxx.execute-api.us-east-1.amazonaws.com

再デプロイは行われていないがログが追加されて、レスポンスのbodyが変わっていることが確認できる

実行結果
bcac3775-0fce-4632-b145-3bd858c0af2c REQUEST masa10Dev-2021-advent-calenda-ApiLambdaGETB1714EF3-1oAEhE3VA39G [src/lambda.handler] invoked by API GET /
Debugger attached.
Debugger attached.
ローカルのLambdaが実行されよー!!!
bcac3775-0fce-4632-b145-3bd858c0af2c RESPONSE {"statusCode":200,"headers":{"Content-Type":"text/plain"},"body":"Hello, Masa10! Your request was received at 22/Dec/2021:21:34:31 +0000."}

ブレークポイント

src/lambda.tsの5行目にブレークポイントを設置

もう一回リクエストを飛ばす

curl https://xxxxx.execute-api.us-east-1.amazonaws.com

ブレークポイントで処理が止まり、ステップ実行や変数の中身などを確認することができる

最後に

AWS限定にはなりますが、簡単かつ楽しくサーバレス開発ができるフレームワークではないかなと思います!

編集した結果をデプロイすることなく実行してフィードバックを得られ、ブレークポイントを活用することでエラー調査やデバッグを効率的に行えるのは嬉しいポイントではないでしょうか?

今回は紹介しきれませんでしたが、インフラの定義に関してもかなり触りやすかったです。
特に、リソースの参照やパーミッションの設定がCloudFormationよりも格段に分かりやすいと感じました。
また、スタックの分割も簡単にできるので、リソース種別などのグループで分けておくとでデプロイ時間が短縮されるので待ち時間を減らすことができます。

2021/12/22時点の最新バージョンが0.54.4なので、1.00.0がリリースされたらプロダクション環境でも使ってみたいと思います。

最後まで読んでくださってありがとうございました!!
皆様良い年末をお過ごしください!!

余談

チュートリアルがとっても丁寧で、AWSの各種リソースやReactについても端折らずに説明してくれているのでおすすめです。
※ インフラ初学者の自分にはとっても有り難かったです。

6
1
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
6
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?