📦

サーバレスフレームワークとしてのSST v3を調査した

2024/12/24に公開

はじめに

この記事は any Product Team Advent Calendar2 24日目の記事です。
https://qiita.com/advent-calendar/2024/anyinc

こんにちは。anyの荒川です。Qastにおけるサーバレスフレームワークの検討の段階における選択肢のひとつであったSSTについて紹介したいと思います。

背景

もともと弊社プロダクトであるQastにおいてはSST v2(クラウドはAWS)をすでに利用していました。

SST v2は開発者体験としては良い部分ももちろんあるのですが、

  • 独自のフレームワークということで学習コストが高い
  • v2 → v3 での破壊的変更コストへの追従
  • Node.js のバージョン管理が必要

特に公式でも言及されているように、

The v3 migration is not simple and there are likely a few of you that won’t be able to make the change. So we are planning on keeping v2 updated.

We’ll accept PRs and release updates. But we won’t add new constructs or introduce breaking changes.

v3への移行は簡単ではなく、移行が難しい方もいらっしゃるかと思います。そのため、v2を引き続き更新する予定です。

私たちはPRを受け付け、更新をリリースします。ただし、新しい構造を追加したり、互換性を壊す変更を導入したりすることはありません。

v2 → v3 への破壊的変更の大きさへの追従がそれなりに大きいため、v3に移行するにしても、抜本的なフレームワークの変更も検討しています。現時点でどちらで進めるかをジャッジしている最中なのですが、今回の記事は移行先の選択肢の一つであるSST v3 の調査備忘録的な記事となります。

SST について

https://sst.dev/

SSTはTypeScriptベースでサーバレスアプリケーション構築できるフレームワークです。API Gateway と Lambda で Hello World のレスポンスを返すアプリを下記コードで作成できます。

export const api = new sst.aws.ApiGatewayV2("Api");

api.route("GET /", {
  link: [bucket],
  handler: "packages/functions/src/api.handler",
});

export const handler = async (event, context) => {
  return {
    statusCode: 200,
    body: "Hello World!"
  };
};

https://guide.sst.dev/chapters/create-a-hello-world-api.html

npx sst dev コマンドを利用してローカル環境でテストしつつ、npx sst deploy で対象のクラウドにデプロイができてしまいます。イメージとしては非常にAWS CDKに近いです。

また開発者体験としてのWebコンソールが用意されているなどサーバレスアプリケーションを構築するために用意されたフレームワークならではの強みもあります。

コードネームionからsstへのマージ

ここからv2以前のSST自体の説明はおいておき、v3について紹介しようと思います。もともとv3は非常に変更が大きく、Ionというコードネームで別リポジトリに切り出された作業されていましたが、

https://github.com/sst/ion

ionリポジトリは2024/10/22にアーカイブされ、SSTリポジトリにマージされました 🎉

https://github.com/sst/sst

開発者側のマイグレーションのロードマップでもStep2まで完了し、マイグレーションが完了した状態といえるでしょう。

https://sst.dev/blog/moving-away-from-cdk#step-2-ion--sst-v3

AWS依存からの脱却

SST v3はバックエンドがAWS CDKとCloudFormationで再構築されていたところから、Pulumi と Terraformベースに移行されました。おかげで、AWS依存だったものが脱却され、Cloudfrareなどの別のプロバイダ向け(Pulumi依存でもある)との連携も可能になっています。

https://sst.dev/docs/providers#directory

したがってサンプルですが、AWS環境から横断した環境でCloudflare × OpenAI × DynamoDB × S3 のようなアーキテクチャをいとも簡単に組むことができるようになっています。

const db = new aws.dynamodb.Table("Movies");
const bucket = new sst.Bucket("Assets");

const vector = new sst.Vector("Vector", {
  openAiApiKey: new sst.Secret("OpenAiApiKey").value,
});

const site = new sst.Nextjs("Web", {
  link: [db, bucket, vector],
});

new cloudflare.cdn("Cdn", {
  domain: "movies.sst.dev",
  route: {
    "/": site.url,
  },
});

https://sst.dev/blog/moving-away-from-cdk#why-the-change

0→1フェーズのような段階でフロントエンドからバックエンドまでを一つのフレームワークでインフラ構築できてしまう点は非常に強力でしょう。

CDK/Cloudformation 特有の問題の解決

CDKは、前述したようにCloudFormationを生成するラッパーなので、動作しないJSONを生成してしまうことがあります。例えば、循環参照(Circular Dependencies)の問題です。
例えば下記のCloudFrontのエンドポイントとしてLambdaを指定する場合でも動作しなかったりします。

const fn = new Function();
const dist = new CloudFront({
  route: {
    "/my-function": fn.url,
  },
});

fn.addEnvironment({
  key: "endpoint",
  value: dist.url,
});

https://sst.dev/blog/moving-away-from-cdk/#what-is-ion

これらの問題は、CloudFormationでは正常に動作し、CDKで反映させるタイミングで発生するため、フレームワーク側がCloudFormation→CDKを事実上面倒を見ねばならず、SSTの自由度を下げる一因になっていたようです。

パフォーマンスの向上

v2 はCDK / CloudFormationの組み合わせをラップするような仕組みであったため、デプロイの遅さについてはかなり気になる点のひとつでした。さらにそもそもCDK が CloudFormationを生成するツールという側面があるため、そのパフォーマンスへの影響は顕著でした。

v3においては、CDKに依存せずに、IaCの機能をフレームワーク側で制御できるようになったため、パフォーマンスは大きく向上したとのことです。正確ではありませんが、手元でサンプルコードをv2で初回デプロイしたときは1分強ほど時間がかかりましたが、v3では35秒ほどになっていました🙌

おわりに

このようにCDK/CloudFormation依存からの脱却を経て、SST v3は非常に強力なフレームワークになっていると感じました。

ここまで語っておきながらですが、実はもともとの課題であった学習コストの高さなどは、なにも解決されていません。ただ、AWSを超えたアーキテクチャの選択肢が増えたことで、メリットも非常に高いということでポジティブに検討を進めていこうと思います。

参考リンク

any株式会社

Discussion