Patrones de SST (Ion)
Guía rápida: SST v3 (Ion) es infraestructura como código centrada en TypeScript para AWS, impulsada por Pulumi/Terraform (no CDK/CloudFormation). Define toda tu aplicación en
sst.config.tsusando componentes de alto nivel (sst.aws.Function,sst.aws.ApiGatewayV2,sst.aws.Bucket,sst.aws.Dynamo, etc.). Usa vinculación de recursos (link: [bucket]+Resource.MyBucket.name) para acceso tipado y consciente de permisos entre componentes. Usasst devpara desarrollo Lambda en vivo con recargas inferiores a 10ms. Usa$app.stagepara aislamiento multi-entorno. Usatransformpara personalizar los recursos subyacentes de Pulumi.
<critical_requirements>
CRÍTICO: Antes de Usar Este Skill
Todo el código debe seguir las convenciones del proyecto en CLAUDE.md (kebab-case, exportaciones con nombre, orden de importaciones,
import type, constantes con nombre)
(DEBES usar vinculación de recursos (link + Resource.*) para conectar componentes — NUNCA codifiques ARNs, nombres de tabla o nombres de bucket)
(DEBES usar $app.stage para el aislamiento de entornos — NUNCA compartas recursos entre etapas sin intención explícita)
(DEBES usar sst dev para el desarrollo local — proporciona proxy Lambda en vivo con recargas inferiores a 10ms contra recursos reales de AWS)
(DEBES usar sst secret set para los secretos — NUNCA pongas secretos en sst.config.ts, archivos .env commiteados en git, o variables de entorno)
(DEBES usar transform para personalizar los recursos subyacentes — NUNCA recurras a recursos Pulumi sin procesar cuando exista un componente de SST)
</critical_requirements>
Ejemplos
- Patrones Principales — estructura de sst.config.ts, Function, vinculación de recursos, globales $app, secretos, multi-etapa
- API y Datos — ApiGatewayV2, Dynamo, Bucket, Queue, Topic, Cron, autorización
- Despliegue y DevOps — sst deploy, CI/CD, políticas de eliminación, transformaciones, Vpc, Cluster, frameworks frontend
- Referencia Rápida — comandos CLI, hoja de referencia de componentes, ayudantes globales, constantes con nombre
Auto-detección: 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
Cuándo usarlo:
- Definiendo infraestructura AWS en TypeScript con componentes de alto nivel
- Desplegando aplicaciones serverless (Lambda, API Gateway, DynamoDB, S3, SQS, SNS)
- Desplegando aplicaciones full-stack (Next.js, Remix, Astro, SvelteKit, SolidStart en AWS)
- Configurando desarrollo Lambda en vivo con recursos reales de AWS
- Gestionando entornos multi-etapa (dev, staging, producción)
- Conectando componentes de infraestructura con vinculación de recursos tipada
Cuándo NO usarlo:
- Infraestructura multi-cloud que abarque muchos proveedores (SST está enfocado en AWS con soporte limitado para Cloudflare)
- Bases de código existentes de Terraform/Pulumi donde la abstracción de SST no aporta valor
- Proyectos que necesiten despliegues solo con contenedores sin componentes serverless
Patrones clave cubiertos:
- Estructura de
sst.config.ts(funcionesapp()+run()) - Vinculación de recursos: propiedad
link+ SDKResource.* - Desarrollo Lambda en vivo con
sst dev - Componentes AWS: Function, ApiGatewayV2, Dynamo, Bucket, Queue, Topic, Cron
- Despliegues frontend: Nextjs, Remix, Astro, StaticSite
- Aislamiento multi-etapa con
$app.stage - Transformaciones para personalizar recursos Pulumi subyacentes
- Gestión de secretos con
sst secret - Linkables personalizados con
sst.LinkableyLinkable.wrap - Ayudantes globales:
$app,$dev,$concat,$interpolate,$resolve,$transform
Filosofía
SST v3 (Ion) reemplaza CDK/CloudFormation con Pulumi/Terraform para despliegues drásticamente más rápidos y un modelo de programación más simple. Las ideas principales:
- Un archivo de configuración — Toda tu aplicación se define en
sst.config.ts. Infraestructura, frontends y funciones se declaran conjuntamente en TypeScript con bucles, condicionales y funciones. - Componentes sobre constructos — Los componentes de alto nivel
sst.aws.*encapsulan mejores prácticas (IAM, logging, monitoreo). Usatransformpara acceder a los recursos subyacentes cuando los valores predeterminados no sean suficientes. - Vinculación de recursos — La función estrella.
link: [bucket]otorga automáticamente permisos IAM e inyecta referencias tipadas. Accede medianteResource.MyBucket.nameen tiempo de ejecución. No es necesario pasar ARNs manualmente ni cablear variables de entorno. - Aislamiento por etapa — Cada desarrollador tiene su propia etapa (
sst devcrea un stack personal).$app.stageimpulsa la nomenclatura de recursos. La producción usasst deploy --stage production. - Desarrollo en vivo contra AWS real —
sst devreemplaza las funciones Lambda con stubs que hacen proxy a tu máquina local. Los cambios se recargan en menos de 10ms. Sin emulación local: tu código se ejecuta contra DynamoDB, S3, SQS reales.
Cuándo usar SST:
- Aplicaciones serverless-first en AWS (Lambda, API Gateway, DynamoDB, S3, SQS, SNS)
- Aplicaciones full-stack que despliegan frameworks frontend (Next.js, Remix, Astro) en AWS
- Equipos que quieran infraestructura TypeScript con mínimo boilerplate de AWS
- Proyectos que necesiten bucles de desarrollo local rápidos contra recursos cloud reales
Cuándo NO usar SST:
- Infraestructura multi-cloud más allá de AWS + Cloudflare (el soporte multi-cloud de SST es limitado)
- Cargas de trabajo solo con contenedores sin componentes serverless (usa Pulumi o Terraform sin procesar)
- Bases de código grandes existentes de Terraform/Pulumi donde la abstracción de SST añade coste de migración
Patrones Principales
Patrón 1: Estructura de sst.config.ts
Cada aplicación SST tiene un único sst.config.ts con dos funciones: app() para metadatos y run() para recursos.
/// <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 };
},
});
Por qué es bueno: app() maneja metadatos y políticas específicas de etapa, run() define todos los recursos, removal: "retain" protege los datos de producción, los valores devueltos se convierten en salidas en .sst/outputs.json
Consulta examples/core.md para la configuración completa con multi-etapa, providers y patrones de protección.
Patrón 2: Vinculación de Recursos
La característica definitoria de SST. Vincula recursos para otorgar permisos y acceso tipado automáticamente.
// En 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],
});
// En src/api.ts — código en tiempo de ejecución
import { Resource } from "sst";
import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
const client = new DynamoDBClient({});
// Resource.Notes.name es el nombre de la tabla — tipado, generado automáticamente
console.log(Resource.Notes.name);
Por qué es bueno: Sin paso manual de ARNs, permisos IAM otorgados automáticamente, acceso tipado mediante sst-env.d.ts generado, funciona a través de Functions, frontends y contenedores
Consulta examples/core.md para patrones de vinculación incluyendo linkables personalizados.
Patrón 3: Desarrollo Lambda en Vivo
sst dev hace proxy de las invocaciones Lambda a tu máquina local para ciclos de recarga inferiores a 10ms.
# Inicia desarrollo en vivo — despliega infraestructura, hace proxy de Lambda a la máquina local
sst dev
# Abre un multiplexor: despliega recursos, inicia frontends, tuneliza VPC
// Detecta el modo de desarrollo en el código del handler
const isLocal = process.env.SST_DEV === "true";
Comportamiento clave: Las funciones se reemplazan con stubs que reenvían eventos a través de AppSync a tu máquina local. Tu código local se ejecuta como Workers de Node.js. Los cambios se recargan al instante, sin necesidad de redeploy.
Advertencia: Matar sst dev deja los stubs desplegados. Las invocaciones Lambda posteriores agotarán el tiempo de espera hasta que ejecutes sst dev nuevamente o sst deploy para reemplazar los stubs con código real.
Consulta examples/core.md para el flujo de trabajo de desarrollo y configuración de depuración.
Patrón 4: Componentes AWS
SST proporciona componentes de alto nivel para servicios AWS comunes. Cada uno maneja IAM, logging y configuración automáticamente.
| Componente | Servicio AWS | Caso de Uso |
|---|---|---|
sst.aws.Function | Lambda | Funciones serverless |
sst.aws.ApiGatewayV2 | API Gateway v2 | APIs HTTP con rutas |
sst.aws.Dynamo | DynamoDB | Base de datos NoSQL |
sst.aws.Bucket | S3 | Almacenamiento de objetos |
sst.aws.Queue | SQS | Colas de mensajes |
sst.aws.Topic | SNS | Mensajería pub/sub |
sst.aws.Cron | EventBridge | Tareas programadas |
sst.aws.Vpc | VPC | Aislamiento de red |
sst.aws.Cluster | ECS | Cargas de trabajo en contenedores |
sst.aws.Postgres | RDS Postgres | Base de datos relacional |
sst.aws.Nextjs | Lambda + CloudFront | Despliegue de Next.js |
sst.aws.Remix | Lambda + CloudFront | Despliegue de Remix |
sst.aws.Astro | Lambda + CloudFront | Despliegue de Astro |
sst.aws.StaticSite | S3 + CloudFront | Alojamiento de sitios estáticos |
sst.aws.Router | CloudFront | Enrutamiento de URL |
Consulta examples/api-data.md para patrones de API, base de datos, almacenamiento, colas y cron.
Patrón 5: Gestión de Secretos
Los secretos se cifran y almacenan en S3, se inyectan en los bundles de funciones en el momento del despliegue.
# Establece un secreto (solicita el valor)
sst secret set DATABASE_URL
# Establece un secreto con valor en línea
sst secret set STRIPE_KEY sk_live_xxx
# Carga secretos desde un archivo
sst secret load .env.production
# Lista todos los secretos
sst secret list
// Accede a los secretos mediante vinculación de recursos
import { Resource } from "sst";
const stripeKey = Resource.StripeKey.value;
Advertencia: Los secretos son por etapa. Establécelos para cada etapa por separado. Usa --fallback para establecer un valor predeterminado en todas las etapas.
Consulta examples/core.md para el patrón de secretos con Linkable.
Patrón 6: Transformaciones
Personaliza los recursos Pulumi subyacentes cuando los valores predeterminados de SST no sean suficientes.
// Transformación por componente
new sst.aws.Function("Api", {
handler: "src/api.handler",
transform: {
function: (args) => {
args.tracingConfig = { mode: "Active" };
},
},
});
// Transformación global — se aplica a TODOS los componentes de un tipo
$transform(sst.aws.Function, (args) => {
args.environment ??= {};
args.environment.variables ??= {};
args.environment.variables.STAGE = $app.stage;
});
Por qué es bueno: Las transformaciones te permiten personalizar cualquier propiedad de recurso subyacente sin abandonar las abstracciones de SST. Las transformaciones globales establecen valores predeterminados en todos los componentes.
Consulta examples/deployment.md para patrones de transformación.
Patrón 7: Entornos Multi-Etapa
Cada etapa es un despliegue completamente aislado. Usa $app.stage para la configuración condicional.
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,
});
}
# Etapa de desarrollo personal (predeterminada)
sst dev
# Despliega a staging
sst deploy --stage staging
# Despliega a producción
sst deploy --stage production
Consulta examples/deployment.md para patrones multi-etapa con políticas de eliminación.
<decision_framework>
Marco de Decisión
Elegir un Componente SST
¿Qué estás construyendo?
|
+-- API HTTP
| +-- Rutas simples con handlers Lambda --> sst.aws.ApiGatewayV2
| +-- Necesitas soporte WebSocket --> sst.aws.ApiGatewayWebSocket
| +-- Enrutamiento de URL / CDN --> sst.aws.Router
|
+-- Almacenamiento de datos
| +-- Datos clave-valor / documento --> sst.aws.Dynamo
| +-- Datos relacionales con SQL --> sst.aws.Postgres
| +-- Almacenamiento de archivos/blobs --> sst.aws.Bucket
|
+-- Procesamiento asíncrono
| +-- Mensajería punto a punto --> sst.aws.Queue (SQS)
| +-- Distribución a múltiples suscriptores --> sst.aws.Topic (SNS)
| +-- Tareas programadas --> sst.aws.Cron
|
+-- Cómputo
| +-- Función serverless --> sst.aws.Function
| +-- Carga de trabajo en contenedor --> sst.aws.Cluster + sst.aws.Service
| +-- Trabajo en segundo plano de larga duración --> sst.aws.Function (hasta 15min)
|
+-- Frontend full-stack
+-- Next.js --> sst.aws.Nextjs
+-- Remix --> sst.aws.Remix
+-- Astro --> sst.aws.Astro
+-- SvelteKit --> sst.aws.SvelteKit
+-- SolidStart --> sst.aws.SolidStart
+-- HTML/JS estático --> sst.aws.StaticSite
Cuándo Usar Transformaciones vs Pulumi Sin Procesar
¿Necesitas establecer una propiedad en un componente SST?
|
+-- La propiedad existe en los argumentos del componente SST --> Usa la propiedad SST directamente
|
+-- La propiedad existe solo en el recurso AWS subyacente --> Usa transform
|
+-- Necesitas establecer un valor predeterminado en TODAS las instancias de un componente --> Usa $transform()
|
+-- No existe un componente SST para este servicio AWS --> Usa el recurso Pulumi sin procesar
+-- ¿Necesitas vincularlo? --> Usa sst.Linkable.wrap() o new sst.Linkable()
</decision_framework>