Specialized skill for building production-ready serverless applications on AWS. Covers Lambda functions, API Gateway, DynamoDB, SQS/SNS event-driven patterns, SAM/CDK deployment, and cold start optimization.
Add this skill
npx mdskills install sickn33/aws-serverlessComprehensive serverless patterns with strong code examples but appears truncated in key sections
1---2name: aws-serverless3description: "Specialized skill for building production-ready serverless applications on AWS. Covers Lambda functions, API Gateway, DynamoDB, SQS/SNS event-driven patterns, SAM/CDK deployment, and cold start optimization."4source: vibeship-spawner-skills (Apache 2.0)5---67# AWS Serverless89## Patterns1011### Lambda Handler Pattern1213Proper Lambda function structure with error handling1415**When to use**: ['Any Lambda function implementation', 'API handlers, event processors, scheduled tasks']1617```python18```javascript19// Node.js Lambda Handler20// handler.js2122// Initialize outside handler (reused across invocations)23const { DynamoDBClient } = require('@aws-sdk/client-dynamodb');24const { DynamoDBDocumentClient, GetCommand } = require('@aws-sdk/lib-dynamodb');2526const client = new DynamoDBClient({});27const docClient = DynamoDBDocumentClient.from(client);2829// Handler function30exports.handler = async (event, context) => {31 // Optional: Don't wait for event loop to clear (Node.js)32 context.callbackWaitsForEmptyEventLoop = false;3334 try {35 // Parse input based on event source36 const body = typeof event.body === 'string'37 ? JSON.parse(event.body)38 : event.body;3940 // Business logic41 const result = await processRequest(body);4243 // Return API Gateway compatible response44 return {45 statusCode: 200,46 headers: {47 'Content-Type': 'application/json',48 'Access-Control-Allow-Origin': '*'49 },50 body: JSON.stringify(result)51 };52 } catch (error) {53 console.error('Error:', JSON.stringify({54 error: error.message,55 stack: error.stack,56 requestId: context.awsRequestId57 }));5859 return {60 statusCode: error.statusCode || 500,61 headers: { 'Content-Type': 'application/json' },62 body: JSON.stringify({63 error: error.message || 'Internal server error'64 })65 };66 }67};6869async function processRequest(data) {70 // Your business logic here71 const result = await docClient.send(new GetCommand({72 TableName: process.env.TABLE_NAME,73 Key: { id: data.id }74 }));75 return result.Item;76}77```7879```python80# Python Lambda Handler81# handler.py8283import json84import os85import logging86import boto387from botocore.exceptions import ClientError8889# Initialize outside handler (reused across invocations)90logger = logging.getLogger()91logger.setLevel(logging.INFO)9293dynamodb = boto3.resource('dynamodb')94table = dynamodb.Table(os.environ['TABLE_NAME'])9596def handler(event, context):97 try:98 # Parse i99```100101### API Gateway Integration Pattern102103REST API and HTTP API integration with Lambda104105**When to use**: ['Building REST APIs backed by Lambda', 'Need HTTP endpoints for functions']106107```javascript108```yaml109# template.yaml (SAM)110AWSTemplateFormatVersion: '2010-09-09'111Transform: AWS::Serverless-2016-10-31112113Globals:114 Function:115 Runtime: nodejs20.x116 Timeout: 30117 MemorySize: 256118 Environment:119 Variables:120 TABLE_NAME: !Ref ItemsTable121122Resources:123 # HTTP API (recommended for simple use cases)124 HttpApi:125 Type: AWS::Serverless::HttpApi126 Properties:127 StageName: prod128 CorsConfiguration:129 AllowOrigins:130 - "*"131 AllowMethods:132 - GET133 - POST134 - DELETE135 AllowHeaders:136 - "*"137138 # Lambda Functions139 GetItemFunction:140 Type: AWS::Serverless::Function141 Properties:142 Handler: src/handlers/get.handler143 Events:144 GetItem:145 Type: HttpApi146 Properties:147 ApiId: !Ref HttpApi148 Path: /items/{id}149 Method: GET150 Policies:151 - DynamoDBReadPolicy:152 TableName: !Ref ItemsTable153154 CreateItemFunction:155 Type: AWS::Serverless::Function156 Properties:157 Handler: src/handlers/create.handler158 Events:159 CreateItem:160 Type: HttpApi161 Properties:162 ApiId: !Ref HttpApi163 Path: /items164 Method: POST165 Policies:166 - DynamoDBCrudPolicy:167 TableName: !Ref ItemsTable168169 # DynamoDB Table170 ItemsTable:171 Type: AWS::DynamoDB::Table172 Properties:173 AttributeDefinitions:174 - AttributeName: id175 AttributeType: S176 KeySchema:177 - AttributeName: id178 KeyType: HASH179 BillingMode: PAY_PER_REQUEST180181Outputs:182 ApiUrl:183 Value: !Sub "https://${HttpApi}.execute-api.${AWS::Region}.amazonaws.com/prod"184```185186```javascript187// src/handlers/get.js188const { getItem } = require('../lib/dynamodb');189190exports.handler = async (event) => {191 const id = event.pathParameters?.id;192193 if (!id) {194 return {195 statusCode: 400,196 body: JSON.stringify({ error: 'Missing id parameter' })197 };198 }199200 const item =201```202203### Event-Driven SQS Pattern204205Lambda triggered by SQS for reliable async processing206207**When to use**: ['Decoupled, asynchronous processing', 'Need retry logic and DLQ', 'Processing messages in batches']208209```python210```yaml211# template.yaml212Resources:213 ProcessorFunction:214 Type: AWS::Serverless::Function215 Properties:216 Handler: src/handlers/processor.handler217 Events:218 SQSEvent:219 Type: SQS220 Properties:221 Queue: !GetAtt ProcessingQueue.Arn222 BatchSize: 10223 FunctionResponseTypes:224 - ReportBatchItemFailures # Partial batch failure handling225226 ProcessingQueue:227 Type: AWS::SQS::Queue228 Properties:229 VisibilityTimeout: 180 # 6x Lambda timeout230 RedrivePolicy:231 deadLetterTargetArn: !GetAtt DeadLetterQueue.Arn232 maxReceiveCount: 3233234 DeadLetterQueue:235 Type: AWS::SQS::Queue236 Properties:237 MessageRetentionPeriod: 1209600 # 14 days238```239240```javascript241// src/handlers/processor.js242exports.handler = async (event) => {243 const batchItemFailures = [];244245 for (const record of event.Records) {246 try {247 const body = JSON.parse(record.body);248 await processMessage(body);249 } catch (error) {250 console.error(`Failed to process message ${record.messageId}:`, error);251 // Report this item as failed (will be retried)252 batchItemFailures.push({253 itemIdentifier: record.messageId254 });255 }256 }257258 // Return failed items for retry259 return { batchItemFailures };260};261262async function processMessage(message) {263 // Your processing logic264 console.log('Processing:', message);265266 // Simulate work267 await saveToDatabase(message);268}269```270271```python272# Python version273import json274import logging275276logger = logging.getLogger()277278def handler(event, context):279 batch_item_failures = []280281 for record in event['Records']:282 try:283 body = json.loads(record['body'])284 process_message(body)285 except Exception as e:286 logger.error(f"Failed to process {record['messageId']}: {e}")287 batch_item_failures.append({288 'itemIdentifier': record['messageId']289 })290291 return {'batchItemFailures': batch_ite292```293294## Anti-Patterns295296### ❌ Monolithic Lambda297298**Why bad**: Large deployment packages cause slow cold starts.299Hard to scale individual operations.300Updates affect entire system.301302### ❌ Large Dependencies303304**Why bad**: Increases deployment package size.305Slows down cold starts significantly.306Most of SDK/library may be unused.307308### ❌ Synchronous Calls in VPC309310**Why bad**: VPC-attached Lambdas have ENI setup overhead.311Blocking DNS lookups or connections worsen cold starts.312313## ⚠️ Sharp Edges314315| Issue | Severity | Solution |316|-------|----------|----------|317| Issue | high | ## Measure your INIT phase |318| Issue | high | ## Set appropriate timeout |319| Issue | high | ## Increase memory allocation |320| Issue | medium | ## Verify VPC configuration |321| Issue | medium | ## Tell Lambda not to wait for event loop |322| Issue | medium | ## For large file uploads |323| Issue | high | ## Use different buckets/prefixes |324
Full transparency — inspect the skill content before installing.