Sua aplicação precisa de S3, filas, Lambda e banco. Seu teste não deveria precisar de uma conta na AWS para começar. O MiniStack leva mais de 60 serviços AWS para o ambiente local, com APIs compatíveis, suporte a Terraform e a possibilidade de executar PostgreSQL, Redis e containers de verdade. Código aberto, licença MIT e sem assinatura do emulador.
A proposta resolve uma dor conhecida: você muda uma regra de negócio, mas precisa esperar infraestrutura, disputar uma conta de desenvolvimento ou descobrir por que o pipeline depende de credenciais que só funcionam no notebook de alguém. Com o MiniStack, uma parte importante desse trabalho pode acontecer em http://localhost:4566, usando as ferramentas que o projeto já conhece.
O atrativo está na combinação: emulação de APIs, integração entre serviços e execução real onde ela faz diferença. Dá para criar um bucket com AWS CLI, publicar uma mensagem pelo boto3, provisionar recursos com Terraform e conectar seu driver SQL a um banco iniciado pelo emulador. Só é preciso entender a profundidade de cada implementação: serviço listado não significa reprodução integral da AWS.
Analisei a documentação, o registro de serviços e implementações do repositório em 4 de setembro de 2026, no commit e025978. O pacote declara versão 1.5.7 e classificação Beta; a análise também considera o estado da branch nesse commit, que pode incluir alterações ainda não lançadas. As referências usam esse recorte para o artigo continuar verificável. Metadados do projeto.
O que é o MiniStack — e qual problema ele quer resolver
MiniStack é um emulador local de serviços AWS voltado a desenvolvimento, testes de integração e CI/CD. Você sobe um processo Python ou um container e aponta as chamadas do SDK para o endpoint local. O programa recebe requisições no formato esperado pelos clientes AWS e mantém o estado dos recursos em sua própria máquina.
Isso permite testar mais do que uma função isolada. Uma aplicação pode gravar um objeto, emitir um evento, consumir uma fila e chamar uma função sem criar esses recursos na nuvem. O ciclo fica mais controlável: criar ambiente, carregar dados, executar testes e descartar ou restaurar o estado.
O projeto se posiciona como alternativa livre ao LocalStack. A promessa editorial “free forever” expressa a direção dos mantenedores; o fato verificável hoje é a licença MIT do código analisado, que permite uso, modificação e redistribuição, inclusive comercial, preservando os avisos exigidos. Não há cobrança de licença do MiniStack. Sua máquina, seu runner de CI e eventuais serviços externos continuam tendo seus próprios custos. Licença MIT.
Uma porta para as APIs, vários tipos de execução por trás
O gateway ASGI identifica o serviço a partir de cabeçalhos, assinatura, parâmetros, caminho e hostname. Os módulos são carregados sob demanda. Por isso S3, SQS, DynamoDB e outros clientes compartilham a porta 4566, mesmo usando protocolos diferentes, como JSON, REST e Query/XML. Há suporte a HTTP/2 h2c e opção de HTTPS.
Por trás dessa entrada existem três comportamentos que vale distinguir:
- Estado e respostas emulados: o MiniStack guarda recursos, valida operações e responde ao SDK. Criar uma VPC nesse modo cria uma representação local da VPC.
- Execução local de lógica: uma função Lambda Python pode rodar em subprocesso; um workflow pode percorrer estados; uma mensagem pode ser entregue a outro serviço.
- Infraestrutura auxiliar real: determinados serviços iniciam containers ou usam engines reais, como PostgreSQL, Redis, k3s, Airflow e DuckDB.
A porta única é a entrada das APIs AWS. Conexões SQL, Redis, SFTP e MQTT podem usar portas adicionais. Um banco criado pelo RDS devolve seu próprio endereço e porta; o driver PostgreSQL conecta ali, não na porta do gateway. Isso explica por que “uma porta” não significa “nenhuma configuração de rede”. Arquitetura documentada.
O mapa dos recursos: o que está incluído no projeto
A lista abaixo reúne as famílias da documentação e complementos encontrados no código. Ela cobre o catálogo analisado, sem confundir dezenas de serviços com cobertura de todas as operações existentes na AWS. Em cada família, o importante é o comportamento disponível para o seu teste. Catálogo documentado e registro de serviços no código.
Armazenamento, filas e eventos: a base de uma aplicação distribuída
Guarde arquivos, transporte mensagens e coordene o que acontece depois. Esta família reúne os serviços que fazem os dados circular pela aplicação.

S3
buckets, objetos, listagem, cópia, exclusão em lote, multipart upload, versionamento, tags, CORS, políticas e configurações de criptografia, lifecycle, notificações e replicação. Object Lock inclui retenção e legal hold com aplicação de restrições de exclusão. Armazenar uma configuração não garante reproduzir todo o serviço gerenciado por trás dela.
S3 Tables
tabelas Iceberg e catálogo REST embutido em /iceberg, com arquivos de dados no S3 local. S3 Files: plano de controle para sistemas de arquivos, mount targets, access points e políticas; não equivale a disponibilizar um filesystem de produção.
SQS
filas, atributos, envio e recebimento, mensagens em lote, visibility timeout, filas FIFO, deduplicação e dead-letter queues. Os protocolos Query e JSON são contemplados.
SNS
tópicos, assinaturas, publicação, FIFO, deduplicação e entrega para SQS e Lambda. Também existem operações de aplicações e endpoints de push; isso não transforma o ambiente em um serviço público de entrega para dispositivos.
EventBridge
buses, regras e padrões de eventos, targets, archives e replay. API Destinations podem chamar endpoints HTTP com autenticação configurada; a documentação ressalva que retry de 24 horas, rate limiting e DLQs desse caminho não são reproduzidos.
EventBridge Scheduler
grupos e agendamentos com rate(), cron() e at(), disparando alvos como Lambda, SQS, SNS e Step Functions.
EventBridge Pipes
ciclo de vida dos pipes e execução limitada, no código analisado, à origem DynamoDB Streams e aos destinos SNS ou Step Functions. Não assuma que qualquer combinação aceita pela AWS execute aqui.
Kinesis
streams, shards e records, com roteamento por partition key e limites documentados de tamanho e lote. Firehose: entrega para S3 local, consumo de origem Kinesis e transformação em lote por Lambda; outros tipos de destino têm cobertura mais restrita.
É essa comunicação entre componentes que torna o emulador interessante para integração. Testar a chamada de publicação é uma coisa. Ver uma publicação chegar à fila e ser processada é outra etapa do contrato da aplicação. Escopo de execução dos Pipes.
Step Functions: workflows que percorrem estados de verdade
Step Functions tem um interpretador de Amazon States Language para estados Pass, Task, Choice, Wait, Succeed, Fail, Map e Parallel. A implementação inclui Retry, Catch, callbacks com waitForTaskToken, Activities para workers externos, histórico e execução de workflows aninhados nos caminhos suportados.
Além de JSONPath e funções intrínsecas, o código analisado avalia expressões JSONata. A API TestState permite exercitar um estado isolado, inspecionar a saída e injetar respostas simuladas. SFN_MOCK_CONFIG aceita configuração no formato do Step Functions Local. Isso ajuda a verificar, por exemplo, se uma falha de pagamento entra no estado de compensação e se uma resposta bem-sucedida segue para confirmação, sem depender de um serviço externo.
Para acelerar testes, a configuração interna de escala de espera pode reduzir durações de Wait e retry. Não use esse modo para medir tempos reais. A execução de um workflow ainda depende das integrações implementadas: testar o JSON da máquina e testar todos os seus efeitos são verificações complementares. Implementação de Step Functions.
Bancos, cache, busca e análise de dados
Aqui o foco é onde os dados vivem e como são consultados: bancos transacionais, cache, busca e processamento analítico.

DynamoDB
tabelas, CRUD, Query, Scan, operações em lote, transações, TTL e configurações auxiliares. O TTL possui processo de expiração em segundo plano; não espere exclusão instantânea no exato segundo do vencimento.
DynamoDB Streams
emite registros de inserção, alteração e remoção, com seleção de imagens e iteradores. A implementação usa um shard sintético por stream; testes locais não medem o comportamento de particionamento real da AWS.
RDS
instâncias e clusters com PostgreSQL, MySQL, MariaDB e variantes Aurora suportadas sobre containers. O endpoint pode aceitar conexões SQL reais. RDS Data API: encaminha SQL aos bancos locais com drivers apropriados. RDS Proxy: cobertura de plano de controle, sem equivalência a um proxy gerenciado em operação.
Aurora DSQL
APIs de clusters e, com DSQL_STRICT=1, PostgreSQL atrás de um proxy que rejeita parte do SQL não suportado pelo DSQL e emula operações como CREATE INDEX ASYNC. A validação tem limites heurísticos; CDC mantém metadados, mas não entrega alterações ao Kinesis.
ElastiCache
containers reais de Redis, Valkey e Memcached. O modo opcional ELASTICACHE_CLUSTER_MODE_REAL=1, com rede Docker configurada, habilita grupos Redis Cluster para exercitar clientes que lidam com slots e redirecionamentos.
OpenSearch Service
gerenciamento de domínios e endpoint simulado por padrão. Com OPENSEARCH_DATAPLANE=1, pode iniciar OpenSearch real; OPENSEARCH_DASHBOARDS=1 adiciona o painel auxiliar. Também pode apontar para um cluster fornecido por você.
Athena
execução de SQL via DuckDB quando instalado, incluindo agregações, joins, CTEs e leitura de arquivos. Sem DuckDB, o resultado é simulado. A compatibilidade de APIs não torna DuckDB idêntico ao engine do Athena.
Glue
catálogo, jobs Python executados localmente e jobs Spark via imagens oficiais do Glue, além de integração com Iceberg. MWAA: o módulo de Airflow pode iniciar Apache Airflow 3 em container e sincronizar DAGs do S3 configurado.
No Aurora PostgreSQL, o comportamento padrão compartilha o banco do cluster entre os membros. Réplicas read-only reais exigem a opção MINISTACK_RDS_PG_CLUSTER_REPLICATION=1 e uma rede Docker. Isso muda o que é válido afirmar em um teste de leitura e escrita: dois endpoints não provam dois processos independentes. Opções de bancos e engines; Implementação do MWAA.
Computação: Lambda, containers, Kubernetes e jobs
Estes componentes executam código ou representam a infraestrutura de execução. O comportamento muda conforme o serviço e o modo habilitado.

Lambda
funções Python e Node.js com execução real, workers aquecidos, versões, aliases, layers, concorrência, Function URLs e configurações de invocação. Event source mappings ligam SQS, Kinesis e DynamoDB Streams às funções.
Runtimes e imagens Lambda
modo Docker com Runtime Interface Emulator, runtimes provided e PackageType=Image. Isso abre caminho para Go, Rust, C++ e imagens próprias, desde que respeitem o contrato do runtime.
Recursos avançados de Lambda
a implementação inclui Durable Functions, callbacks e retomadas; SnapStart inicializa o ambiente ao publicar uma versão, mas não cria um snapshot real; integração de tracing injeta contexto X-Ray nos executores suportados. Lambda MicroVMs é emulação de ciclo de vida e metadados, sem iniciar uma VM real.
Lambda Proxy
encaminha o evento por HTTP a um container que você mantém em execução. Útil para o ciclo local com PHP, Bun, Deno ou outro servidor; esse modo de registrar um container externo não é uma funcionalidade equivalente da AWS Lambda.
ECS
clusters, task definitions, tasks e serviços. RunTask pode iniciar containers reais e injetar metadados de tarefa, endpoint de credenciais e endpoint AWS local.
EKS
criação de cluster com k3s quando Docker está disponível, permitindo uso de kubectl e Helm. Também há operações de nodegroups, addons e access entries; executar k3s não reproduz todos os componentes gerenciados do EKS.
EC2 e EBS
instâncias, imagens, VPCs, subnets, security groups, rotas, interfaces, volumes, snapshots e operações de fleet. Por padrão, instâncias são metadados. Registrar uma AMI associada a uma imagem de container permite executar um container e usar comandos SSM nesse ambiente.
Auto Scaling
grupos, políticas, scheduled actions e lifecycle hooks emulados. Batch: filas e jobs no plano de controle, com conclusão simulada. EMR: representação de clusters e steps, sem executar Hadoop ou Spark por esse serviço.
CodeBuild
projetos e builds simulados por padrão; MINISTACK_CODEBUILD_EXECUTE=1 permite execução com o agente local oficial e Docker, exigindo compartilhamento correto do workspace. ECR: operações de repositório, imagens, manifests Docker V2, tokens e políticas.
Se o teste precisa garantir que a função rodou em container, vale ativar LAMBDA_STRICT=1: a falta de Docker passa a produzir erro em vez de degradar para subprocesso. No EKS, o container k3s usa modo privilegiado. Esses detalhes fazem parte da configuração do laboratório e do acesso que ele terá ao host. Execução Lambda em Docker; Escopo de MicroVMs.
APIs, autenticação, rede e comunicação em tempo real
Esta camada recebe chamadas, identifica usuários e conecta aplicações. APIs HTTP, GraphQL, WebSockets e entrega de conteúdo aparecem neste grupo.

API Gateway REST v1 e HTTP/WebSocket v2
APIs, rotas, métodos, stages, deployments, integrações com Lambda, HTTP e mocks. Há execução de tráfego, CORS, authorizers nos caminhos suportados e gerenciamento de conexões WebSocket.
URLs previsíveis
o caminho /_aws/execute-api/{apiId}/{stage}/{path} facilita acesso sem depender de DNS personalizado. A tag ms-custom-id fixa IDs de API; o nome legado ls-custom-id não é intercambiável.
AppSync
APIs GraphQL, schemas e resolvers; o código analisado valida schemas com graphql-core e executa resolvers APPSYNC_JS em workers Node, com fontes NONE, HTTP, DynamoDB e Lambda. A cobertura deve ser validada por operação; não é garantia de todo o GraphQL/AppSync.
AppSync Events
publicação HTTP, canais e conexões WebSocket, com opção de exigir autenticação local. É uma superfície própria; não deve ser confundida com cobertura automática de todas as subscriptions GraphQL.
Cognito
User Pools e Identity Pools, fluxos de autenticação e integração com aplicações. Há fluxo CUSTOM_AUTH com triggers Lambda e verificação TOTP real. Outros atalhos continuam presentes, como códigos fixos em fluxos de confirmação; não é um provedor de identidade para produção.
ELBv2/ALB
listeners, regras, target groups, encaminhamento para Lambda, respostas fixas, redirects e fluxo OIDC implementado. A cobertura de ações e destinos continua sendo específica do emulador.
Route 53 e Cloud Map
zonas, registros e service discovery. Configurar registros localmente não publica DNS autoritativo na internet.
CloudFront e CloudFront KeyValueStore
distribuições, políticas, invalidações, configurações de SaaS Manager e armazenamento chave/valor com ETags. CloudFront Functions guarda código e versões de configuração, sem executar JavaScript na borda; o emulador não cria uma CDN mundial.
EFS
APIs de sistemas de arquivos, mount targets e access points emulados. Transfer Family: listener SFTP real com arquivos no S3 local e autenticação por chaves SSH, usando uma porta adicional.
Amplify Gen 2 aparece entre as integrações documentadas, combinando Cognito, AppSync, S3 e Lambda. Antes de assumir compatibilidade total, rode o schema, os resolvers e o fluxo de login do seu aplicativo. O README tem trechos de épocas diferentes; para os resolvers JavaScript e AppSync Events, a análise também conferiu a implementação. AppSync no código; AppSync Events.
Segurança, configuração, observabilidade e governança
Quem pode acessar, onde guardar configurações e como observar o sistema: os componentes abaixo ajudam a controlar e acompanhar o ambiente.

IAM e STS
identidades, roles, políticas e sessões. A opção AUTH=true ativa verificações IAM implementadas pelo projeto. No padrão, não use uma chamada bem-sucedida como prova de que a política de produção está correta.
KMS
chaves, aliases, criptografia, assinaturas, HMAC e recursos de chaves multirregião. Há operações criptográficas reais, mas isso não representa isolamento por HSM nem a fronteira de segurança da AWS.
Secrets Manager e SSM Parameter Store
segredos, parâmetros e tipos String, SecureString e StringList. O SSM também participa do caminho de comandos em instâncias locais compatíveis.
AppConfig e AppConfigData
versões de configuração, deployments e recuperação por sessões com rotação de tokens.
CloudWatch Metrics e Logs
métricas, alarmes, grupos, streams, eventos de log e caminhos de consulta/Live Tail suportados. CloudTrail: trilha local em memória com gravação opt-in por CLOUDTRAIL_RECORDING=1.
SES e SES v2
identidades, templates e e-mails inspecionáveis localmente. Por padrão, mensagens ficam em memória; configurar SMTP_HOST permite encaminhamento a um servidor SMTP.
ACM
certificados e registros de validação emulados, com emissão automática no ambiente. WAF v2: ACLs, conjuntos de IP e regras no plano de controle; WAF Classic/Regional tem cobertura mínima. Isso não torna o gateway um firewall equivalente à AWS.
Organizations e Account
organizações, unidades organizacionais, contas e configurações regionais. Resource Groups e Resource Groups Tagging API: agrupamento, consulta e gerenciamento de tags.
AWS Config
regras, recorders, canais de entrega e consultas de status/conformidade. Cloud Control API: operações genéricas de recursos para ferramentas que usam esse contrato.
AWS Backup
vaults, planos e jobs com conclusão simulada. Cost & Usage Reports: gerenciamento de definições de relatórios, não apuração real de uma fatura AWS. Inspector2: findings determinísticos simulados; não executa uma auditoria real de vulnerabilidades.
Também existem emulações de IMDS v1/v2, ECS Task Metadata v4 e credenciais de containers ECS. Elas ajudam a testar aplicações que dependem da cadeia padrão de credenciais e dos metadados do ambiente. É diferente de simplesmente preencher duas variáveis de acesso no código. Roteamento e configuração de autenticação.
IoT, Kafka, mensagens e mídia: os detalhes que ficam fora do básico
Dispositivos, brokers e protocolos especializados têm requisitos próprios. Neste grupo, preste atenção a quais serviços executam um backend e quais mantêm apenas metadados.

IoT Core
recursos de dispositivos, certificados e políticas, MQTT 3.1.1/5.0 sobre WebSocket e listener MQTT com TLS na porta 8883, conforme as dependências e a configuração. O certificado de cliente é opcional no comportamento local documentado, e políticas IoT não têm a mesma aplicação da AWS.
IoT Jobs
APIs de controle e de dispositivo, estados das execuções e controle de concorrência por versão. Nem todas as transições e timeouts reais são automatizados.
MSK
clusters, configurações e bootstrap brokers no plano de controle. Para produzir e consumir Kafka, forneça um broker real, como Kafka ou Redpanda, e configure MINISTACK_MSK_BOOTSTRAP. O protocolo Kafka não é emulado.
Amazon MQ
recursos e operações de gerenciamento, sem broker real iniciado pelo serviço.
MediaConnect
representação de flows e operações de consulta, sem backend real de streaming ou transcodificação.
Essa distinção evita uma armadilha comum: o SDK receber um endereço ou status válido não prova que existe um mecanismo de execução por trás. Em MSK você traz o broker; em ElastiCache, o projeto pode criá-lo; em MediaConnect, a proposta do módulo é representar o plano de controle. Escopo do MediaConnect.
Bedrock local: use o contrato da AWS com um modelo no seu ambiente
Nesta parte entram inferência, agentes e processamento de áudio. A diferença entre resposta simulada e execução de um modelo é central para entender o que seu teste valida.

A família Bedrock cobre catálogo e gerenciamento de modelos, perfis de inferência, guardrails, jobs e outras operações. Bedrock Runtime implementa caminhos como Converse, InvokeModel e versões com streaming. Bedrock Agent e Agent Runtime acrescentam agentes, knowledge bases, ingestão, sessões, flows e operações de recuperação. AgentCore inclui ciclo de vida de runtimes e endpoints.
Por padrão, as respostas de inferência são mocks determinísticos, com formatos compatíveis com famílias de modelos. Isso é útil para testar parsing, campos obrigatórios e tratamento de streaming. Para gerar texto real, MINISTACK_BEDROCK_PROXY_URL aponta para um backend compatível com chat completions, como Ollama, llama.cpp ou vLLM. O MiniStack traduz a chamada de entrada e a resposta.
No Docker Desktop, com o backend já disponível no host na porta 11434, a configuração documentada usa:
docker run --rm --name ministack-bedrock \
-p 127.0.0.1:4566:4566 \
-e MINISTACK_BEDROCK_PROXY_URL=http://host.docker.internal:11434/ \
ministackorg/ministack:1.5.7
Esse comando é uma alternativa à instância anterior: duas instâncias não podem ocupar a mesma porta. No Linux, ajuste a resolução e o acesso ao host, por exemplo com --add-host host.docker.internal:host-gateway quando aplicável. O identificador enviado ao backend precisa corresponder a um modelo que ele consiga atender; usar um nome de Claude não instala nem executa Claude localmente.
Existem limites que afetam diretamente o teste:
- Falha do proxy pode voltar ao mock. A implementação documenta fallback quando a conexão falha. Verifique a saída e os logs; sucesso HTTP não garante que seu LLM respondeu.
- Knowledge bases não equivalem a um sistema vetorial completo. A recuperação analisa documentos ingeridos com pontuação lexical, sem embeddings.
- Agentes não reproduzem toda a orquestração.
InvokeAgentusa resposta predefinida; a invocação de AgentCore é um echo determinístico no escopo analisado. - Guardrails têm cobertura parcial. Políticas determinísticas de palavras, regex e certos dados sensíveis podem ser aplicadas; avaliações que dependem de modelos, como tópicos e grounding, não são reproduzidas.
- Contagem de tokens pode ser aproximada. Não use o mock para comparar custo, latência ou qualidade de um modelo real.
O Transcribe merece o mesmo cuidado: simula jobs batch, lê referências de mídia, grava resultados e pode emitir eventos de conclusão, mas não reconhece fala. A transcrição é texto determinístico. Serve para testar o pipeline que reage ao job; não para medir acurácia de áudio. Runtime do Bedrock; Limites dos agentes; Transcribe.
Subindo o ambiente: comece com o menor exemplo útil
Com os grupos de serviços em mente, vamos montar o ambiente: primeiro subir o MiniStack, depois chamar as APIs, adicionar bancos e automatizar os testes.

Para instalação Python, o pacote analisado exige Python 3.10 ou superior. Em um ambiente virtual:
python3 -m venv .venv
source .venv/bin/activate
python -m pip install ministack==1.5.7
ministack
Com Docker, uma instância simples pode ser iniciada assim:
docker run --rm --name ministack-dev \
-p 127.0.0.1:4566:4566 \
ministackorg/ministack:1.5.7
Em outro terminal, com AWS CLI instalado, confira a saúde e faça as primeiras chamadas. As credenciais abaixo são locais, não chaves de uma conta real:
curl --fail http://localhost:4566/_ministack/health
export AWS_ACCESS_KEY_ID=test
export AWS_SECRET_ACCESS_KEY=test
export AWS_DEFAULT_REGION=us-east-1
export AWS_EC2_METADATA_DISABLED=true
aws --endpoint-url=http://localhost:4566 s3 mb s3://ministack-demo
aws --endpoint-url=http://localhost:4566 sqs create-queue --queue-name pedidos
aws --endpoint-url=http://localhost:4566 sts get-caller-identity
A imagem full adiciona dependências como DuckDB e drivers de banco. Para esse cenário, use ministackorg/ministack:full ou instale ministack[full]==1.5.7 no Python. A tag full pode avançar; em CI, fixe uma versão publicada apropriada ou o digest da imagem que você validou. O README apresenta números diferentes de tamanho entre trechos, então não trato tamanho, memória ou tempo de boot anunciados como benchmark reproduzido.
Um exemplo Python que verifica armazenamento e mensageria
Com o emulador rodando, instale boto3 no ambiente do seu script. Este exemplo cria recursos com nome único, grava e lê um objeto, envia e confirma uma mensagem e limpa os recursos ao terminar. O endpoint fica explícito para que o teste use o ambiente local.
import json
from uuid import uuid4
import boto3
from botocore.config import Config
def client(service):
return boto3.client(
service,
endpoint_url="http://localhost:4566",
region_name="us-east-1",
aws_access_key_id="test",
aws_secret_access_key="test",
config=Config(s3={"addressing_style": "path"}),
)
s3 = client("s3")
sqs = client("sqs")
suffix = uuid4().hex[:12]
bucket = f"pedidos-{suffix}"
queue_url = None
created_bucket = False
try:
s3.create_bucket(Bucket=bucket)
created_bucket = True
queue_url = sqs.create_queue(QueueName=f"pedidos-{suffix}")["QueueUrl"]
payload = json.dumps({"pedido_id": "p-123", "total": 149.90}).encode()
s3.put_object(Bucket=bucket, Key="pedido.json", Body=payload)
response = s3.get_object(Bucket=bucket, Key="pedido.json")
with response["Body"] as body:
assert body.read() == payload
sqs.send_message(QueueUrl=queue_url, MessageBody=payload.decode())
messages = sqs.receive_message(
QueueUrl=queue_url, MaxNumberOfMessages=1, WaitTimeSeconds=5
).get("Messages", [])
assert messages, "A mensagem não chegou à fila local"
assert json.loads(messages[0]["Body"])["pedido_id"] == "p-123"
sqs.delete_message(
QueueUrl=queue_url, ReceiptHandle=messages[0]["ReceiptHandle"]
)
print("S3 e SQS responderam ao fluxo de integração local.")
finally:
if queue_url is not None:
sqs.delete_queue(QueueUrl=queue_url)
if created_bucket:
s3.delete_object(Bucket=bucket, Key="pedido.json")
s3.delete_bucket(Bucket=bucket)
O exemplo valida chamadas de S3 e SQS; ele não configura notificação automática de S3 para a fila. Quando o contrato do produto depender de um evento, inclua a configuração de notificação ou o vínculo entre serviços e teste também essa entrega. Separar essas duas expectativas torna a falha muito mais fácil de interpretar.
Docker Compose, persistência e bancos reais
O Compose abaixo usa a imagem completa, guarda estado e objetos e disponibiliza o socket Docker para serviços que iniciam containers auxiliares. A rede tem nome explícito para que os componentes possam se encontrar:
services:
ministack:
image: ministackorg/ministack:full
ports:
- "127.0.0.1:4566:4566"
environment:
DOCKER_NETWORK: ministack-dev
PERSIST_STATE: "1"
STATE_DIR: /data/state
S3_PERSIST: "1"
S3_DATA_DIR: /data/s3
RDS_PERSIST: "1"
MINISTACK_RDS_PUBLIC_ENDPOINT: "1"
MINISTACK_HOST: localhost
LAMBDA_EXECUTOR: docker
ATHENA_ENGINE: duckdb
volumes:
- ministack-data:/data
- /var/run/docker.sock:/var/run/docker.sock
networks:
- dev
networks:
dev:
name: ministack-dev
volumes:
ministack-data:
Aqui, MINISTACK_RDS_PUBLIC_ENDPOINT=1 atende drivers de banco executados no host: o RDS informa endereço e porta publicados. Para aplicações dentro de containers, ajuste o hostname e a rede. localhost dentro de um container aponta para o próprio container. Não é um endereço universal para o serviço MiniStack.
O socket permite ao emulador controlar containers no seu daemon Docker. Ele só é necessário quando você quer essa execução auxiliar. O primeiro uso pode baixar imagens, e bancos, Kubernetes e modelos de IA acrescentam consumo real de CPU, RAM e disco.
PERSIST_STATE conserva o estado dos serviços; S3_PERSIST conserva objetos; RDS_PERSIST troca armazenamento temporário por volumes dos bancos. Não são opções equivalentes. Escrita atômica de estado também não equivale a durabilidade completa diante de qualquer interrupção: o salvamento documentado ocorre no encerramento do processo.
Para criar PostgreSQL, depois de subir esse Compose e instalar boto3 e psycopg2-binary, o fluxo abaixo aguarda a instância ficar disponível antes de conectar. Execute em um ambiente de demonstração vazio:
import boto3
import psycopg2
rds = boto3.client(
"rds",
endpoint_url="http://localhost:4566",
region_name="us-east-1",
aws_access_key_id="test",
aws_secret_access_key="test",
)
rds.create_db_instance(
DBInstanceIdentifier="blog-postgres",
DBInstanceClass="db.t3.micro",
Engine="postgres",
MasterUsername="appuser",
MasterUserPassword="local-dev-password",
DBName="appdb",
AllocatedStorage=20,
)
rds.get_waiter("db_instance_available").wait(
DBInstanceIdentifier="blog-postgres",
WaiterConfig={"Delay": 2, "MaxAttempts": 90},
)
instance = rds.describe_db_instances(
DBInstanceIdentifier="blog-postgres"
)["DBInstances"][0]
endpoint = instance["Endpoint"]
connection = psycopg2.connect(
host=endpoint["Address"],
port=endpoint["Port"],
dbname="appdb",
user="appuser",
password="local-dev-password",
connect_timeout=10,
)
try:
with connection.cursor() as cursor:
cursor.execute("SELECT 40 + 2")
assert cursor.fetchone()[0] == 42
finally:
connection.close()
Esse caminho exercita SQL real. A classe db.t3.micro é um parâmetro da API emulada; não significa que seu container tenha o mesmo hardware, desempenho ou disponibilidade da instância correspondente na AWS. O exemplo deixa a instância criada para inspeção; remova-a pelo RDS local quando terminar. Endpoints RDS.
Terraform: mantenha os recursos, direcione o provider
A documentação declara suporte aos providers AWS v5 e v6. O ajuste central é configurar credenciais locais, endpoints e opções que evitam verificações contra a nuvem real. Para um exemplo só com S3 e SQS, um main.tf pode ser:
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 6.0"
}
}
}
provider "aws" {
region = "us-east-1"
access_key = "test"
secret_key = "test"
s3_use_path_style = true
skip_credentials_validation = true
skip_metadata_api_check = true
skip_requesting_account_id = true
endpoints {
s3 = "http://localhost:4566"
sqs = "http://localhost:4566"
sts = "http://localhost:4566"
}
}
resource "aws_s3_bucket" "uploads" {
bucket = "ministack-terraform-uploads"
}
resource "aws_sqs_queue" "pedidos" {
name = "ministack-terraform-pedidos"
}
terraform init
terraform plan
terraform apply
# Ao terminar, neste diretório de demonstração:
terraform destroy
Adicione endpoints para todos os serviços utilizados pelo seu módulo, incluindo data sources e operações auxiliares. Não copie um provider que redireciona só S3 para um projeto que também usa IAM, EC2 e RDS. Preserve o lockfile e o estado local desse laboratório separados dos ambientes reais.
O teste de compatibilidade útil inclui criar, consultar, atualizar, aplicar novamente e destruir. Uma operação Create funcionar não garante que o provider consiga fazer o Read seguinte sem diferenças permanentes. Esse é um dos motivos para o changelog conter correções específicas de convergência do Terraform. Integrações de infraestrutura como código.
CloudFormation, CDK, Pulumi e Testcontainers
CloudFormation tem operações de stacks, change sets, exports, parâmetros, condições e funções intrínsecas, incluindo referências entre stacks. Templates JSON e YAML são aceitos, e existe implantação assíncrona com status e rollback. A cobertura de tipos de recurso é parcial; não basta um serviço existir para todo recurso CloudFormation dele estar implementado.
Para CDK, a documentação usa AWS_ENDPOINT_URL=http://localhost:4566 junto das credenciais de teste. Para Pulumi, configura endpoints no provider AWS. Os dois dependem da cobertura dos recursos que o programa gera; confirme o endpoint no processo que efetivamente faz o deploy.
O repositório também oferece exemplos de Testcontainers para Java, Go e Python. A vantagem é o teste controlar o ciclo de vida do container: inicia o ambiente, espera o health check, usa o endpoint e encerra ao terminar. Isso ajuda a reproduzir o mesmo cenário no notebook e no runner de CI. Exemplos de Testcontainers.
Várias contas e regiões sem multiplicar o ambiente
Uma access key numérica de 12 dígitos representa o ID da conta local. Chaves como test usam a conta padrão, normalmente 000000000000. A região vem do escopo da assinatura SigV4 usada pelo SDK. Assim você pode exercitar recursos homônimos em contextos diferentes.
AWS_ACCESS_KEY_ID=111111111111 AWS_SECRET_ACCESS_KEY=test \
aws --endpoint-url=http://localhost:4566 --region us-east-1 \
sqs create-queue --queue-name pedidos
AWS_ACCESS_KEY_ID=222222222222 AWS_SECRET_ACCESS_KEY=test \
aws --endpoint-url=http://localhost:4566 --region us-east-1 \
sqs create-queue --queue-name pedidos
AWS_ACCESS_KEY_ID=111111111111 AWS_SECRET_ACCESS_KEY=test \
aws --endpoint-url=http://localhost:4566 --region eu-west-1 \
sqs create-queue --queue-name pedidos
Esses três contextos não deveriam disputar a mesma fila. Mas o README registra exceções regionais para S3 e Aurora DSQL, que compartilham estado entre regiões dentro da conta. Serviços globais, como IAM, STS, Route 53, CloudFront e Organizations, exigem leitura própria desse escopo. E conta local é organização de estado para testes, não uma fronteira de segurança entre usuários hostis. Escopo e exceções multirregião.
Automação de testes: saúde, reset, inspeção e scripts de inicialização
A API interna facilita preparar o ambiente e observar o que aconteceu. Estes endpoints são especialmente úteis em testes:
# Saúde do ambiente
curl --fail http://localhost:4566/_ministack/health
# Inspecionar e-mails e mensagens locais
curl --fail http://localhost:4566/_ministack/ses/messages
curl --fail http://localhost:4566/_ministack/sqs/messages
# Apagar o estado de TODOS os serviços e contas desta instância
curl --fail -X POST http://localhost:4566/_ministack/reset
# Apagar o estado e executar novamente os scripts de inicialização
curl --fail -X POST 'http://localhost:4566/_ministack/reset?init=1'
O reset é global para a instância. Se dois jobs compartilham o mesmo processo, separar access keys não protege um deles do reset acionado pelo outro. Para paralelismo, prefira instâncias independentes por job ou coordene explicitamente a limpeza dos recursos. Os endpoints de inspeção ajudam a verificar conteúdo, visibilidade e tentativas sem depender só dos logs da aplicação.
Scripts .sh e .py podem rodar antes da inicialização ou após o serviço ficar pronto, nos diretórios nativos e nos caminhos compatíveis com LocalStack. Para criar buckets e filas via API, use a fase ready.d. Os scripts recebem endpoint e credenciais locais; nomes ordenados permitem carregar primeiro recursos e depois dados de exemplo.
Existe ainda /_ministack/config para configurações de execução suportadas, além de filtros de serviços por SERVICES, nível de log, customização de portas, TLS e prefixo de registro privado para imagens auxiliares. Consulte a opção do recurso que você vai executar: “instalou o pacote” e “habilitou todos os backends” são etapas diferentes. API interna; Inicialização automatizada.
Quando vale adotar — e o que ainda precisa chegar à AWS
MiniStack é particularmente útil para onboarding de times, desenvolvimento de backends orientados a eventos, testes de SDKs, validação de módulos Terraform e integração de aplicações que dependem de armazenamento, filas, bancos e funções. O melhor primeiro passo é escolher um fluxo real do produto e reproduzi-lo do começo ao fim.
Eu avaliaria a adoção com perguntas concretas: a aplicação grava e recupera o mesmo dado? O evento chega ao destino? A função falha como esperado? O provider converge? O retry acontece? O teste distingue um backend indisponível de um mock bem-sucedido? A resposta vale mais que contar quantos nomes aparecem no catálogo.
O ambiente local não mede latência entre regiões, escalabilidade da infraestrutura gerenciada, custo de produção, todos os limites de serviço ou a totalidade das políticas IAM. Complete os testes locais com uma etapa controlada na AWS para os contratos que dependem dessas propriedades. Isso permite reservar a nuvem para as verificações que realmente precisam dela.
O ecossistema já inclui integrações comunitárias como StackPort, um painel para inspecionar recursos, integração com .NET Aspire e OpenArchFlow, voltado a diagramas de arquitetura. São projetos externos, não funcionalidades de interface embutidas no MiniStack. Integrações comunitárias.
Como contribuir e por que a proposta importa
O código organiza as implementações por serviço em Python. O roteiro de contribuição envolve criar o handler, registrar o serviço, acrescentar o roteamento e escrever testes. Para quem encontrou uma incompatibilidade de SDK ou Terraform, uma reprodução pequena com a operação, versão do cliente e resposta esperada costuma ser uma contribuição valiosa. Guia de contribuição.
O MiniStack reduz a distância entre escrever código que usa AWS e conseguir testá-lo. Uma instalação local pode reunir contratos de APIs, eventos e recursos de infraestrutura que antes exigiam mais configuração espalhada pelo time. O código aberto permite inspecionar o comportamento e corrigir justamente o pedaço que seu projeto precisa.
A proposta fica mais forte quando usada com expectativas precisas: comece por um fluxo, habilite os componentes reais necessários e confirme os limites do serviço. Se a sua aplicação depende de S3, SQS, Lambda ou PostgreSQL, já existe um ponto de partida concreto para colocar o ambiente de desenvolvimento sob seu controle.
Referências e escopo da análise
Fontes primárias consultadas no repositório do projeto. Os exemplos foram escritos para explicar configuração e uso; esta análise não é um benchmark nem uma certificação de paridade com a AWS. Recursos da branch podem anteceder uma imagem publicada.
- MiniStack — repositório oficial.
- README no commit analisado — proposta, catálogo, instalação, configuração e limitações.
- Gateway e registro de serviços — serviços presentes e carregamento sob demanda.
- Pacote Python — versão, dependências e classificação Beta.
- Changelog — evolução, correções de compatibilidade e alterações ainda não lançadas.
- Licença MIT e guia de contribuição.