AWSとSSTで実現する次世代サーバーレス開発
AWSでサーバーレスなアプリを作りたいとき,どのようなIaCフレームワークを使っていますか?
- AWS SAM
- AWS CDK
- Serverless Framework
- AWS Amplify
このあたりが代表的だと思います.
最近私が激推ししているIaCフレームワークは SST です.本記事ではSST使ったことがない方に,その魅力を伝えることを目指します.ハンズオンのような形式になっているので,ぜひ実際に手を動かしてみてください.
SSTの特徴
SSTの推しポイントはたくさんありますが,勝手に厳選すると以下の3点になります:
- Lambdaをローカルで開発しながらAWSリソースにもアクセスできる(Live Lambda)
- フロントエンド,バックエンド,インフラストラクチャのすべてをSSTで開発できる
- AWS CDK Constructs をすべて利用できる
特に1番目が重要です.Live Lambdaという機能のおかげで,ローカル環境にあるLambdaのコードがまるでAWS上で実行されているような感覚で開発・デバッグできます.さらに開発環境(ローカル)と本番環境(AWS)での挙動の違いが少なくなるというメリットもあります.
SST Getting Started
開発環境をデプロイする
早速SSTでサーバーレスアプリを作ってみます.
まずはSSTプロジェクトのテンプレートをダウンロードし,必要なパッケージをインストールします.ここではプロジェクト名をmy-sst-app
としましたが,もちろん好きな名前で構いません.
npx create-sst@latest my-sst-app
cd my-sst-app
npm install
VSCode等のエディタでディレクトリを開きます.ディレクトリの直下にあるsst.config.ts
というファイルを開きます.デフォルトではリージョンがus-east-1
に設定されているので,好きなところに書き換えましょう.私はap-northeast-1
にしました.
import { SSTConfig } from "sst";
import { API } from "./stacks/MyStack";
export default {
config(_input) {
return {
name: "my-sst-app",
- region: "us-east-1",
+ region: "ap-northeast-1",
};
},
stacks(app) {
app.stack(API);
}
} satisfies SSTConfig;
開発環境を起動します.
npm run dev
ステージ名をどうしたいか聞かれますが,特に気にせずEnterを押してデフォルトのままで行きます.デフォルトではユーザー名(私の場合はbe4rr
)が開発環境のステージ名になります.
Please enter a name you’d like to use for your personal stage. Or hit enter to use be4rr:
開発用の環境がAWSにデプロイされます.初回のデプロイには数分かかります.
SST v2.38.7 ready!
➜ App: my-sst-app
Stage: be4rr
Console: https://console.sst.dev/local/my-sst-app/be4rr
(略)
デプロイが完了すると次のように表示されます.
✔ Deployed:
API
ApiEndpoint: https://xxxxxxxx.execute-api.ap-northeast-1.amazonaws.com
API Gatewayが作成されたことがわかります.npm run dev
を実行したまま表示されたURLをブラウザなどで開くと,現在の時刻が表示されると思います.
Hello world. The time is 2023-12-23T11:11:39.851Z
何が起こった?
my-sst-app
ディレクトリに作られたファイルを眺めてみます.
.
├── package-lock.json
├── package.json
├── packages
│ ├── core
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── event.ts
│ │ │ └── todo.ts
│ │ ├── sst-env.d.ts
│ │ └── tsconfig.json
│ └── functions
│ ├── package.json
│ ├── src
│ │ ├── events
│ │ ├── lambda.ts
│ │ └── todo.ts
│ ├── sst-env.d.ts
│ └── tsconfig.json
├── pnpm-workspace.yaml
├── sst.config.ts
├── stacks
│ └── MyStack.ts
└── tsconfig.json
stacks/MyStack.ts
にAWSインフラストラクチャが定義されています.
import { StackContext, Api, EventBus } from "sst/constructs";
export function API({ stack }: StackContext) {
...(略)...
const api = new Api(stack, "api", {
defaults: {
function: {
bind: [bus],
},
},
routes: {
"GET /": "packages/functions/src/lambda.handler",
"GET /todo": "packages/functions/src/todo.list",
"POST /todo": "packages/functions/src/todo.create",
},
});
...(略)...
stack.addOutputs({
ApiEndpoint: api.url,
});
}
SSTではAWS CDKと同じように「スタック」という単位でインフラストラクチャを定義します.上のコードではAPI
というスタックが定義されています.その中でEventBus
とApi
という2つのコンストラクト(AWSリソース)が定義されています.
ここではAPI Gatewayを定義しているApi
に注目します.このApi
が先ほどのAPIhttps://xxxxxxxx.execute-api.ap-northeast-1.amazonaws.com
を定義しています."GET /": "packages/functions/src/lambda.handler"
では,APIへのGETリクエストをLambda関数に結びつけています.そのLambda関数の実際の処理はpackages/functions/src/lambda.ts
内のhandler
関数に記述されています.
ファイルの中身を見ると次のようになっています.APIのURLを開いたときに現在時刻が表示されましたが,その処理がここに定義されていることがわかります.
import { ApiHandler } from "sst/node/api";
export const handler = ApiHandler(async (_evt) => {
return {
statusCode: 200,
body: `Hello world. The time is ${new Date().toISOString()}`,
};
});
先ほどのnpm run dev
は,これらのAPI GatewayやLambda関数をAWSにデプロイしていました.
Live Lambda の威力
Lambda関数を編集することで,Live Lambdaの威力を体験してみましょう.
次のようにLambdaを変更します.
export const handler = ApiHandler(async (_evt) => {
return {
statusCode: 200,
- body: `Hello world. The time is ${new Date().toISOString()}`,
+ body: `こんにちは.今の時間は ${new Date().toTimeString()} です.`,
};
});
ファイルを保存してAPIエンドポイントhttps://xxxxxxxx.execute-api.ap-northeast-1.amazonaws.com
を再び開くかブラウザをリロードします.するとLambda関数への変更がすでに反映されていることがわかります.
こんにちは.今の時間は 20:12:04 GMT+0900 (日本標準時) です.
AWS上のAPI GatewayからLambda関数を起動しているのにも関わらず,ローカルでの変更がすぐに反映されるのは驚きです.これがSSTのLive Lambdaです.
Live Lambdaの特徴として,Lambda関数自体はローカル環境に存在しますが,他のリソースはAWSクラウドにデプロイされています.この構成によりAWSクラウド上のリソースがローカルのLambda関数をトリガーすることや,逆にローカルのLambda関数からAWSクラウド上のリソースを操作することが可能です.この機能によってまるでクラウド上のLambda関数を直接編集しているかのような体験が得られます.
本番環境にデプロイ
ここまでは開発環境で作業をしていました.ここでは開発環境で作成したものを本番環境にデプロイしてみます.
本番環境にデプロイする,といっても実際に必要な操作は以下のコマンド1つだけです.
npx sst deploy --stage prod
上のコマンドを実行することで,プロジェクトで定義されたリソースが,開発環境とは完全に独立してデプロイされます.つまり開発環境をデプロイした時とは異なるAPI GatewayやLambda関数が作成されます.
実際,CloudFormationを見てみるとprod-my-sst-app-API
と[ユーザー名]-my-sst-app-API
の2つのスタックができています.私の場合はprod-my-sst-app-API
とbe4rr-my-sst-app-API
ができています.
後片付け
ここまでにデプロイした開発環境と本番環境を削除します.
開発環境の削除:
npx sst remove
本番環境の削除:
npx sst remove --stage prod
ちなみにCloudFormationのコンソールから削除することもできます.
参考
最後にSSTを使う際に参考になるリソースを紹介します.
-
SST Docs
公式ドキュメントがとても丁寧でわかりやすいです.SSTに興味を持ったらまずはGetting StartedやExamples,Guideから始めるのがおすすめです. - GitHub Issue
-
Discord
GPTにSSTについて質問できるチャンネルがあります. -
Web Dev Cody - Youtube
SSTに限らず,サーバーレスなアプリケーション開発全般の動画を上げているTech系チャンネルです.個人的に好きなので紹介しました.
Discussion