AWS for DevOps — SAM: Serverless Application Model
9.4 — SAM: Serverless Application Model
AWS SAM is a framework for building serverless applications. It extends CloudFormation with simplified syntax for Lambda, API Gateway, DynamoDB, and more.
SAM vs Raw CloudFormation
| Raw CloudFormation | SAM |
|---|---|
| 50+ lines for one Lambda function | 10 lines |
| Manually wire API Gateway + Lambda + permissions | Automatic with Events property |
| No local testing | sam local invoke, sam local start-api |
Installation
# macOS
$ brew install aws-sam-cli
# Verify
$ sam --version
SAM CLI, version 1.120.0
SAM Template
template.yaml:
AWSTemplateFormatVersion: "2010-09-09"
Transform: AWS::Serverless-2016-10-31
Description: "My Serverless API"
Globals:
Function:
Runtime: python3.12
Timeout: 30
MemorySize: 256
Environment:
Variables:
TABLE_NAME: !Ref DeploymentsTable
Resources:
HelloFunction:
Type: AWS::Serverless::Function
Properties:
Handler: app.lambda_handler
CodeUri: src/hello/
Events:
HelloApi:
Type: HttpApi
Properties:
Path: /hello
Method: get
CreateDeploymentFunction:
Type: AWS::Serverless::Function
Properties:
Handler: app.lambda_handler
CodeUri: src/create-deployment/
Policies:
- DynamoDBCrudPolicy:
TableName: !Ref DeploymentsTable
Events:
CreateApi:
Type: HttpApi
Properties:
Path: /deployments
Method: post
DeploymentsTable:
Type: AWS::Serverless::SimpleTable
Properties:
PrimaryKey:
Name: DeploymentId
Type: String
Outputs:
ApiUrl:
Value: !Sub "https://${ServerlessHttpApi}.execute-api.${AWS::Region}.amazonaws.com"
Project Structure
my-serverless-app/
├── template.yaml ← SAM template
├── samconfig.toml ← Deploy configuration
├── src/
│ ├── hello/
│ │ ├── app.py ← Lambda handler
│ │ └── requirements.txt
│ └── create-deployment/
│ ├── app.py
│ └── requirements.txt
└── tests/
└── test_hello.py
SAM Workflow
# 1. Build (installs dependencies, packages code)
$ sam build
Building codeuri: src/hello/ runtime: python3.12
Build Succeeded
# 2. Local testing
$ sam local invoke HelloFunction --event events/hello.json
{"statusCode": 200, "body": "{\"message\": \"Hello, World!\"}"}
# Start a local API (mimics API Gateway)
$ sam local start-api
Mounting HelloFunction at http://127.0.0.1:3000/hello [GET]
$ curl http://localhost:3000/hello
# 3. Deploy (guided for first time)
$ sam deploy --guided
Setting default arguments for 'sam deploy'
Stack Name: my-serverless-app
AWS Region: ap-south-1
Confirm changes before deploy: yes
Allow SAM CLI IAM role creation: yes
# Subsequent deploys
$ sam deploy
SAM Resource Types
| SAM Resource | Equivalent CloudFormation | Simplified? |
|---|---|---|
AWS::Serverless::Function |
Lambda + IAM Role + permissions | Much simpler |
AWS::Serverless::HttpApi |
API Gateway HTTP API | Auto-created from Events |
AWS::Serverless::Api |
API Gateway REST API | Auto-created from Events |
AWS::Serverless::SimpleTable |
DynamoDB table | One-line table |
SAM Policy Templates
Instead of writing full IAM policies, use SAM’s shorthand:
Policies:
- DynamoDBCrudPolicy:
TableName: !Ref MyTable
- S3ReadPolicy:
BucketName: !Ref MyBucket
- SQSPollerPolicy:
QueueName: !GetAtt MyQueue.QueueName
samconfig.toml
Save deploy settings so you don’t re-type them:
version = 0.1
[default.deploy.parameters]
stack_name = "my-serverless-app"
region = "ap-south-1"
resolve_s3 = true
capabilities = "CAPABILITY_IAM"
confirm_changeset = true
Common Mistakes
| Mistake | Why It Hurts | Fix |
|---|---|---|
Not running sam build before deploy |
Old code gets deployed | Always build before deploy |
Missing Transform line |
SAM resources not recognized | Include Transform: AWS::Serverless-2016-10-31 |
| Not using SAM policy templates | Verbose IAM policies, over-permissioned | Use built-in policy templates |
| Skipping local testing | Bugs found only after deployment | Use sam local invoke and sam local start-api |
Quick Reference
| Task | Command |
|---|---|
| Init project | sam init |
| Build | sam build |
| Local invoke | sam local invoke FunctionName --event event.json |
| Local API | sam local start-api |
| Deploy (first time) | sam deploy --guided |
| Deploy (subsequent) | sam deploy |
| View logs | sam logs -n FunctionName --stack-name STACK --tail |
| Delete | sam delete --stack-name STACK |
Next → Event-Driven Architecture