Serverless na AWS: Lambda, DynamoDB Streams e Boto3 para Eliminar Arquivos Órfãos no S3
Como criei um microserviço orientado a eventos que apaga automaticamente o PDF do S3 quando o cadastro é excluído do DynamoDB.
Tags: AWS, Serverless, Python, DynamoDB, Lambda
🪲 O problema
Na aplicação HumanGov, cada cadastro grava um registro no DynamoDB e um PDF no S3. Ao excluir o cadastro, o registro sumia da tabela, mas o arquivo continuava no bucket. Com o tempo, isso gera custo de armazenamento e dados órfãos.
✅ A solução
Um microserviço serverless e orientado a eventos:
Exclusão no DynamoDB → DynamoDB Stream → AWS Lambda (Python + Boto3) → remoção do PDF no S3 → log no CloudWatch
🧰 Tecnologias
• Amazon DynamoDB com Streams: registra cada alteração da tabela como um evento
• AWS Lambda (Python 3.11): processa o evento e executa a lógica
• Boto3: SDK da AWS para Python
• Amazon S3: armazena os PDFs
• IAM: define as permissões da função
• CloudWatch Logs: monitoramento e evidência
⚙️ Passo a passo
1. Ativei o stream na tabela. Em Exports and streams, liguei o DynamoDB stream com o tipo de visualização “New and old images”. Esse tipo é essencial: no evento de exclusão, só a imagem antiga contém o nome do arquivo.
2. Criei a função Lambda “HumanGovDeleteFile” com runtime Python 3.11.
3. Escrevi o código. A função percorre os eventos, filtra os de exclusão (REMOVE), lê o nome do PDF da imagem antiga do item e apaga o objeto no S3:
import boto3
Get Eduardo Carvalho’s stories in your inbox
Join Medium for free to get updates from this writer.
s3_client = boto3.client(‘s3’)
def lambda_handler(event, context):
for record in event[‘Records’]:
if record[‘eventName’] == ‘REMOVE’:
pdf_filename = record[‘dynamodb’][‘OldImage’][‘pdf’][‘S’]
try:
s3_client.delete_object(Bucket=’NOME-DO-BUCKET’, Key=pdf_filename)
print(f’Successfully deleted {pdf_filename} from the S3 bucket.’)
except Exception as e:
print(f’Error deleting {pdf_filename}: {e}’)
raise e
4. Ajustei as permissões. A role criada junto com a função só escreve logs. Anexei políticas de acesso ao S3 e ao DynamoDB para que ela consiga apagar objetos e ler o stream.
5. Criei o trigger. Em Configuration → Triggers, conectei a função ao stream da tabela.
[INSERIR IMAGEM: Lambda com o trigger do DynamoDB]
✅ Teste e evidência
Para validar, coloquei um PDF no bucket, criei na tabela um item cujo atributo “pdf” aponta para esse arquivo e, em seguida, excluí o item. Em segundos, o PDF sumiu do bucket e o CloudWatch registrou a mensagem:
Successfully deleted <arquivo>.pdf from the S3 bucket.
[INSERIR IMAGEM: print do CloudWatch Logs com a linha em destaque]
Observação: simulei no console o que a aplicação faz, em vez de usar a tela do HumanGov, para não manter o cluster EKS ligado e economizar crédito.
🧠 O que aprendi
• O DynamoDB Streams transforma alterações da tabela em eventos, e o tipo de visualização do stream define quais dados chegam à função.
• Na arquitetura orientada a eventos, nada roda enquanto não há evento, e o custo é proporcional ao uso.
• As permissões IAM são parte da solução: a função só funcionou depois que a role ganhou acesso ao S3 e ao stream.
• O “raise e” no tratamento de erro faz o evento ser reprocessado, em vez de falhar silenciosamente.
🔐 O que eu melhoraria em produção
Usei políticas amplas de acesso (S3 e DynamoDB completos) por ser um ambiente de estudo. Em produção, aplicaria o princípio do menor privilégio: apenas a permissão de apagar objetos no bucket específico e as ações de leitura do stream específico. Também trataria o caso de um item sem o atributo “pdf”.
💰 Limpeza
Ao terminar, excluí a função Lambda, o log group e a role, e destruí o restante da infraestrutura com Terraform.
🔗 Links







