<h2>Entendendo Serverless Framework vs AWS SAM</h2>
<p>Serverless Framework e AWS SAM (Serverless Application Model) são ferramentas complementares para deploy de funções Lambda na AWS. O Serverless Framework é agnóstico a provedores, permitindo trabalhar com AWS, Google Cloud e Azure. AWS SAM é nativo da AWS, integrado ao CloudFormation, oferecendo sintaxe YAML otimizada para serverless. Escolha o Serverless Framework se precisa de multi-cloud; escolha SAM se quer máxima integração com o ecossistema AWS.</p>
<p>A diferença prática está na configuração. SAM usa <code>template.yaml</code> mais enxuto e CloudFormation nativo, enquanto Serverless Framework usa <code>serverless.yml</code> com abstração maior. Ambas resolvem o mesmo problema: transformar seu código em infraestrutura pronta para produção. Neste guia, abordaremos ambas as abordagens com exemplos reais.</p>
<h2>Primeiros Passos: Setup e Configuração Inicial</h2>
<h3>Instalação e Configuração do Serverless Framework</h3>
<p>Comece instalando o Serverless Framework globalmente via npm:</p>
<pre><code class="language-bash">npm install -g serverless
serverless --version</code></pre>
<p>Configure suas credenciais AWS criando um usuário IAM com permissões programáticas (acesso a Lambda, API Gateway, CloudFormation, S3, CloudWatch). Depois configure localmente:</p>
<pre><code class="language-bash">serverless config credentials --provider aws --key SUA_ACCESS_KEY --secret SUA_SECRET_KEY --region us-east-1</code></pre>
<p>Crie seu primeiro projeto:</p>
<pre><code class="language-bash">serverless create --template aws-nodejs-http-api --path meu-projeto
cd meu-projeto
npm install</code></pre>
<h3>Instalação e Configuração do AWS SAM</h3>
<p>Instale o AWS SAM CLI:</p>
<pre><code class="language-bash"># macOS com Homebrew
brew tap aws/tap
brew install aws-sam-cli
Windows ou Linux, consulte: https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html
sam --version</code></pre>
<p>Crie um projeto SAM:</p>
<pre><code class="language-bash">sam init --runtime python3.11 --dependency-manager pip --app-template hello-world
cd sam-app</code></pre>
<p>Ambas as ferramentas criam estruturas similares com função Lambda pronta. A diferença está no formato de configuração: <code>serverless.yml</code> vs <code>template.yaml</code>.</p>
<h2>Deployment Prático: Serverless Framework</h2>
<h3>Estrutura e Configuração</h3>
<p>Crie seu <code>serverless.yml</code>:</p>
<pre><code class="language-yaml">service: meu-servico-lambda
provider:
name: aws
region: us-east-1
runtime: nodejs18.x
environment:
TABELA_DINAMODB: users
functions:
obterUsuario:
handler: src/handlers/getUser.handler
events:
- http:
path: usuarios/{id}
method: get
cors: true
environment:
USUARIO_TABLE: ${self:provider.environment.TABELA_DINAMODB}
criarUsuario:
handler: src/handlers/createUser.handler
events:
- http:
path: usuarios
method: post
cors: true
plugins:
- serverless-plugin-tracing
- serverless-offline</code></pre>
<h3>Handler Funcional</h3>
<p>Crie <code>src/handlers/getUser.js</code>:</p>
<pre><code class="language-javascript">const AWS = require('aws-sdk');
const dynamodb = new AWS.DynamoDB.DocumentClient();
module.exports.handler = async (event) => {
const { id } = event.pathParameters;
try {
const result = await dynamodb.get({
TableName: process.env.USUARIO_TABLE,
Key: { id }
}).promise();
return {
statusCode: 200,
body: JSON.stringify(result.Item || { erro: 'Usuário não encontrado' })
};
} catch (error) {
console.error('Erro:', error);
return {
statusCode: 500,
body: JSON.stringify({ erro: 'Erro interno do servidor' })
};
}
};</code></pre>
<p>Deploy com um comando:</p>
<pre><code class="language-bash">serverless deploy --stage prod --region us-east-1
serverless logs -f obterUsuario --stage prod</code></pre>
<h2>Deployment Prático: AWS SAM</h2>
<h3>Template SAM Completo</h3>
<p>Crie seu <code>template.yaml</code>:</p>
<pre><code class="language-yaml">AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Globals:
Function:
Timeout: 20
Runtime: python3.11
Environment:
Variables:
TABELA_USUARIOS: !Ref TabelaUsuarios
Resources:
TabelaUsuarios:
Type: AWS::DynamoDB::Table
Properties:
TableName: usuarios-prod
BillingMode: PAY_PER_REQUEST
AttributeDefinitions:
- AttributeName: id
AttributeType: S
KeySchema:
- AttributeName: id
KeyType: HASH
FuncaoObterUsuario:
Type: AWS::Serverless::Function
Properties:
FunctionName: obter-usuario
CodeUri: src/handlers/
Handler: get_user.lambda_handler
Policies:
- DynamoDBCrudPolicy:
TableName: !Ref TabelaUsuarios
Events:
GetUser:
Type: Api
Properties:
RestApiId: !Ref MinhaAPI
Path: /usuarios/{id}
Method: GET
MinhaAPI:
Type: AWS::Serverless::Api
Properties:
StageName: prod
Cors:
AllowMethods: "'GET,POST,PUT,DELETE'"
AllowHeaders: "'Content-Type'"
Outputs:
APIEndpoint:
Value: !Sub 'https://${MinhaAPI}.execute-api.${AWS::Region}.amazonaws.com/prod'</code></pre>
<h3>Handler Python para SAM</h3>
<p>Crie <code>src/handlers/get_user.py</code>:</p>
<pre><code class="language-python">import json
import boto3
import os
dynamodb = boto3.resource('dynamodb')
tabela = dynamodb.Table(os.environ['TABELA_USUARIOS'])
def lambda_handler(event, context):
usuario_id = event['pathParameters']['id']
try:
resposta = tabela.get_item(Key={'id': usuario_id})
if 'Item' not in resposta:
return {
'statusCode': 404,
'body': json.dumps({'erro': 'Usuário não encontrado'})
}
return {
'statusCode': 200,
'body': json.dumps(resposta['Item'])
}
except Exception as e:
print(f"Erro: {e}")
return {
'statusCode': 500,
'body': json.dumps({'erro': 'Erro interno'})
}</code></pre>
<p>Deploy:</p>
<pre><code class="language-bash">sam build
sam deploy --guided # Primeira vez
sam deploy # Próximas vezes
sam logs -n FuncaoObterUsuario --stack-name sam-app</code></pre>
<h2>Técnicas Avançadas e Boas Práticas</h2>
<p>Tanto em Serverless Framework quanto em SAM, implemente observabilidade nativa. Use X-Ray para tracing distribuído adicionando <code>tracing_config: Active</code> (Serverless) ou <code>Tracing: Active</code> (SAM). Estruture código em camadas: handlers (entrada), business logic (regras) e data access (persistência).</p>
<p>Gerencie secrets com AWS Secrets Manager e não hardcode credenciais. Otimize tempo de cold start usando Node.js/Python em vez de Java, e considere provisioned concurrency para endpoints críticos. Implemente versionamento de função com <code>--function-version</code> no Serverless Framework ou <code>AutoPublishAlias</code> no SAM. Use variáveis de ambiente diferentes por stage (<code>prod</code>, <code>dev</code>, <code>staging</code>) para segregar recursos.</p>
<h2>Conclusão</h2>
<p>Tanto Serverless Framework quanto AWS SAM eliminam complexidade operacional de Lambda. Serverless Framework destaca-se em flexibilidade e multi-cloud; SAM brilha em integração profunda com AWS e CloudFormation. A escolha depende da estratégia: para projetos AWS puro, SAM é ideal; para portabilidade, Serverless Framework. Ambas reduzem drasticamente o tempo entre código e produção.</p>
<p>Três aprendizados principais: primeiro, infrastructure-as-code (IaC) transforma deploy em processo reproduzível e versionado. Segundo, observabilidade desde o início (logs, métricas, tracing) economiza horas de debugging em produção. Terceiro, serverless não significa "sem servidor" — significa delegar operações para AWS, mantendo foco em lógica de negócio.</p>
<h2>Referências</h2>
<ul>
<li><a href="https://www.serverless.com/framework/docs" target="_blank" rel="noopener noreferrer">Serverless Framework Documentation</a></li>
<li><a href="https://docs.aws.amazon.com/serverless-application-model/" target="_blank" rel="noopener noreferrer">AWS SAM Developer Guide</a></li>
<li><a href="https://docs.aws.amazon.com/lambda/latest/dg/best-practices.html" target="_blank" rel="noopener noreferrer">AWS Lambda Best Practices</a></li>
<li><a href="https://aws.amazon.com/blogs/compute/" target="_blank" rel="noopener noreferrer">Comparação Serverless vs SAM - AWS Blog</a></li>
<li><a href="https://learning.oreilly.com/" target="_blank" rel="noopener noreferrer">Building Serverless Applications with SAM - O'Reilly</a></li>
</ul>