agents-inc/skills/src/skills/infra-iac-sst/SKILL.md
infra-iac-sst
SST (Ion) infrastructure-as-code — TypeScript-first serverless on AWS with Pulumi, resource linking, and live Lambda dev
- Source repository stars
- 23
- Declared platforms
- 0
- Static risk flags
- 1
- Last source update
- 2026-08-09
- Source checked
- 2026-08-28
Decision brief
What it does: where it fits
Quick Guide: SST v3 (Ion) is TypeScript-first infrastructure-as-code for AWS, powered by Pulumi/Terraform (not CDK/CloudFormation). Define your entire app in sst.config.ts using high-level components (sst.aws.Function, sst.aws.ApiGatewayV2, sst.aws.Bucket, sst.aws.Dynamo, etc.).…
Not for
- Tasks that require unconfirmed production actions or broad system permissions.
- Environments where the pinned source and install steps cannot be inspected.
Compatibility matrix
Platform support, with evidence labels
| Platform | Status | Evidence | What to check |
|---|---|---|---|
| Codex | Not declared | No explicit evidence | Portability before use |
| Claude Code | Not declared | No explicit evidence | Portability before use |
| Cursor | Not declared | No explicit evidence | Portability before use |
| Gemini CLI | Not declared | No explicit evidence | Portability before use |
Installation
Inspect first. Install second.
The source command is displayed only when detected. A safe inspection prompt is always available so your agent can explain every action before execution.
npx skills add https://github.com/agents-inc/skills --skill "src/skills/infra-iac-sst"Inspect the Agent Skill "infra-iac-sst" from https://github.com/agents-inc/skills/blob/81d43a51211aca12c85dcc16085fa99014ec548e/src/skills/infra-iac-sst/SKILL.md at commit 81d43a51211aca12c85dcc16085fa99014ec548e. List every install step, command, network request, credential, file read/write, external action, and rollback step. Explain whether it fits my task. Do not install or execute anything until I approve.
Workflow
What the source asks the agent to do
- 01
Pattern 7: Multi-Stage Environments
Every stage is a fully isolated deployment. Use $app.stage for conditional configuration.
Every stage is a fully isolated deployment. Use $app.stage for conditional configuration. - 02
Personal dev stage (default)
Review the “Personal dev stage (default)” section in the pinned source before continuing.
Review and apply the “Personal dev stage (default)” source section. - 03
CRITICAL: Before Using This Skill
All code must follow project conventions in CLAUDE.md (kebab-case, named exports, import ordering, import type, named constants)
All code must follow project conventions in CLAUDE.md (kebab-case, named exports, import ordering, import type, named constants)(You MUST use resource linking (link + Resource.) to connect components — NEVER hardcode ARNs, table names, or bucket names)(You MUST use $app.stage for environment isolation — NEVER share resources across stages without explicit intent) - 04
Examples
Auto-detection: 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.Route…
Core Patterns — sst.config.ts structure, Function, resource linking, $app globals, secrets, multi-stageAPI & Data — ApiGatewayV2, Dynamo, Bucket, Queue, Topic, Cron, authorizationDeployment & DevOps — sst deploy, CI/CD, removal policies, transforms, Vpc, Cluster, frontend frameworks - 05
Philosophy
SST v3 (Ion) replaces CDK/CloudFormation with Pulumi/Terraform for dramatically faster deployments and a simpler programming model. The core ideas:
One config file — Your entire app is defined in sst.config.ts. Infrastructure, frontends, and functions all declared together in TypeScript with loops, conditionals, and functions.Components over constructs — High-level sst.aws. components encapsulate best practices (IAM, logging, monitoring). Use transform to reach into underlying resources when defaults aren't enough.Resource linking — The killer feature. link: [bucket] automatically grants IAM permissions and injects type-safe references. Access via Resource.MyBucket.name at runtime. No manual ARN passing or environment variable wi…
Permission review
Static risk signals and limitations
Reads files
The documentation asks the agent to read local files, directories, or repositories.
# Load secrets from a fileEvidence record
Why each signal appears
| Signal | Value | Evidence type | Meaning |
|---|---|---|---|
| Quality score | 92/100 | Computed | Documentation, specificity, maintenance, and trust rules |
| Repository stars | 23 | Source | Repository attention, not individual Skill quality |
| Compatibility | 0 platforms | Source | Declared in the catalog source record |
| Usage guide | automated source guide | Editorial | Generated or reviewed according to the visible evidence level |
Pinned source
Provenance and original SKILL.md
- Repository
- agents-inc/skills
- Skill path
- src/skills/infra-iac-sst/SKILL.md
- Commit
- 81d43a51211aca12c85dcc16085fa99014ec548e
- License
- MIT
- Collected
- 2026-08-28
- Default branch
- main
View the original SKILL.md
SST (Ion) Patterns
Quick Guide: SST v3 (Ion) is TypeScript-first infrastructure-as-code for AWS, powered by Pulumi/Terraform (not CDK/CloudFormation). Define your entire app in
sst.config.tsusing high-level components (sst.aws.Function,sst.aws.ApiGatewayV2,sst.aws.Bucket,sst.aws.Dynamo, etc.). Use resource linking (link: [bucket]+Resource.MyBucket.name) for type-safe, permission-aware access between components. Usesst devfor live Lambda development with sub-10ms reloads. Use$app.stagefor multi-environment isolation. Usetransformto customize underlying Pulumi resources.
<critical_requirements>
CRITICAL: Before Using This Skill
All code must follow project conventions in CLAUDE.md (kebab-case, named exports, import ordering,
import type, named constants)
(You MUST use resource linking (link + Resource.*) to connect components — NEVER hardcode ARNs, table names, or bucket names)
(You MUST use $app.stage for environment isolation — NEVER share resources across stages without explicit intent)
(You MUST use sst dev for local development — it provides live Lambda proxying with sub-10ms reloads against real AWS resources)
(You MUST use sst secret set for secrets — NEVER put secrets in sst.config.ts, .env files committed to git, or environment variables)
(You MUST use transform to customize underlying resources — NEVER reach for raw Pulumi resources when an SST component exists)
</critical_requirements>
Examples
- Core Patterns — sst.config.ts structure, Function, resource linking, $app globals, secrets, multi-stage
- API & Data — ApiGatewayV2, Dynamo, Bucket, Queue, Topic, Cron, authorization
- Deployment & DevOps — sst deploy, CI/CD, removal policies, transforms, Vpc, Cluster, frontend frameworks
- Quick Reference — CLI commands, component cheat sheet, global helpers, named constants
Auto-detection: 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
When to use:
- Defining AWS infrastructure in TypeScript with high-level components
- Deploying serverless applications (Lambda, API Gateway, DynamoDB, S3, SQS, SNS)
- Deploying full-stack apps (Next.js, Remix, Astro, SvelteKit, SolidStart on AWS)
- Setting up live Lambda development with real AWS resources
- Managing multi-stage environments (dev, staging, production)
- Connecting infrastructure components with type-safe resource linking
When NOT to use:
- Multi-cloud infrastructure spanning many providers (SST is AWS-focused with limited Cloudflare support)
- Existing Terraform/Pulumi codebases where SST abstraction adds no value
- Projects that need container-only deployments without serverless components
Key patterns covered:
sst.config.tsstructure (app()+run()functions)- Resource linking:
linkproperty +Resource.*SDK - Live Lambda development with
sst dev - AWS components: Function, ApiGatewayV2, Dynamo, Bucket, Queue, Topic, Cron
- Frontend deployments: Nextjs, Remix, Astro, StaticSite
- Multi-stage isolation with
$app.stage - Transforms for customizing underlying Pulumi resources
- Secrets management with
sst secret - Custom linkables with
sst.LinkableandLinkable.wrap - Global helpers:
$app,$dev,$concat,$interpolate,$resolve,$transform
Philosophy
SST v3 (Ion) replaces CDK/CloudFormation with Pulumi/Terraform for dramatically faster deployments and a simpler programming model. The core ideas:
- One config file — Your entire app is defined in
sst.config.ts. Infrastructure, frontends, and functions all declared together in TypeScript with loops, conditionals, and functions. - Components over constructs — High-level
sst.aws.*components encapsulate best practices (IAM, logging, monitoring). Usetransformto reach into underlying resources when defaults aren't enough. - Resource linking — The killer feature.
link: [bucket]automatically grants IAM permissions and injects type-safe references. Access viaResource.MyBucket.nameat runtime. No manual ARN passing or environment variable wiring. - Stage-based isolation — Every developer gets their own stage (
sst devcreates a personal stack).$app.stagedrives resource naming. Production usessst deploy --stage production. - Live dev against real AWS —
sst devreplaces Lambda functions with stubs that proxy to your local machine. Changes reload in under 10ms. No local emulation — your code runs against real DynamoDB, S3, SQS.
When to use SST:
- Serverless-first applications on AWS (Lambda, API Gateway, DynamoDB, S3, SQS, SNS)
- Full-stack apps deploying frontend frameworks (Next.js, Remix, Astro) to AWS
- Teams that want TypeScript infrastructure with minimal AWS boilerplate
- Projects needing fast local development loops against real cloud resources
When NOT to use SST:
- Multi-cloud infrastructure beyond AWS + Cloudflare (SST's multi-cloud support is limited)
- Container-only workloads with no serverless components (use raw Pulumi or Terraform)
- Existing large Terraform/Pulumi codebases where SST abstraction adds migration cost
Core Patterns
Pattern 1: sst.config.ts Structure
Every SST app has a single sst.config.ts with two functions: app() for metadata and run() for resources.
/// <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 };
},
});
Why good: app() handles metadata and stage-specific policies, run() defines all resources, removal: "retain" protects production data, returned values become outputs in .sst/outputs.json
See examples/core.md for full config with multi-stage, providers, and protect patterns.
Pattern 2: Resource Linking
The defining SST feature. Link resources to grant permissions and type-safe access automatically.
// In 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],
});
// In src/api.ts — runtime code
import { Resource } from "sst";
import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
const client = new DynamoDBClient({});
// Resource.Notes.name is the table name — type-safe, auto-generated
console.log(Resource.Notes.name);
Why good: No manual ARN passing, IAM permissions granted automatically, type-safe access via generated sst-env.d.ts, works across Functions, frontends, and containers
See examples/core.md for linking patterns including custom linkables.
Pattern 3: Live Lambda Development
sst dev proxies Lambda invocations to your local machine for sub-10ms reload cycles.
# Start live dev — deploys infra, proxies Lambda to local machine
sst dev
# Opens multiplexer: deploys resources, starts frontends, tunnels VPC
// Detect dev mode in handler code
const isLocal = process.env.SST_DEV === "true";
Key behavior: Functions are replaced with stubs that forward events via AppSync to your local machine. Your local code runs as Node.js Workers. Changes reload instantly — no redeploy needed.
Gotcha: Killing sst dev leaves stubs deployed. Subsequent Lambda invocations will timeout until you run sst dev again or sst deploy to replace stubs with real code.
See examples/core.md for dev workflow and debugging setup.
Pattern 4: AWS Components
SST provides high-level components for common AWS services. Each handles IAM, logging, and configuration automatically.
| Component | AWS Service | Use Case |
|---|---|---|
sst.aws.Function | Lambda | Serverless functions |
sst.aws.ApiGatewayV2 | API Gateway v2 | HTTP APIs with routes |
sst.aws.Dynamo | DynamoDB | NoSQL database |
sst.aws.Bucket | S3 | Object storage |
sst.aws.Queue | SQS | Message queues |
sst.aws.Topic | SNS | Pub/sub messaging |
sst.aws.Cron | EventBridge | Scheduled tasks |
sst.aws.Vpc | VPC | Network isolation |
sst.aws.Cluster | ECS | Container workloads |
sst.aws.Postgres | RDS Postgres | Relational database |
sst.aws.Nextjs | Lambda + CloudFront | Next.js deployment |
sst.aws.Remix | Lambda + CloudFront | Remix deployment |
sst.aws.Astro | Lambda + CloudFront | Astro deployment |
sst.aws.StaticSite | S3 + CloudFront | Static site hosting |
sst.aws.Router | CloudFront | URL routing |
See examples/api-data.md for API, database, storage, queue, and cron patterns.
Pattern 5: Secrets Management
Secrets are encrypted and stored in S3, injected into function bundles at deploy time.
# Set a secret (prompts for value)
sst secret set DATABASE_URL
# Set a secret with value inline
sst secret set STRIPE_KEY sk_live_xxx
# Load secrets from a file
sst secret load .env.production
# List all secrets
sst secret list
// Access secrets via resource linking
import { Resource } from "sst";
const stripeKey = Resource.StripeKey.value;
Gotcha: Secrets are per-stage. Set them for each stage separately. Use --fallback to set a default across all stages.
See examples/core.md for secrets with Linkable pattern.
Pattern 6: Transforms
Customize underlying Pulumi resources when SST defaults aren't enough.
// Per-component transform
new sst.aws.Function("Api", {
handler: "src/api.handler",
transform: {
function: (args) => {
args.tracingConfig = { mode: "Active" };
},
},
});
// Global transform — applies to ALL components of a type
$transform(sst.aws.Function, (args) => {
args.environment ??= {};
args.environment.variables ??= {};
args.environment.variables.STAGE = $app.stage;
});
Why good: Transforms let you customize any underlying resource property without abandoning SST's abstractions. Global transforms set defaults across all components.
See examples/deployment.md for transform patterns.
Pattern 7: Multi-Stage Environments
Every stage is a fully isolated deployment. Use $app.stage for conditional configuration.
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,
});
}
# Personal dev stage (default)
sst dev
# Deploy to staging
sst deploy --stage staging
# Deploy to production
sst deploy --stage production
See examples/deployment.md for multi-stage patterns with removal policies.
<decision_framework>
Decision Framework
Choosing an SST Component
What are you building?
|
+-- HTTP API
| +-- Simple routes with Lambda handlers --> sst.aws.ApiGatewayV2
| +-- Need WebSocket support --> sst.aws.ApiGatewayWebSocket
| +-- URL routing / CDN --> sst.aws.Router
|
+-- Data storage
| +-- Key-value / document data --> sst.aws.Dynamo
| +-- Relational data with SQL --> sst.aws.Postgres
| +-- File/blob storage --> sst.aws.Bucket
|
+-- Async processing
| +-- Point-to-point messaging --> sst.aws.Queue (SQS)
| +-- Fan-out to multiple subscribers --> sst.aws.Topic (SNS)
| +-- Scheduled tasks --> sst.aws.Cron
|
+-- Compute
| +-- Serverless function --> sst.aws.Function
| +-- Container workload --> sst.aws.Cluster + sst.aws.Service
| +-- Long-running background job --> sst.aws.Function (up to 15min)
|
+-- Full-stack frontend
+-- Next.js --> sst.aws.Nextjs
+-- Remix --> sst.aws.Remix
+-- Astro --> sst.aws.Astro
+-- SvelteKit --> sst.aws.SvelteKit
+-- SolidStart --> sst.aws.SolidStart
+-- Static HTML/JS --> sst.aws.StaticSite
When to Use Transforms vs Raw Pulumi
Need to set a property on an SST component?
|
+-- Property exists on the SST component args --> Use the SST property directly
|
+-- Property exists only on the underlying AWS resource --> Use transform
|
+-- Need to set a default across ALL instances of a component --> Use $transform()
|
+-- No SST component exists for this AWS service --> Use raw Pulumi resource
+-- Need to link it? --> Use sst.Linkable.wrap() or new sst.Linkable()
</decision_framework>
<red_flags>
RED FLAGS
High Priority Issues:
- Hardcoding ARNs, table names, or bucket names instead of using resource linking (
link+Resource.*) — defeats SST's type-safe wiring and breaks across stages - Sharing resource names across stages without
$app.stageprefix — causes resource conflicts and accidental cross-stage access - Putting secrets in
sst.config.tsor committed.envfiles instead of usingsst secret set— secrets leak to version control - Using
sst devfor shared environments (staging, production) — stubs proxy to a single developer's machine, breaking for everyone else - Creating raw Pulumi resources when an equivalent
sst.aws.*component exists — loses SST's linking, permissions, and defaults
Medium Priority Issues:
- Not setting
removal: "retain"andprotect: truefor production stages — accidentalsst removedeletes all data - Missing
/// <reference path="./.sst/platform/config.d.ts" />at top ofsst.config.ts— loses type checking for$app,$transform, etc. - Using
.envfiles for secrets instead ofsst secret—.envfiles aren't encrypted and must be managed manually per stage - Not running
sst deployafter finishingsst devsession — stubs remain deployed and Lambda invocations timeout
Common Mistakes:
- Forgetting that
sst devstubs persist after you stop the process — always redeploy or re-runsst dev - Using
$app.stagein runtime code — it's only available insst.config.ts, useResource.*or env vars for runtime stage awareness - Trying to use SST resource linking in client-side frontend code — links are server-side only (SSR functions, API routes)
- Expecting
sst devto emulate AWS locally — it doesn't; it proxies to real AWS resources in your account
Gotchas & Edge Cases:
- Pulumi Outputs cannot be used directly in string templates — use
$concat()or$interpolateinstead of template literals sst devmultiplexer starts frontends automatically — you don't need to runnext devorvite devseparately- FIFO queues require
.fifosuffix in names — SST handles this automatically but be aware when referencing externally .envand.env.<stage>files are loaded automatically —.envtakes precedence over stage-specific files- Frontend framework links (Next.js, Remix) only work server-side — client components cannot access
Resource.* - Layers specified in Function config are not applied during
sst dev— local execution skips layers - The
removalsetting inapp()controls what happens when you runsst remove—"remove"deletes resources,"retain"keeps them,"retain-all"keeps everything including logs
</red_flags>
<critical_reminders>
CRITICAL REMINDERS
All code must follow project conventions in CLAUDE.md (kebab-case, named exports, import ordering,
import type, named constants)
(You MUST use resource linking (link + Resource.*) to connect components — NEVER hardcode ARNs, table names, or bucket names)
(You MUST use $app.stage for environment isolation — NEVER share resources across stages without explicit intent)
(You MUST use sst dev for local development — it provides live Lambda proxying with sub-10ms reloads against real AWS resources)
(You MUST use sst secret set for secrets — NEVER put secrets in sst.config.ts, .env files committed to git, or environment variables)
(You MUST use transform to customize underlying resources — NEVER reach for raw Pulumi resources when an SST component exists)
Failure to follow these rules will cause cross-stage resource conflicts, leaked secrets, broken type safety, and unnecessary infrastructure complexity.
</critical_reminders>
Frequently asked questions
What to verify before installation and use
What does the infra-iac-sst source document cover?
Quick Guide: SST v3 (Ion) is TypeScript-first infrastructure-as-code for AWS, powered by Pulumi/Terraform (not CDK/CloudFormation). Define your entire app in sst.config.ts using high-level components (sst.aws.Function, sst.aws.ApiGatewayV2, sst.aws.Bucket, sst.aws.Dynamo, etc.).…
How do I install infra-iac-sst?
The source record exposes this install command: npx skills add https://github.com/agents-inc/skills --skill "src/skills/infra-iac-sst". Inspect the command and pinned source before running it.
Which permission-related actions were detected?
Static rules flagged read-files in the source; the page lists the matching lines and excerpts.
Alternatives
Compare before choosing
vasilyu1983/AI-Agents-public
qa-testing-ios
Guides iOS testing with XCTest, XCUITest, Swift Testing, simctl, and xcresult. Use when choosing destinations, controlling flakes, or parsing test artifacts for native apps.
garrytan/gbrain
brain-pdf
Generate a publication-quality PDF from any brain page via the gstack make-pdf binary. Strips YAML frontmatter, sanitizes emoji, applies running headers and page numbers. Brain page is always the source of truth; PDF is a rendering.
NVIDIA/skills
rtvi-cv-customize-model
How to swap the DeepStream CV detection model in the VSS Alerts Blueprint verification (2d_cv) mode - covers ONNX export, custom bbox parsers, compose mount gotchas, nvinfer config, runtime TRT engine build, deployment, and a segmentation-capable model addendum handoff.
vasilyu1983/AI-Agents-public
research-git
Scans public GitHub repos for agent skills, dev practices, and code patterns. Use when enriching skills, setting team policy, or researching a build domain.