SSTとは?
SSTとはServerless Stackの略で、SSTが正式なプロダクト名のようです。AWS上でサーバーレスアプリケーションを簡単に開発、テスト、デプロイするためのオープンソースのフレームワークです。そして、AWS CDK(Cloud Development Kit)をラップする形で構築されており、特にサーバーレスなワークロードに焦点を当てています。Serverless FramworkやSAM、それとCDKの良いとこ取りを目指したフレームワークだと考えてもらえれば良いと思います。
訂正:V2まではCDKに依存する形で作られていましたが、V3からは依存しない形になったようです。
https://sst.dev/docs/migrate-from-v2
Live Lambda Mode
Live Lambda Modeとはローカルで開発したLambdaファンクションを即座にAWS経由で動作確認が出来る機能です。API Gateway + AWS Lambdaを使ってローカルで開発していたとすると、エディタ上で保存したコードが即座にAWS上のAPI Gateway経由で動作確認が出来ます。以前は実際にAWS環境にLambdaファンクションをデプロイするか、ローカルでAPI Gatewayのエミュレーターなどを動作させて確認するしかありませんでした。これらには以下の様なデメリットが有りました
- AWS環境へのデプロイには時間がかかるため、コードを更新するたびにデプロイを行うと毎回待ちが発生し、スムーズな開発が行えない
- ローカルのエミュレーターはIAM周りやAWS独自の環境などが再現できない。いざテストが完了してAWSにデプロイしても動かないということがよくあった
Live Lambda Modeを使うことで上記のデメリットは解決されて、快適なLambdaファンクションの開発経験を得ることが出来ます。具体的な内容については以降で説明します。
SSTのインストールからLive Lambda Modeのセットアップまで
まずはSSTをインストールしていきます。専用のプロジェクト用のディレクトリを作成してからnpx経由でsstをインストールします。npx sst@latest initをすると、対話型のダイアログが表示されますので、それに沿ってセットアップします。
% mkdir my-ts-app && cd my-ts-app
% npm init -y
% npx sst@latest init
███████╗███████╗████████╗
██╔════╝██╔════╝╚══██╔══╝
███████╗███████╗ ██║
╚════██║╚════██║ ██║
███████║███████║ ██║
╚══════╝╚══════╝ ╚═╝
> JS project detected. This will...
- use the JS template
- create an sst.config.ts
✓ Template: js
✓ Using: aws
✓ Done 🎉
すると以下のようなシンプルなディレクトリ構成が出来上がります。
├── package.json
├── sst.config.ts
└── tsconfig.json
sst.config.ts
を開くと以下のようなコードが記述されています。async run() {}
の内部に使用するAWSリソースの設定を記述していくことになります。
/// <reference path="./.sst/platform/config.d.ts" />
export default $config({
app(input) {
return {
name: "my-ts2-app",
removal: input?.stage === "production" ? "retain" : "remove",
home: "aws",
};
},
async run() {},
});
まずは、 Amazon API Gateway + AWS LambdaでHello Worldを返すだけのAPIを作っていきましょう。sst.config.ts
のrun内にAmazon API Gatewayのコードを以下のように記述します。HTTPの/にGETリクエストが有れば、index.tsのhelloメソッドにルーティングされます。
async run() {
const api = new sst.aws.ApiGatewayV2("MyApi");
api.route("GET /", {
handler: "index.hello",
});
},
ここで、Live Lambda Modeを立ち上げてみましょう。プロジェクトのルートディレクトリで以下のコマンドを実行します。
% npx sst dev
以下のような専用のコンソールが立ち上がってAmazon API Gatewayのエンドポイントが発行されたことがわかります。
そして、index.tsを作成して、Hello Worldをレスポンスするメソッドを作成します。
export async function hello() {
return {
statusCode: 200,
body: "Hello World",
};
}
エディタで保存後発行されたエンドポイントにアクセスするとすぐにHello Worldが返ってきました。
% curl https://04kyvqsb3d.execute-api.us-east-1.amazonaws.com/
Hello World
レスポンスの内容をHello WordからHelloに変更すると、デプロイで待たされることなくすぐにAmazon API Gatewayのレスポンスに反映されています。これがLive Lambda Modeの凄さです。
% curl https://04kyvqsb3d.execute-api.us-east-1.amazonaws.com/
Hello
もし、構文エラーなどが発生していた際もLive Lambda Mode起動時に立ち上がったコンソールからリアルタイムにログを確認することが可能です。
Function Logs
Waiting for invocations...
| Build MyApiRouteDnvusbHandler
| Invoke MyApiRouteDnvusbHandler
| Done took +461ms
| Invoke MyApiRouteDnvusbHandler
| Done took +451ms
| Build MyApiRouteDnvusbHandler
| Invoke MyApiRouteDnvusbHandler
| Done took +458ms
| Build Error MyApiRouteDnvusbHandler
| ↳ Unterminated string literal index.ts:4:17
Amazon S3を使ったサーバレスアプリケーションをSSTで開発する
Hello Worldだけでは少し物足りないので、S3バケットにAmazon API Gateway経由でファイルのアップロードを行うアプリケーションを作ってみましょう。具体的にはAmazon API Gateway経由でAmazon S3の署名付きURLを発行してそこからファイルのアップロードを行うといったものです。
まずはS3のクライアントをnpmでインストールします。
% npm install @aws-sdk/client-s3 @aws-sdk/s3-request-presigner
そして、sst.config.ts
にてAmazon API GatewayとAmazon S3の指定を行います。
async run() {
const bucket = new sst.aws.Bucket("MyBucket", {
access: "public"
});
const api = new sst.aws.ApiGatewayV2("MyApi");
api.route("GET /", {
link: [bucket],
handler: "index.upload",
});
},
index.ts内では署名付きURLを発行してそれをAPIのレスポンスとして返す処理を作ります。S3バケットのキーは後で動作確認して分かりやすいようにuploaded-fileと命名しておきます。これのファイルが作られていれば処理成功です。
import { Resource } from "sst";
import { getSignedUrl } from "@aws-sdk/s3-request-presigner";
import {
S3Client,
PutObjectCommand,
} from "@aws-sdk/client-s3";
const s3 = new S3Client({});
export async function upload() {
const command = new PutObjectCommand({
Key: 'uploaded-file',
Bucket: Resource.MyBucket.name,
});
return {
statusCode: 200,
body: await getSignedUrl(s3, command),
};
}
動作確認でpackage.jsonを以下のコマンドでアップロードしてみましょう。
% curl --upload-file package.json "$(curl https://xk28df6no8.execute-api.us-east-1.amazonaws.com)"
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 1462 100 1462 0 0 563 0 0:00:02 0:00:02 --:--:-- 565
以下のようにS3バケット上にuploaded-fileというオブジェクトが生成されていました。処理成功です。そしてここまでAWS Lambdaのデプロイは行っていません。すべてローカルのコードをAmazon API Gateway経由で動かしています。
まとめ
今回はSSTを使ってLive Lambda Modeの紹介を行いました。直接デプロイする手間がなくなったことでかなり快適にLambdaファンクションの開発を行うことが出きました。まだまだ、日本ではSSTはメジャーとは言えませんが、是非機会があれば試してみてください。