agentsclimarketplace

Infra iac sst

Skill agents-inc/skills/dist/plugins/infra-iac-sst/skills/infra-iac-sst

The official skills marketplace for Agents Inc, an agent composition framework that builds stacks and compiles specialized subagents for Claude Code

Install
npx -y skills add agents-inc/skills --skill infra-iac-sst

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 18 stars18 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

SST (Ion) infrastructure-as-code — TypeScript-first serverless on AWS with Pulumi, resource linking, and live Lambda dev

SKILL.md

17.2 KB, ~4.1k tokens by cl100k_base, as published. Nobody here has run it

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.ts using 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. Use sst dev for live Lambda development with sub-10ms reloads. Use $app.stage for multi-environment isolation. Use transform to 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.ts structure (app() + run() functions)
  • Resource linking: link property + 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.Linkable and Linkable.wrap
  • Global helpers: $app, $dev, $concat, $interpolate, $resolve, $transform

<philosophy>

Philosophy

SST v3 (Ion) replaces CDK/CloudFormation with Pulumi/Terraform for dramatically faster deployments and a simpler programming model. The core ideas:

  1. 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.
  2. 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.
  3. 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 wiring.
  4. Stage-based isolation — Every developer gets their own stage (sst dev creates a personal stack). $app.stage drives resource naming. Production uses sst deploy --stage production.
  5. Live dev against real AWSsst dev replaces 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
</philosophy>
<patterns>

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.

ComponentAWS ServiceUse Case
sst.aws.FunctionLambdaServerless functions
sst.aws.ApiGatewayV2API Gateway v2HTTP APIs with routes
sst.aws.DynamoDynamoDBNoSQL database
sst.aws.BucketS3Object storage
sst.aws.QueueSQSMessage queues
sst.aws.TopicSNSPub/sub messaging
sst.aws.CronEventBridgeScheduled tasks
sst.aws.VpcVPCNetwork isolation
sst.aws.ClusterECSContainer workloads
sst.aws.PostgresRDS PostgresRelational database
sst.aws.NextjsLambda + CloudFrontNext.js deployment
sst.aws.RemixLambda + CloudFrontRemix deployment
sst.aws.AstroLambda + CloudFrontAstro deployment
sst.aws.StaticSiteS3 + CloudFrontStatic site hosting
sst.aws.RouterCloudFrontURL 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.

</patterns>

<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.stage prefix — causes resource conflicts and accidental cross-stage access
  • Putting secrets in sst.config.ts or committed .env files instead of using sst secret set — secrets leak to version control
  • Using sst dev for 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" and protect: true for production stages — accidental sst remove deletes all data
  • Missing /// <reference path="./.sst/platform/config.d.ts" /> at top of sst.config.ts — loses type checking for $app, $transform, etc.
  • Using .env files for secrets instead of sst secret.env files aren't encrypted and must be managed manually per stage
  • Not running sst deploy after finishing sst dev session — stubs remain deployed and Lambda invocations timeout

Common Mistakes:

  • Forgetting that sst dev stubs persist after you stop the process — always redeploy or re-run sst dev
  • Using $app.stage in runtime code — it's only available in sst.config.ts, use Resource.* 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 dev to 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 $interpolate instead of template literals
  • sst dev multiplexer starts frontends automatically — you don't need to run next dev or vite dev separately
  • FIFO queues require .fifo suffix in names — SST handles this automatically but be aware when referencing externally
  • .env and .env.<stage> files are loaded automatically — .env takes 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 removal setting in app() controls what happens when you run sst 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>

What ships with it: 4 files

31.4 KB alongside SKILL.md

examples/

Keep looking

Skills are one crate of 327,132. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.