SST (Ion) 패턴은(는) 무엇을 하나요?
빠른 가이드: SST v3 (Ion)은 Pulumi/Terraform(CDK/CloudFormation 아님)을 기반으로 하는 TypeScript 우선 AWS 인프라-코드 도구입니다.
sst.config.ts에서 고수준 컴포넌트(sst.aws.Function,sst.aws.ApiGatewayV2,sst.aws.Bucket,sst.aws.Dynamo등)를 사용해 전체 앱을 정의합니다. 리소스 링크(link: [bucket]+Resource.MyBucket.name)를 사용해 컴포넌트 간 타입 안전하고 권한 인식 가능한 접근을 제공합니다.sst dev로 10ms 미만의 재로딩이 가능한 라이브 Lambda 개발을 사용합니다.$app.stage로 다중 환경을 분리합니다.transform을 사용해 기본 Pulumi 리소스를 커스터마이즈합니다.
<critical_requirements>
중요: 이 스킬 사용 전 필수 사항
모든 코드는 CLAUDE.md의 프로젝트 규칙을 따라야 합니다(케밥-케이스, 명명된 내보내기, import 순서,
import type, 명명된 상수)
(리소스 링크(link + Resource.*)를 사용해 컴포넌트를 연결해야 합니다 — ARN, 테이블 이름, 버킷 이름을 절대 하드코딩하지 마십시오)
($app.stage를 사용해 환경을 분리해야 합니다 — 명시적인 의도 없이 스테이지 간 리소스를 공유하지 마십시오)
(로컬 개발에는 sst dev를 반드시 사용하십시오 — 실제 AWS 리소스에 대해 10ms 미만 재로딩의 라이브 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, Resource from sst, sst dev, sst deploy, sst remove, sst secret, $app.stage, $transform, $concat, $interpolate, resource linking, live Lambda, Ion
사용 시점:
- TypeScript로 고수준 컴포넌트를 사용해 AWS 인프라 정의
- 서버리스 애플리케이션 배포 (Lambda, API Gateway, DynamoDB, S3, SQS, SNS)
- 풀스택 앱 배포 (AWS에서 Next.js, Remix, Astro, SvelteKit, SolidStart)
- 실제 AWS 리소스를 사용한 라이브 Lambda 개발 설정
- 멀티 스테이지 환경 관리 (dev, staging, production)
- 타입 안전한 리소스 링크로 인프라 컴포넌트 연결
사용하지 말아야 할 때:
- 여러 클라우드 제공자에 걸친 멀티 클라우드 인프라 (SST는 AWS에 중점을 두고 Cloudflare 지원은 제한적)
- SST 추상화가 이점을 주지 않는 기존 Terraform/Pulumi 코드베이스
- 서버리스 컴포넌트 없이 컨테이너 전용 배포가 필요한 프로젝트
다루는 핵심 패턴:
sst.config.ts구조 (app()+run()함수)- 리소스 링크:
link속성 +Resource.*SDK sst dev를 이용한 라이브 Lambda 개발- AWS 컴포넌트: Function, ApiGatewayV2, Dynamo, Bucket, Queue, Topic, Cron
- 프론트엔드 배포: Nextjs, Remix, Astro, StaticSite
$app.stage를 이용한 멀티 스테이지 분리- 기본 Pulumi 리소스 커스터마이즈를 위한 Transform
sst secret을 이용한 시크릿 관리sst.Linkable및Linkable.wrap을 이용한 사용자 정의 링크 가능- 전역 헬퍼:
$app,$dev,$concat,$interpolate,$resolve,$transform
철학
SST v3 (Ion)은 CDK/CloudFormation을 Pulumi/Terraform으로 대체하여 훨씬 빠른 배포와 단순한 프로그래밍 모델을 제공합니다. 핵심 아이디어:
- 하나의 설정 파일 — 전체 앱이
sst.config.ts에 정의됩니다. 인프라, 프론트엔드, 함수가 모두 TypeScript로 함께 선언되며 루프, 조건문, 함수를 사용할 수 있습니다. - 구성(Construct) 대신 컴포넌트 — 고수준
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)
- AWS에 프론트엔드 프레임워크(Next.js, Remix, Astro)를 배포하는 풀스택 앱
- 최소한의 AWS 보일러플레이트로 TypeScript 인프라를 원하는 팀
- 실제 클라우드 리소스에 대한 빠른 로컬 개발 루프가 필요한 프로젝트
SST를 사용하지 말아야 할 때:
- AWS + Cloudflare를 넘어서는 멀티 클라우드 인프라 (SST의 멀티 클라우드 지원은 제한적)
- 서버리스 컴포넌트가 없는 컨테이너 전용 워크로드 (원시 Pulumi 또는 Terraform 사용)
- SST 추상화가 마이그레이션 비용을 추가하는 기존의 대규모 Terraform/Pulumi 코드베이스
핵심 패턴
패턴 1: sst.config.ts 구조
모든 SST 앱은 단일 sst.config.ts 파일을 가지며, app()(메타데이터)과 run()(리소스) 두 함수로 구성됩니다.
/// <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: 라이브 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, 데이터베이스, 스토리지, 큐, 크론 패턴은 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 리소스를 커스터마이즈합니다.
// 컴포넌트별 transform
new sst.aws.Function("Api", {
handler: "src/api.handler",
transform: {
function: (args) => {
args.tracingConfig = { mode: "Active" };
},
},
});
// 글로벌 transform — 특정 유형의 모든 컴포넌트에 적용
$transform(sst.aws.Function, (args) => {
args.environment ??= {};
args.environment.variables ??= {};
args.environment.variables.STAGE = $app.stage;
});
좋은 이유: Transform을 사용하면 SST의 추상화를 포기하지 않고 기본 리소스 속성을 커스터마이즈할 수 있습니다. 글로벌 Transform은 모든 컴포넌트에 기본값을 설정합니다.
Transform 패턴은 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
Transform vs 원시 Pulumi 사용 시기
SST 컴포넌트의 속성을 설정해야 합니까?
|
+-- 속성이 SST 컴포넌트 인자에 존재함 --> SST 속성을 직접 사용
|
+-- 속성이 기본 AWS 리소스에만 존재함 --> transform 사용
|
+-- 모든 컴포넌트 인스턴스에 기본값을 설정해야 함 --> $transform() 사용
|
+-- 이 AWS 서비스에 대한 SST 컴포넌트가 없음 --> 원시 Pulumi 리소스 사용
+-- 연결해야 합니까? --> sst.Linkable.wrap() 또는 new sst.Linkable() 사용
</decision_framework>