Communitygithub.com

SST (Ion) 패턴

SST v3 (Ion)은 Pulumi/Terraform 기반의 TypeScript 우선 AWS 인프라-코드 도구입니다. `sst.config.ts`에서 고수준 컴포넌트를 사용해 전체 애플리케이션을 정의하고, 리소스 링크로 타입 안전한 연결을 제공하며, 라이브 Lambda 개발을 지원합니다.

SST (Ion) 패턴란 무엇인가요?

이 스킬은 AWS 서버리스 애플리케이션을 TypeScript로 정의하고 배포하기 위한 SST v3 (Ion) 패턴을 제공합니다. Pulumi/Terraform을 기반으로 CDK/CloudFormation보다 빠른 배포와 단순한 프로그래밍 모델을 제공합니다. 핵심 기능으로는 `sst.aws.Function`, `sst.aws.ApiGatewayV2`, `sst.aws.Dynamo` 등 AWS 서비스를 추상화한 고수준 컴포넌트, 리소스 간 타입 안전한 연결과 IAM 권한을 자동 부여하는 리소스 링크(`link` + `Resource.*`), 실제 AWS 리소스에 대해 로컬에서 Lambda를 개발할 수 있는 `sst dev` 라이브 개발 모드, `$app.stage`를 통한 멀티 스테이지 환경 격리, 그리고 기본 Pulumi 리소스를 커스터마이즈할 수 있는 `transform` 기능을 다룹니다. 이 스킬은 Next.js, Remix, Astro 같은 풀스택 프론트엔드 프레임워크 배포와 함께 서버리스 애플리케이션 구축에 적합합니다. CLAUDE.md의 프로젝트 규칙을 따르고, ARN이나 리소스 이름을 하드코딩하지 않고 리소스 링크를 사용해야 하며, 비밀 정보는 `sst secret set`으로 관리해야 합니다.

지원 대상✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/agents-inc/skills/tree/HEAD/src/skills/infra-iac-sst

즐겨 사용하는 AI에게 물어보기

이 에이전트 스킬이 미리 로드된 새 채팅을 엽니다.

문서

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으로 대체하여 훨씬 빠른 배포와 단순한 프로그래밍 모델을 제공합니다. 핵심 아이디어:

  1. 하나의 설정 파일 — 전체 앱이 sst.config.ts에 정의됩니다. 인프라, 프론트엔드, 함수가 모두 TypeScript로 함께 선언되며 루프, 조건문, 함수를 사용할 수 있습니다.
  2. 구성(Construct) 대신 컴포넌트 — 고수준 sst.aws.* 컴포넌트는 모범 사례(IAM, 로깅, 모니터링)를 캡슐화합니다. 기본값이 충분하지 않을 때는 transform을 사용해 기본 리소스에 접근합니다.
  3. 리소스 링크 — 핵심 기능입니다. link: [bucket]은 IAM 권한을 자동으로 부여하고 타입 안전한 참조를 주입합니다. 런타임에 Resource.MyBucket.name으로 접근합니다. 수동 ARN 전달이나 환경 변수 연결이 필요 없습니다.
  4. 스테이지 기반 격리 — 모든 개발자는 자신만의 스테이지를 가집니다 (sst dev가 개인 스택 생성). $app.stage가 리소스 이름을 결정합니다. 프로덕션은 sst deploy --stage production을 사용합니다.
  5. 실제 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.FunctionLambda서버리스 함수
sst.aws.ApiGatewayV2API Gateway v2라우트가 있는 HTTP API
sst.aws.DynamoDynamoDBNoSQL 데이터베이스
sst.aws.BucketS3객체 스토리지
sst.aws.QueueSQS메시지 큐
sst.aws.TopicSNSPub/Sub 메시징
sst.aws.CronEventBridge예약된 작업
sst.aws.VpcVPC네트워크 격리
sst.aws.ClusterECS컨테이너 워크로드
sst.aws.PostgresRDS Postgres관계형 데이터베이스
sst.aws.NextjsLambda + CloudFrontNext.js 배포
sst.aws.RemixLambda + CloudFrontRemix 배포
sst.aws.AstroLambda + CloudFrontAstro 배포
sst.aws.StaticSiteS3 + CloudFront정적 사이트 호스팅
sst.aws.RouterCloudFrontURL 라우팅

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>

Individual skills in this repo

This repo contains 11 individual skills — each has its own dedicated page.

관련 스킬