AWS SAM (Serverless Application Model)
Guia de uso do AWS SAM para desenvolvimento e deploy serverless.
O que é SAM?
AWS SAM é um framework open-source para construir aplicações serverless na AWS.
Benefícios: - Templates CloudFormation simplificados - Local testing e debugging - Deploy simplificado - Built-in best practices
Instalação
Template SAM
template.yaml:
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: People Tech App
Globals:
Function:
Timeout: 30
Runtime: python3.11
MemorySize: 512
Environment:
Variables:
ENVIRONMENT: !Ref Environment
LOG_LEVEL: INFO
Parameters:
Environment:
Type: String
AllowedValues: [staging, production]
Description: Environment name
Resources:
# API Gateway
AppApi:
Type: AWS::Serverless::Api
Properties:
StageName: !Ref Environment
Cors:
AllowOrigin: "'*'"
AllowHeaders: "'*'"
AllowMethods: "'GET,POST,PUT,DELETE,OPTIONS'"
# Lambda Function
UserFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: src/
Handler: app.users.lambda_handler
Events:
GetUsers:
Type: Api
Properties:
RestApiId: !Ref AppApi
Path: /users
Method: GET
CreateUser:
Type: Api
Properties:
RestApiId: !Ref AppApi
Path: /users
Method: POST
Policies:
- AWSSecretsManagerGetSecretValuePolicy:
SecretArn: !Ref DatabaseSecret
- DynamoDBCrudPolicy:
TableName: !Ref UsersTable
Environment:
Variables:
DATABASE_SECRET_ARN: !Ref DatabaseSecret
USERS_TABLE: !Ref UsersTable
# SQS Queue
UserEventsQueue:
Type: AWS::SQS::Queue
Properties:
QueueName: !Sub '${AWS::StackName}-user-events'
VisibilityTimeout: 300
MessageRetentionPeriod: 345600 # 4 days
RedrivePolicy:
deadLetterTargetArn: !GetAtt UserEventsDLQ.Arn
maxReceiveCount: 3
UserEventsDLQ:
Type: AWS::SQS::Queue
Properties:
QueueName: !Sub '${AWS::StackName}-user-events-dlq'
# Event Processor Lambda
EventProcessor:
Type: AWS::Serverless::Function
Properties:
CodeUri: src/
Handler: app.workers.event_processor
Events:
SQSEvent:
Type: SQS
Properties:
Queue: !GetAtt UserEventsQueue.Arn
BatchSize: 10
# SNS Topic
ProductUpdatesTopic:
Type: AWS::SNS::Topic
Properties:
DisplayName: Product Updates
Subscriptions:
- Endpoint: !GetAtt EmailSender.Arn
Protocol: lambda
# Database Secret
DatabaseSecret:
Type: AWS::SecretsManager::Secret
Properties:
Name: !Sub '/${AWS::StackName}/database'
SecretString: !Sub |
{
"username": "app_user",
"password": "${DatabasePassword}",
"host": "${DatabaseHost}",
"port": 5432,
"database": "app_db"
}
Outputs:
ApiUrl:
Description: API Gateway URL
Value: !Sub 'https://${AppApi}.execute-api.${AWS::Region}.amazonaws.com/${Environment}/'
Export:
Name: !Sub '${AWS::StackName}-ApiUrl'
QueueUrl:
Description: SQS Queue URL
Value: !Ref UserEventsQueue
Configuração
samconfig.toml:
version = 0.1
[default.global.parameters]
stack_name = "people-tech-app"
[default.build.parameters]
cached = true
parallel = true
[default.deploy.parameters]
capabilities = "CAPABILITY_IAM"
confirm_changeset = true
resolve_s3 = true
region = "us-east-1"
[staging]
[staging.deploy.parameters]
stack_name = "people-tech-app-staging"
parameter_overrides = "Environment=staging"
[production]
[production.deploy.parameters]
stack_name = "people-tech-app-production"
parameter_overrides = "Environment=production"
Comandos
Build
# Build application
sam build
# Build com Docker (recomendado)
sam build --use-container
# Build função específica
sam build UserFunction
Local Testing
# Iniciar API local
sam local start-api
# Invocar função
sam local invoke UserFunction -e events/user-created.json
# Start Lambda local
sam local start-lambda
Deploy
# Deploy para staging
sam deploy --config-env staging
# Deploy para production
sam deploy --config-env production
# Deploy com confirmação
sam deploy --guided
# Deploy forçando upload
sam deploy --config-env production --force-upload
Logs
# Tail logs de função
sam logs -n UserFunction --tail
# Logs com filtro
sam logs -n UserFunction --filter "ERROR"
Sync (Hot reload)
Layers
Para compartilhar código entre Lambdas:
Resources:
SharedLayer:
Type: AWS::Serverless::LayerVersion
Properties:
LayerName: shared-dependencies
ContentUri: layers/shared/
CompatibleRuntimes:
- python3.11
Metadata:
BuildMethod: python3.11
UserFunction:
Type: AWS::Serverless::Function
Properties:
Layers:
- !Ref SharedLayer
Environment Variables
Globals:
Function:
Environment:
Variables:
ENVIRONMENT: !Ref Environment
LOG_LEVEL: INFO
# Resolve from SSM
API_ENDPOINT: '{{resolve:ssm:/app/api-endpoint}}'
# Resolve from Secrets Manager
DB_PASSWORD: '{{resolve:secretsmanager:db-secret:SecretString:password}}'
Best Practices
✅ Fazer
- Usar
sam build --use-container(consistência) - Versioning de Layers
- Separate resources per environment (staging/prod stacks)
- Use
samconfig.toml(não hardcode params) - Tags para todos os resources
❌ Evitar
- Hardcode values no template
- Deployar sem build
- Usar
sam deploy --guidedno CI (use config file) - Secrets em plaintext
Troubleshooting
Build failed
Deploy failed
# Ver changesets
aws cloudformation describe-change-set \
--stack-name people-tech-app-staging \
--change-set-name <changeset-id>
# Rollback
sam delete --stack-name people-tech-app-staging