Actionable rules for designing, deploying, and operating serverless applications with safe, automated strategies.
Your serverless functions are running. Your team is shipping fast. But every deployment feels like rolling dice—will this break production? Will that rollback work? Are you really ready to scale when traffic spikes?
You've probably been here: a Lambda deployment goes sideways at 2 AM, your API Gateway is throwing 500s, and you're frantically trying to roll back while your monitoring dashboard lights up red. Or maybe you're still clicking through the AWS console to deploy functions manually, knowing full well that the next person on your team won't follow the same steps.
The core problems killing serverless productivity:
These aren't just inconveniences—they're productivity destroyers that turn your serverless advantage into a maintenance nightmare.
These Cursor Rules implement a complete deployment strategy that eliminates manual processes, provides instant rollback capabilities, and gives you full visibility into every deployment. You'll move from hoping deployments work to knowing they will.
What you get:
From code commit to production deployment in under 10 minutes with fully automated CI/CD pipelines. No manual approval gates blocking your flow.
Canary deployments catch issues before they impact users. Automatic rollbacks prevent outages from lasting more than 5 minutes.
Every Lambda invocation includes structured logs with trace IDs. Find the root cause of any issue in seconds, not hours.
Infrastructure-as-Code means your staging environment matches production exactly. No more "works on my machine" deployment surprises.
# The old way - hope and pray
$ zip -r function.zip src/
$ aws lambda update-function-code --function-name my-function --zip-file fileb://function.zip
$ aws lambda update-alias --function-name my-function --name live --function-version $LATEST
# Cross fingers, check CloudWatch logs, panic when errors appear
// Your CDK stack with built-in safety
const chargeCard = new NodejsFunction(this, 'ChargeCardFn', {
entry: '../src/handlers/charge-card.ts',
memorySize: 256,
tracing: Tracing.ACTIVE,
insightsVersion: LambdaInsightsVersion.VERSION_1_0_119_0,
});
// Automatic canary deployment
new CfnDeploymentPreference(this, 'ChargeCardPreference', {
alias: chargeCard.currentVersion.addAlias('live'),
type: 'Canary10Percent5Minutes',
});
# One command deploys safely
$ npm run deploy:prod
# Automatic: build → test → deploy 10% → monitor → rollout 100%
Old way: Notice errors in monitoring → check logs → identify bad deployment → manually revert → verify fix (30+ minutes)
New way: Automatic rollback triggers on error threshold → notification sent → verified within 5 minutes
Before: Each environment deployed differently, configuration scattered across multiple places
After: Single source of truth with environment-specific overrides:
// One codebase, multiple environments
const config = {
dev: { memorySize: 128, timeout: 30 },
staging: { memorySize: 256, timeout: 60 },
prod: { memorySize: 512, timeout: 120, provisionedConcurrency: 10 }
};
.cursorrules fileFor AWS-native projects:
# CDK setup
npm install -g aws-cdk
cdk init app --language typescript
For multi-cloud flexibility:
# Terraform setup
terraform init
terraform workspace new staging
terraform workspace new production
The rules include complete GitHub Actions workflows:
# .github/workflows/deploy-prod.yml
name: Deploy to Production
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- run: npm ci
- run: npm run lint
- run: npm run test -- --coverage
- run: npm run deploy:prod
// Built into every handler
export const handler: APIGatewayProxyHandlerV2 = async (event) => {
const traceId = context.awsRequestId;
logger.info('Processing request', {
traceId,
path: event.rawPath,
method: event.requestContext.http.method
});
// Your business logic here
};
Your serverless applications will deploy confidently, scale automatically, and recover instantly. You'll spend time building features instead of fixing deployment disasters.
The rules handle the complexity—you focus on the code that matters.
You are an expert in Serverless, AWS Lambda, AWS CDK (TypeScript), AWS SAM, Serverless Framework, Terraform, GitHub Actions, AWS CodePipeline, CloudWatch, Datadog.
Key Principles
- Infrastructure-as-Code (IaC) for everything. Never create cloud resources manually.
- Immutable, automated, and idempotent deployments via CI/CD.
- Favor small, single-purpose functions that can be deployed independently.
- Use event-driven, microservice architecture; every Lambda owns its data and responsibilities.
- Fail fast and rollback fast: implement canary and blue-green strategies by default.
- Security first: least-privilege IAM, encrypted secrets, static analysis in pipelines.
- Observability is mandatory: structured logs, metrics, distributed tracing shipped on every invocation.
- Consistent naming: <service>-<stage>-<module>-<function> (e.g., billing-prod-payments-chargeCard).
TypeScript (Function & IaC Code)
- Use `async`/`await`; never mix with `.then()` chains.
- Export a single `handler` per file: `export const handler: APIGatewayProxyHandlerV2 = async (event) => { … }`.
- Keep business logic pure; isolate AWS SDK calls in adapters.
- Directory convention:
- `/src/handlers` ➜ Lambda entry points
- `/src/lib` ➜ pure domain logic
- `/infra` ➜ CDK/SAM/Terraform code
- `/tests` ➜ unit & integration tests
- Enable `esbuild` or `swc` for CDK bundling; target `nodejs18.x`.
- ESLint rules:
- `@typescript-eslint/strict-boolean-expressions: error`
- `no-floating-promises: error` (via `eslint-plugin-promise`)
- Always type AWS events (`APIGatewayProxyEventV2`, `SQSEvent`, etc.) and API responses.
- Use environment variables ONLY for non-secret configuration; fetch secrets at start-up from AWS Secrets Manager.
Error Handling & Validation
- Validate all inbound events with `zod` schemas; throw `BadRequestError` when invalid.
- Wrap AWS SDK calls in `try/catch`; attach `context.awsRequestId` to error logs.
- Early-return on known error states; avoid nested `if`.
- Use a centralized middleware (e.g., `@middy/core`) to translate thrown errors into structured JSON responses.
- Emit `metric` logs (`MONITORING|<value>|<unit>|<name>|#<dimensions>`) so CloudWatch Embedded Metric Format (EMF) picks them up.
AWS CDK Rules
- One stack per bounded context; do not exceed 200 resources per stack.
- Use explicit logical IDs with `this.node.setLogicalId()` for critical resources to avoid replacement.
- Define Lambda like:
```ts
const chargeCard = new NodejsFunction(this, 'ChargeCardFn', {
entry: '../src/handlers/charge-card.ts',
memorySize: 256,
environment: {
TABLE_NAME: paymentsTable.tableName,
},
tracing: Tracing.ACTIVE,
insightsVersion: LambdaInsightsVersion.VERSION_1_0_119_0,
});
```
- Add `CfnDeploymentPreference` for gradual rollout:
```ts
new CfnDeploymentPreference(this, 'ChargeCardPreference', {
alias: chargeCard.currentVersion.addAlias('live'),
type: 'Canary10Percent5Minutes',
});
```
AWS SAM Rules
- Organize template with nested stacks: `/template.yaml` imports `template-functions.yaml`, `template-database.yaml`.
- Enable safe deployments:
```yaml
AutoPublishAlias: live
DeploymentPreference:
Type: Linear10PercentEvery2Minutes
```
- Use `sam build --use-container` to align with Lambda runtime.
Serverless Framework Rules (serverless.yml)
- File structure: `serverless.<stage>.yml` merged via `serverless.yml`.
- Default to canary deployments: `deploymentSettings:` block with 10% for 5 min.
- Enable `serverless-domain-manager` for custom domains.
- Use `serverless-iam-roles-per-function` to scope permissions per handler.
Terraform Rules
- Keep providers locked: `required_version = ">= 1.4"`.
- Use `for_each` to create identical functions for multiple stages.
- Store state in an encrypted S3 bucket with DynamoDB state locking.
- Use `terraform validate`, `tfsec`, and `tflint` in CI.
CI/CD (GitHub Actions example)
- Workflow per environment (`prd.yml`, `stg.yml`) triggered on `push` to branch.
- Jobs: `lint → test → build → sam/cdk/terraform deploy`.
- Require manual approval before production deployment via `environment` protection rules.
- Fail build if code coverage < 80%.
Testing
- Unit test pure logic with `vitest`.
- Integration tests spin up `localstack` in CI; verify Lambda can read/write to DynamoDB.
- End-to-end tests run against a deployed staging stack using `aws-sdk` to invoke APIs.
- Load test with `k6` to measure cold start vs warm performance.
Performance & Cold Starts
- Prefer `nodejs18.x` runtime for faster cold starts.
- Keep packages < 10 MB zipped; bundle with `esbuild` and `external: ['aws-sdk']`.
- Enable Provisioned Concurrency only for latency-critical paths; monitor cost impact.
- Use Lambda Power Tuning to find optimal memory vs duration.
Security Rules
- IAM least privilege: generate function policy with `cdk-iam-floyd` or `terraform-aws-iam`.
- Store all secrets in AWS Secrets Manager; rotate automatically.
- Enforce HTTPS everywhere; use AWS WAF on API Gateway.
- Run `npm audit`, `bandit` (for Python functions) in CI.
- Enable AWS GuardDuty, Config rules for drift detection.
Logging & Observability
- Structured logs: `JSON.stringify({ msg, level, requestId, ... })`.
- Enable Lambda Insights for metrics.
- Trace everything: AWS X-Ray or Datadog APM; propagate `trace_id` across SNS/SQS.
- Dashboards: 95th latency, error %, invocations, throttle %, provisioned vs utilized concurrency.
Deployment Strategies
- Canary (default): 10 % traffic, 5 min bake, auto-rollback on 5xx > 1 %.
- Blue-green: full production clone (`prod-blue`), swap DNS in Route 53.
- Feature flags for selective enablement (e.g., LaunchDarkly).
- Rollback command: `aws lambda update-alias --function-name fn --name live --function-version $PREV`.
Common Pitfalls & Guards
- ❌ Uploading monolithic 200 MB Lambda zips → ✅ prune deps, use layers.
- ❌ Using `*` in IAM policies → ✅ scope to specific ARNs.
- ❌ Hard-coding ARNs in code → ✅ read from env or stack outputs.
- ❌ Skipping DLQs → ✅ attach SQS DLQ or Step Function retry.