SST(Ion)パターン
クイックガイド: SST v3(Ion)はAWS向けのTypeScriptファーストなInfrastructure-as-Codeで、Pulumi/Terraformをベースとしています(CDK/CloudFormationではありません)。
sst.config.tsで高レベルコンポーネント(sst.aws.Function、sst.aws.ApiGatewayV2、sst.aws.Bucket、sst.aws.Dynamoなど)を使用してアプリ全体を定義します。リソースリンク(link: [bucket]+Resource.MyBucket.name)を使用して、コンポーネント間の型安全で権限を考慮したアクセスを実現します。sst devでサブ10msのリロードが可能なLive Lambda開発を行います。$app.stageでマルチステージ環境を分離します。transformを使用して基盤となるPulumiリソースをカスタマイズします。
<critical_requirements>
重要:このスキルを使用する前に
すべてのコードは CLAUDE.md のプロジェクト規約に従う必要があります(ケバブケース、名前付きエクスポート、インポート順序、
import type、名前付き定数)
(コンポーネントの接続には必ずリソースリンク(link + Resource.*)を使用してください — ARN、テーブル名、バケット名をハードコードしないでください)
(環境分離には必ず $app.stage を使用してください — 明示的な意図なくステージ間でリソースを共有しないでください)
(ローカル開発には必ず sst dev を使用してください — 実際のAWSリソースに対してサブ10msのリロードでLive Lambdaプロキシを提供します)
(シークレットには必ず sst secret set を使用してください — sst.config.ts、Gitにコミットされた .env ファイル、環境変数にシークレットを絶対に置かないでください)
(基盤となるリソースのカスタマイズには必ず transform を使用してください — SSTコンポーネントが存在する場合に生のPulumiリソースに手を出さないでください)
</critical_requirements>
例
- コアパターン — sst.config.ts の構造、Function、リソースリンク、$app グローバル、シークレット、マルチステージ
- APIとデータ — ApiGatewayV2、Dynamo、Bucket、Queue、Topic、Cron、認可
- デプロイとDevOps — sst deploy、CI/CD、削除ポリシー、変換、Vpc、Cluster、フロントエンドフレームワーク
- クイックリファレンス — CLIコマンド、コンポーネント早見表、グローバルヘルパー、名前付き定数
自動検出: SST、sst.config.ts、sst.aws.Function、sst.aws.ApiGatewayV2、sst.aws.Bucket、sst.aws.Dynamo、sst.aws.Queue、sst.aws.Topic、sst.aws.Cron、sst.aws.Nextjs、sst.aws.Remix、sst.aws.Astro、sst.aws.StaticSite、sst.aws.Vpc、sst.aws.Cluster、sst.aws.Postgres、sst.aws.Router、sst.Linkable、sst からの Resource、sst dev、sst deploy、sst remove、sst secret、$app.stage、$transform、$concat、$interpolate、リソースリンク、Live Lambda、Ion
使用すべき場合:
- 高レベルコンポーネントを使用してAWSインフラをTypeScriptで定義する場合
- サーバーレスアプリケーション(Lambda、API Gateway、DynamoDB、S3、SQS、SNS)をデプロイする場合
- フルスタックアプリ(Next.js、Remix、Astro、SvelteKit、SolidStart on AWS)をデプロイする場合
- 実際のAWSリソースを使用してLive Lambda開発をセットアップする場合
- マルチステージ環境(dev、staging、production)を管理する場合
- 型安全なリソースリンクでインフラコンポーネントを接続する場合
使用すべきでない場合:
- 多くのプロバイダにまたがるマルチクラウドインフラ(SSTはAWSに特化しており、Cloudflareのサポートは限定的です)
- SSTの抽象化が価値を追加しない既存のTerraform/Pulumiコードベース
- サーバーレスコンポーネントなしのコンテナのみのデプロイメントを必要とするプロジェクト
カバーする主要パターン:
sst.config.tsの構造(app()+run()関数)- リソースリンク:
linkプロパティ +Resource.*SDK sst devを使用したLive Lambda開発- AWSコンポーネント:Function、ApiGatewayV2、Dynamo、Bucket、Queue、Topic、Cron
- フロントエンドデプロイメント:Nextjs、Remix、Astro、StaticSite
$app.stageによるマルチステージ分離- 基盤となるPulumiリソースをカスタマイズするための変換
sst secretによるシークレット管理sst.LinkableとLinkable.wrapによるカスタムリンカブル- グローバルヘルパー:
$app、$dev、$concat、$interpolate、$resolve、$transform
哲学
SST v3(Ion)はCDK/CloudFormationをPulumi/Terraformに置き換え、劇的に高速なデプロイとシンプルなプログラミングモデルを実現します。核となるアイデアは以下の通りです:
- 単一の設定ファイル — アプリ全体が
sst.config.tsで定義されます。インフラ、フロントエンド、関数がすべてTypeScriptで宣言され、ループ、条件分岐、関数が使用可能です。 - 構築物ではなくコンポーネント — 高レベルの
sst.aws.*コンポーネントはベストプラクティス(IAM、ロギング、モニタリング)をカプセル化します。デフォルトで十分でない場合はtransformを使用して基盤となるリソースにアクセスします。 - リソースリンク — キラーフィーチャーです。
link: [bucket]は自動的にIAM権限を付与し、型安全な参照を注入します。ランタイムではResource.MyBucket.nameでアクセスします。ARNの手動引き渡しや環境変数の配線は不要です。 - ステージベースの分離 — すべての開発者が独自のステージを持ちます(
sst devは個人のスタックを作成します)。$app.stageがリソースの命名を駆動します。本番環境ではsst deploy --stage productionを使用します。 - 実際のAWSに対するライブ開発 —
sst devはLambda関数をスタブに置き換え、ローカルマシンにプロキシします。変更は10ms未満でリロードされます。ローカルエミュレーションはありません — コードは実際のDynamoDB、S3、SQSに対して実行されます。
SSTを使用すべき場合:
- AWS上のサーバーレスファーストのアプリケーション(Lambda、API Gateway、DynamoDB、S3、SQS、SNS)
- フロントエンドフレームワーク(Next.js、Remix、Astro)をAWSにデプロイするフルスタックアプリ
- 最小限のAWSボイラープレートでTypeScriptインフラを求めるチーム
- 実際のクラウドリソースに対して高速なローカル開発ループを必要とするプロジェクト
SSTを使用すべきでない場合:
- AWSとCloudflare以外のマルチクラウドインフラ(SSTのマルチクラウドサポートは限定的です)
- サーバーレスコンポーネントなしのコンテナのみのワークロード(生のPulumiまたはTerraformを使用してください)
- SSTの抽象化が移行コストを追加する既存の大規模なTerraform/Pulumiコードベース
コアパターン
パターン1:sst.config.ts の構造
すべてのSSTアプリは単一の sst.config.ts を持ち、メタデータのための app() 関数とリソースのための run() 関数の2つの関数があります。
/// <reference path="./.sst/platform/config.d.ts" />
export default $config({
app(input) {
return {
name: "my-app",
home: "aws",
removal: input.stage === "production" ? "retain" : "remove",
protect: input.stage === "production",
providers: {
aws: { region: "us-east-1" },
},
};
},
async run() {
const bucket = new sst.aws.Bucket("Uploads");
const api = new sst.aws.Function("Api", {
handler: "src/api.handler",
link: [bucket],
});
return { apiUrl: api.url };
},
});
なぜ優れているか: app() はメタデータとステージ固有のポリシーを処理し、run() はすべてのリソースを定義し、removal: "retain" は本番データを保護し、戻り値は .sst/outputs.json の出力になります。
完全な設定については examples/core.md を参照してください。マルチステージ、プロバイダ、保護パターンについて説明しています。
パターン2:リソースリンク
SSTの定義的な機能です。リソースをリンクして権限と型安全なアクセスを自動的に付与します。
// sst.config.ts 内
const table = new sst.aws.Dynamo("Notes", {
fields: { userId: "string", noteId: "string" },
primaryIndex: { hashKey: "userId", rangeKey: "noteId" },
});
new sst.aws.Function("Api", {
handler: "src/api.handler",
link: [table],
});
// src/api.ts 内 — ランタイムコード
import { Resource } from "sst";
import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
const client = new DynamoDBClient({});
// Resource.Notes.name はテーブル名です — 型安全で自動生成されます
console.log(Resource.Notes.name);
なぜ優れているか: ARNの手動引き渡しなし、IAM権限が自動的に付与、生成された sst-env.d.ts による型安全なアクセス、Functions、フロントエンド、コンテナ間で動作します。
カスタムリンカブルのリンクパターンについては examples/core.md を参照してください。
パターン3:Live Lambda開発
sst dev はLambda呼び出しをローカルマシンにプロキシし、サブ10msのリロードサイクルを実現します。
# ライブ開発を開始 — インフラをデプロイし、Lambdaをローカルマシンにプロキシ
sst dev
# マルチプレクサを開く:リソースをデプロイ、フロントエンドを起動、VPCをトンネリング
// ハンドラコードで開発モードを検出
const isLocal = process.env.SST_DEV === "true";
主な動作: 関数はスタブに置き換えられ、AppSyncを介してイベントをローカルマシンに転送します。ローカルコードはNode.js Workersとして実行されます。変更は即座にリロードされます — 再デプロイは不要です。
注意点: sst dev を強制終了するとスタブがデプロイされたままになります。その後のLambda呼び出しは、sst dev を再度実行するか、sst deploy でスタブを実際のコードで置き換えるまでタイムアウトします。
開発ワークフローとデバッグ設定については examples/core.md を参照してください。
パターン4:AWSコンポーネント
SSTは一般的なAWSサービス向けの高レベルコンポーネントを提供します。各コンポーネントはIAM、ロギング、設定を自動的に処理します。
| コンポーネント | AWSサービス | ユースケース |
|---|---|---|
sst.aws.Function | Lambda | サーバーレス関数 |
sst.aws.ApiGatewayV2 | API Gateway v2 | ルート付きHTTP API |
sst.aws.Dynamo | DynamoDB | NoSQLデータベース |
sst.aws.Bucket | S3 | オブジェクトストレージ |
sst.aws.Queue | SQS | メッセージキュー |
sst.aws.Topic | SNS | Pub/Subメッセージング |
sst.aws.Cron | EventBridge | スケジュールタスク |
sst.aws.Vpc | VPC | ネットワーク分離 |
sst.aws.Cluster | ECS | コンテナワークロード |
sst.aws.Postgres | RDS Postgres | リレーショナルデータベース |
sst.aws.Nextjs | Lambda + CloudFront | Next.jsデプロイ |
sst.aws.Remix | Lambda + CloudFront | Remixデプロイ |
sst.aws.Astro | Lambda + CloudFront | Astroデプロイ |
sst.aws.StaticSite | S3 + CloudFront | 静的サイトホスティング |
sst.aws.Router | CloudFront | URLルーティング |
API、データベース、ストレージ、キュー、cronパターンについては examples/api-data.md を参照してください。
パターン5:シークレット管理
シークレットは暗号化されてS3に保存され、デプロイ時に関数バンドルに注入されます。
# シークレットを設定(値を入力するプロンプトが表示されます)
sst secret set DATABASE_URL
# 値をインラインでシークレットを設定
sst secret set STRIPE_KEY sk_live_xxx
# ファイルからシークレットを読み込み
sst secret load .env.production
# すべてのシークレットを一覧表示
sst secret list
// リソースリンクを介してシークレットにアクセス
import { Resource } from "sst";
const stripeKey = Resource.StripeKey.value;
注意点: シークレットはステージごとに設定されます。各ステージで個別に設定してください。--fallback を使用すると、すべてのステージにデフォルトを設定できます。
Linkableパターンを使用したシークレットについては examples/core.md を参照してください。
パターン6:変換(Transform)
SSTのデフォルトで十分でない場合に、基盤となるPulumiリソースをカスタマイズします。
// コンポーネントごとの変換
new sst.aws.Function("Api", {
handler: "src/api.handler",
transform: {
function: (args) => {
args.tracingConfig = { mode: "Active" };
},
},
});
// グローバル変換 — 特定のタイプのすべてのコンポーネントに適用されます
$transform(sst.aws.Function, (args) => {
args.environment ??= {};
args.environment.variables ??= {};
args.environment.variables.STAGE = $app.stage;
});
なぜ優れているか: 変換を使用すると、SSTの抽象化を放棄することなく、基盤となる任意のリソースプロパティをカスタマイズできます。グローバル変換はすべてのコンポーネントにデフォルトを設定します。
変換パターンについては examples/deployment.md を参照してください。
パターン7:マルチステージ環境
すべてのステージは完全に分離されたデプロイメントです。条件付き設定には $app.stage を使用します。
async run() {
const isProd = $app.stage === "production";
const table = new sst.aws.Dynamo("Notes", {
fields: { userId: "string", noteId: "string" },
primaryIndex: { hashKey: "userId", rangeKey: "noteId" },
deletionProtection: isProd,
});
}
# 個人開発ステージ(デフォルト)
sst dev
# ステージングにデプロイ
sst deploy --stage staging
# 本番環境にデプロイ
sst deploy --stage production
削除ポリシーを使用したマルチステージパターンについては examples/deployment.md を参照してください。
<decision_framework>
意思決定フレームワーク
SSTコンポーネントの選択
何を構築していますか?
|
+-- HTTP API
| +-- Lambdaハンドラを使用したシンプルなルート --> sst.aws.ApiGatewayV2
| +-- WebSocketサポートが必要 --> sst.aws.ApiGatewayWebSocket
| +-- URLルーティング / CDN --> sst.aws.Router
|
+-- データストレージ
| +-- キーバリュー / ドキュメントデータ --> sst.aws.Dynamo
| +-- SQLを使用したリレーショナルデータ --> sst.aws.Postgres
| +-- ファイル / ブロブストレージ --> sst.aws.Bucket
|
+-- 非同期処理
| +-- ポイントツーポイントメッセージング --> sst.aws.Queue (SQS)
| +-- 複数のサブスクライバーへのファンアウト --> sst.aws.Topic (SNS)
| +-- スケジュールタスク --> sst.aws.Cron
|
+-- コンピュート
| +-- サーバーレス関数 --> sst.aws.Function
| +-- コンテナワークロード --> sst.aws.Cluster + sst.aws.Service
| +-- 長時間実行バックグラウンドジョブ --> sst.aws.Function(最大15分)
|
+-- フルスタックフロントエンド
+-- Next.js --> sst.aws.Nextjs
+-- Remix --> sst.aws.Remix
+-- Astro --> sst.aws.Astro
+-- SvelteKit --> sst.aws.SvelteKit
+-- SolidStart --> sst.aws.SolidStart
+-- 静的HTML/JS --> sst.aws.StaticSite
変換 vs 生のPulumiをいつ使用するか
SSTコンポーネントのプロパティを設定する必要がありますか?
|
+-- プロパティがSSTコンポーネントの引数に存在する --> SSTのプロパティを直接使用
|
+-- プロパティが基盤となるAWSリソースにのみ存在する --> transformを使用
|
+-- コンポーネントのすべてのインスタンスにデフォルトを設定する必要がある --> $transform() を使用
|
+-- このAWSサービスに対応するSSTコンポーネントが存在しない --> 生のPulumiリソースを使用
+-- リンクする必要がありますか? --> sst.Linkable.wrap() または new sst.Linkable() を使用
</decision_framework>