AWS Serverless Deployment
AWS LabsOfficialPublished by AWS Labs
- Skill
- Tool integration
- Cloud and DevOps
- Apache-2.0
- Low risk
AutoGineer summary
Written by AutoGineer from the skill’s own files, not by the author
This skill provides a structured approach to deploying serverless applications on AWS. It supports both AWS SAM and AWS CDK, offering guidance on project scaffolding, IaC template management, Lambda function constructs, and CI/CD pipeline integration. It includes best practices for resource configuration, environment management, and testing, while providing specific hooks for SAM template validation and automated deployment workflows.
What it does
- Provides project scaffolding for both SAM and CDK serverless applications.
- Offers guidance on using L2 CDK constructs for optimized Lambda function deployment.
- Automates SAM template validation via a post-edit hook.
- Supports multi-environment deployment strategies using configuration files.
- Facilitates the integration of CI/CD pipelines for serverless infrastructure.
- Provides reference material for SAM and CDK coexistence and migration.
When to use it
- When initializing a new serverless project on AWS.
- When you need to define Lambda functions using optimized CDK constructs like NodejsFunction.
- When you require automated validation for your SAM templates.
- When setting up infrastructure-as-code for serverless resources like DynamoDB, SQS, or API Gateway.
- When migrating or managing a project that uses both SAM and CDK.
Advantages
- Promotes the use of L2 constructs for safer, least-privilege IAM policies.
- Enables type-safe infrastructure development using TypeScript with CDK.
- Reduces manual errors through automated template validation.
- Simplifies complex resource wiring with pre-defined serverless patterns.
- Supports deterministic synthesis through cached context files.
Usage examples
- “Initialize a new serverless project using CDK with TypeScript.”
- The agent will guide you through the cdk init process, setting up the project structure with bin, lib, and test directories.
- “How do I define a Lambda function in CDK using NodejsFunction?”
- The agent will provide a code snippet demonstrating the NodejsFunction construct, including configuration for runtime, memory, and esbuild bundling.
- “Validate my current SAM template.”
- The agent will trigger the sam validate command to check your template.yaml for syntax and configuration errors.
Install
Download the skill as a ZIP:
https://autogineer.com/agent-skills/awslabs/aws-serverless-deployment/downloadUnzip it into the cross-client skills folder of your project:
mkdir -p .agents/skills && unzip aws-serverless-deployment.zip -d .agents/skills
Documentation by AWS Labs
AWS Serverless Deployment
Deploy serverless applications to AWS using SAM or CDK. This skill covers project scaffolding, IaC templates, CDK constructs and patterns, deployment workflows, CI/CD pipelines, and SAM/CDK coexistence.
For Lambda runtime behavior, event sources, orchestration, observability, and optimization, see the aws-lambda skill.
When to Load Reference Files
Load the appropriate reference file based on what the user is working on:
SAM project setup, templates, deployment workflow, local testing, or container images -> see references/sam-project-setup.md
CDK project setup, constructs, CDK testing, or CDK pipelines -> see references/cdk-project-setup.md
CDK Lambda constructs, NodejsFunction, PythonFunction, or CDK Function -> see references/cdk-lambda-constructs.md
CDK serverless patterns, API Gateway CDK, Function URL CDK, EventBridge CDK, DynamoDB CDK, or SQS CDK -> see references/cdk-serverless-patterns.md
SAM and CDK coexistence, migrating from SAM to CDK, or using sam build with CDK -> see references/sam-cdk-coexistence.md
Best Practices
SAM
Do: Use
sam_initwith an appropriate template for your use caseDo: Set global defaults for timeout, memory, runtime, and tracing in the
GlobalssectionDo: Use
samconfig.tomlenvironment-specific sections for multi-environment deploymentsDo: Use
sam build --use-containerwhen native dependencies are involvedDon't: Copy-paste templates from the internet without understanding the resource configuration
Don't: Hardcode resource ARNs or account IDs in templates — use
!Ref,!GetAtt, and!Sub
CDK
Do: Use TypeScript — type checking catches errors at synthesis time, before any AWS API calls
Do: Prefer L2 constructs and
grant*methods over L1 and raw IAM statementsDo: Separate stateful and stateless resources into different stacks; enable termination protection on stateful stacks
Do: Commit
cdk.context.jsonto version control — it caches VPC/AZ lookups for deterministic synthesisDo: Write unit tests with
aws-cdk-lib/assertions; assert logical IDs of stateful resources to detect accidental replacementsDo: Use
cdk diffin CI before every deployment to review changesDon't: Hardcode account IDs or region strings — use
this.accountandthis.regionDon't: Use
cdk deploydirectly in production without a pipelineDon't: Skip
cdk bootstrap— deployments will fail without the CDK toolkit stack
Configuration
AWS CLI Setup
This skill requires that AWS credentials are configured on the host machine:
Verify access: Run aws sts get-caller-identity to confirm credentials are valid
SAM CLI Setup
Verify: Run sam --version
Container Runtime Setup
Install a Docker compatible container runtime: Required for
sam_local_invokeand container-based buildsVerify: Use an appropriate command such as
docker --versionorfinch --version
AWS Serverless MCP Server
Write access is enabled by default. The plugin ships with --allow-write in .mcp.json, so the MCP server can create projects, generate IaC, and deploy on behalf of the user.
Access to sensitive data (like Lambda and API Gateway logs) is not enabled by default. To grant it, add --allow-sensitive-data-access to .mcp.json.
SAM Template Validation Hook
This plugin includes a PostToolUse hook that runs sam validate automatically after any edit to template.yaml or template.yml. If validation fails, the error is returned as a system message so you can fix it immediately. The hook requires SAM CLI and jq to be installed; if either is missing, validation is skipped with a system message. Users can disable it via /hooks.
Verify: Run jq --version
IaC framework selection
Default: CDK
Override syntax:
"use CloudFormation" → Generate YAML templates
"use SAM" → Generate YAML templates
When not specified, ALWAYS use CDK
Language selection for CDK
Default: TypeScript
Override syntax:
"use Python" → Generate Python code
"use JavaScript" → Generate JavaScript code
When not specified, ALWAYS use TypeScript
Error Scenarios
Serverless MCP Server Unavailable
Inform user: "AWS Serverless MCP not responding"
Ask: "Proceed without MCP support?"
DO NOT continue without user confirmation
Resources
Files
- ATTRIBUTION.mdAdded by AutoGineer936 B
- LICENSELicence file added by AutoGineer9.9 KiB
- NOTICELicence file added by AutoGineer89 B
- SKILL.md5.2 KiB
- references/cdk-lambda-constructs.md3.3 KiB
- references/cdk-project-setup.md11.4 KiB
- references/cdk-serverless-patterns.md4.4 KiB
- references/sam-cdk-coexistence.md2.7 KiB
- references/sam-project-setup.md13.0 KiB
references/sam-project-setup.md
SAM Project Setup Guide
Template Selection
Choose the right template based on your use case:
| Template | Best For |
|---|---|
hello-world | Basic Lambda function with API Gateway |
quick-start-web | Web application with frontend and backend |
quick-start-cloudformation | Infrastructure-focused templates |
quick-start-scratch | Minimal template for custom builds |
Use get_serverless_templates to browse additional templates from Serverless Land for specific patterns (e.g., API + DynamoDB, step functions, event processing).
Architecture Selection
Choose arm64 (Graviton) for better price-performance unless you have x86-specific dependencies.
Project Structure
my-serverless-app/
├── template.yaml # SAM template
├── samconfig.toml # Deployment configuration
├── src/ # Function source code
│ ├── handlers/ # Lambda function handlers
│ ├── layers/ # Shared layers
│ └── utils/ # Utility functions
├── events/ # Test event files
└── tests/ # Unit and integration testsTestability tip: Extract pure business logic (calculations, validations, decisions) into plain functions that don't import the AWS SDK. This lets you unit test core logic without mocking — reserve mocks for the handler-level tests that exercise SDK calls.
Template Configuration
Global Settings
Set global defaults in template.yaml to apply to all functions:
Globals:
Function:
Timeout: 30
MemorySize: 512
Runtime: python3.12
Tracing: Active
Environment:
Variables:
LOG_LEVEL: INFO
POWERTOOLS_SERVICE_NAME: my-serviceEnvironment Parameters
Use CloudFormation parameters to make templates environment-aware:
Parameters:
Environment:
Type: String
Default: dev
AllowedValues: [dev, staging, prod]Reference !Ref Environment in resource names and configuration to differentiate stacks.
Development Workflow
1. Initialize
Use sam_init with chosen runtime, template, and dependency manager.
2. Develop
Write handler code in src/handlers/. Create test events in events/.
3. Build
Use sam_build before every deployment. Use --use-container for consistent builds with Lambda-compatible dependencies.
4. Test Locally
Use sam_local_invoke with a test event to validate before deploying. For API-triggered functions, use sam local start-api to test with real HTTP requests (see Testing > Local Integration Testing below).
5. Deploy
Use sam_deploy with guided: true for the first deploy, which generates samconfig.toml. For subsequent deploys, sam_deploy reads from samconfig.toml.
6. Monitor
Use sam_logs to check function output. Use get_metrics to monitor health.
Deployment Strategies
Canary and Linear Deployments
For production APIs, use SAM's built-in DeploymentPreference to shift traffic gradually and automatically roll back on errors. This uses CodeDeploy and Lambda aliases under the hood.
Globals:
Function:
AutoPublishAlias: live
Resources:
MyFunction:
Type: AWS::Serverless::Function
Properties:
DeploymentPreference:
Type: Canary10Percent5Minutes # 10% for 5 min, then 100%
Alarms:
- !Ref MyFunctionErrorAlarmAvailable deployment types:
| Type | Traffic shift pattern |
|---|---|
AllAtOnce | Immediate full cutover (no safety, dev/test use) |
Canary10Percent5Minutes | 10% for 5 min, then 100% |
Canary10Percent30Minutes | 10% for 30 min, then 100% |
Linear10PercentEvery1Minute | +10% every minute |
Linear10PercentEvery10Minutes | +10% every 10 min |
Set DeploymentPreference.Alarms to a CloudWatch alarm on error rate. CodeDeploy automatically rolls back if the alarm fires during the shift window.
Lambda Layers
Layers let you share code and dependencies across functions without including them in each deployment package.
When to use layers:
Shared business logic used by multiple functions
Large dependencies (e.g., pandas, Pillow) you want to cache separately
AWS Lambda Powertools (AWS provides a managed layer ARN per runtime/region)
Add a layer in SAM template:
MyLayer:
Type: AWS::Serverless::LayerVersion
Properties:
LayerName: my-shared-utils
ContentUri: layers/shared-utils/
CompatibleRuntimes:
- python3.12
RetentionPolicy: Retain
MyFunction:
Type: AWS::Serverless::Function
Properties:
Layers:
- !Ref MyLayerLimits: Maximum 5 layers per function. Total uncompressed size of function + layers must be under 250 MB.
Container Images
Lambda supports container images up to 10 GB as a first-class deployment model alongside zip packages.
When to Use Container Images
| Criterion | Zip Package | Container Image |
|---|---|---|
| Max size | 250 MB uncompressed | 10 GB |
| Custom OS dependencies | Limited (layers) | Full control via Dockerfile |
| Existing Docker workflow | N/A | Reuse Dockerfiles and CI pipelines |
| Cold start | Faster baseline | Slower baseline, mitigated by SOCI |
| Local testing | sam local invoke | sam local invoke (Docker required either way) |
Use container images when your deployment package exceeds 250 MB (ML models, large native dependencies), you need OS-level packages not available in Lambda runtimes, or your team already has Docker build pipelines.
Dockerfile Examples
Python (multi-stage build):
FROM public.ecr.aws/lambda/python:3.12 AS builder
COPY requirements.txt .
RUN pip install --target /asset -r requirements.txt
FROM public.ecr.aws/lambda/python:3.12
COPY --from=builder /asset ${LAMBDA_TASK_ROOT}
COPY src/ ${LAMBDA_TASK_ROOT}/
CMD ["app.handler"]Node.js:
FROM public.ecr.aws/lambda/nodejs:22
COPY package.json package-lock.json ${LAMBDA_TASK_ROOT}/
RUN npm ci --omit=dev
COPY src/ ${LAMBDA_TASK_ROOT}/
CMD ["app.handler"]SAM Template Configuration
MyFunction:
Type: AWS::Serverless::Function
Properties:
PackageType: Image
Architectures: [arm64]
MemorySize: 512
Timeout: 30
Metadata:
Dockerfile: Dockerfile
DockerContext: ./src
DockerTag: latestSAM builds the image locally during sam build and pushes it to ECR during sam deploy. No manual docker push needed.
Seekable OCI (SOCI) Lazy Loading
Container images have longer cold starts than zip because Lambda must download the full image before starting. SOCI creates an index that enables lazy loading — Lambda pulls only the layers needed at startup and fetches the rest in the background. SOCI is most beneficial for images larger than 250 MB. For smaller images, the overhead of maintaining the index may not be worthwhile.
Best Practices
[ ] Use multi-stage builds to minimize final image size — install build dependencies in a builder stage, copy only artifacts to the final stage
[ ] Use AWS base images (
public.ecr.aws/lambda/*) — they include the Lambda runtime interface client[ ] Choose
arm64architecture for the same 20% cost savings as zip deployments[ ] Pin base image tags to specific versions in production (e.g.,
python:3.12.2024.11.22notpython:3.12)[ ] Create SOCI indexes for images larger than 250 MB to reduce cold starts
Configuration Management
samconfig.toml
Use environment-specific sections:
[default.deploy.parameters]
stack_name = "my-serverless-app"
region = "us-east-1"
capabilities = "CAPABILITY_IAM"
[dev.deploy.parameters]
stack_name = "my-app-dev"
parameter_overrides = "Environment=dev LogLevel=DEBUG"
[prod.deploy.parameters]
stack_name = "my-app-prod"
parameter_overrides = "Environment=prod LogLevel=WARN"Deploy to a specific environment with sam_deploy using config_env: prod.
Security
Follow least-privilege IAM: scope each function's role to only the actions and resources it needs
Use
AWSLambdaBasicExecutionRolemanaged policy for CloudWatch loggingAdd VPC configuration only when the function needs access to VPC resources (RDS, ElastiCache)
Store secrets in Secrets Manager or SSM Parameter Store
Testing
Serverless Testing Pyramid
| Level | What it tests | Speed | AWS dependency |
|---|---|---|---|
| Unit | Handler logic, business rules | Fast (ms) | None (mocked) |
| Local integration | Function + event shape | Medium (seconds) | Docker only |
| Cloud integration | Function + real AWS services | Slow (seconds-minutes) | Full |
| End-to-end | Complete request path | Slowest | Full |
Invest most effort in unit tests. Use local integration to catch event shape mismatches. Reserve cloud tests for verifying IAM, networking, and service integration behavior.
Unit Testing
Mock all AWS SDK calls. Use the Arrange-Act-Assert pattern.
Python (pytest):
from unittest.mock import MagicMock, patch
def test_get_order_returns_item():
# Arrange
mock_table = MagicMock()
mock_table.get_item.return_value = {"Item": {"orderId": "ord-1", "status": "active"}}
with patch("src.handlers.orders.table", mock_table):
from src.handlers.orders import app
event = {"httpMethod": "GET", "pathParameters": {"orderId": "ord-1"}}
# Act
result = app.resolve(event, {})
# Assert
assert result["statusCode"] == 200TypeScript (jest + aws-sdk-client-mock):
import { handler } from '../src/handlers/orders';
import { mockClient } from 'aws-sdk-client-mock';
import { DynamoDBDocumentClient, GetCommand } from '@aws-sdk/lib-dynamodb';
const ddbMock = mockClient(DynamoDBDocumentClient);
afterEach(() => ddbMock.reset());
it('should return order when it exists', async () => {
// Arrange
ddbMock.on(GetCommand).resolves({ Item: { orderId: 'ord-1', status: 'active' } });
const event = { httpMethod: 'GET', pathParameters: { orderId: 'ord-1' } } as any;
// Act
const result = await handler(event, {} as any);
// Assert
expect(result.statusCode).toBe(200);
});Local Integration Testing
# Generate a test event template
sam local generate-event s3 put --bucket my-bucket --key uploads/test.jpg > events/s3_put.json
# Invoke locally with the generated event
sam local invoke MyFunction --event events/s3_put.json
# Enable Powertools dev mode for verbose local output
sam local invoke MyFunction --event events/test.json \
--env-vars <(echo '{"MyFunction": {"POWERTOOLS_DEV": "true"}}')sam local generate-event supports all Lambda event sources (s3, sqs, sns, kinesis, dynamodb, apigateway, etc.). Use it instead of hand-crafting event JSON.
The sam local start-api subcommand runs your AWS Lambda functions locally to test through a local HTTP server host. This lets you test your APIs with real HTTP requests using curl, Postman, or your browser:
# Start local API server (default port 3000)
sam local start-api
# Test with curl
curl http://localhost:3000/hello
# Use custom port
sam local start-api --port 8080Cloud Integration Testing
Local testing cannot fully replicate IAM policies, VPC networking, or service integrations. Use cloud-based testing for these.
# Test a deployed function directly
sam remote invoke MyFunction --stack-name my-app-dev --event-file events/test.json
# Deploy an ephemeral stack for PR testing
sam deploy --config-env ci \
--parameter-overrides "Environment=pr-${PR_NUMBER}" \
--stack-name "my-app-pr-${PR_NUMBER}"
# Tear down after tests pass
aws cloudformation delete-stack --stack-name "my-app-pr-${PR_NUMBER}"Ephemeral stacks (one per PR) provide full isolation between test runs without polluting shared environments.
Testing Checklist
[ ] Mock all AWS SDK calls in unit tests — never call real AWS services
[ ] Keep test events in
events/for repeatability[ ] Use
sam local generate-eventrather than hand-crafting event JSON[ ] Set
POWERTOOLS_DEV=truelocally for verbose structured log output[ ] Run unit tests in CI on every commit; cloud integration tests on PR merge
[ ] Use ephemeral stacks for integration testing to avoid environment conflicts
Requirements and compatibility
Written for: Claude Code
Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta
“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.
Needs: Claude Code frontmatter, Needs an MCP server
Security
What our scanner noticed· Low risk
- Instructions that use the network
A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.
Attribution and licence
- Published by
- AWS Labs
- Publisher
- AWS Labs (Official)
- Source
- awslabs/agent-plugins · plugins/aws-serverless/skills/aws-serverless-deployment · commit fbefb37
- Licence
- Apache License 2.0 (redistribution allowed)
- LICENSE (added by AutoGineer from LICENSE)
- NOTICE (added by AutoGineer from NOTICE)
- ATTRIBUTION.md (written by AutoGineer)
- Synced
AutoGineer is not affiliated with or endorsed by AWS Labs or AWS Labs.
Download ZIP
The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download aws-serverless-deployment.zip