// CONTEXTO
Um blueprint que se repete em qualquer sistema sério
Este blueprint vem da engenharia real de um sistema que rodou em produção por 8 anos: a infraestrutura de borda (edge / load balancing) da Atlassian. Cada passo abaixo é uma decisão de arquitetura que se repete em qualquer sistema sério, seja SaaS, CRM, agente de IA ou edge.
A ideia central que amarra tudo: criar a oportunidade de centralizar lógica e resolver preocupações cedo na cadeia de requisições. Você expõe entradas simples pro usuário, valida, e transforma isso em recursos complexos e válidos automaticamente. O usuário manda um pedacinho de JSON; a plataforma monta o mundo inteiro pra ele.
// OS 10 PASSOS · ABRA CADA UM
A arquitetura, peça por peça
01 Comece pelo contrato, não pelo código
Antes de escrever uma linha, defina o que é sucesso. Na entrevista, ele perguntou aos entrevistadores: “olhem 12 meses pra frente; o que eu teria que ter entregue pra vocês dizerem que me contratar foi uma boa decisão?”. A resposta virou o escopo: uma aplicação de load balancers self-service. Esse é o contrato.
No código, o mesmo princípio: ele não começou inventando rotas. Começou pelo Open Service Broker (OSB), uma especificação aberta de API que descreve como provisionar recursos pra uma plataforma (catálogo de serviços e planos, provisioning, binding). Pegou o documento OpenAPI e gerou os handlers a partir dele com a lib connexion (documento OpenAPI vira rotas automaticamente). Depois migrou pra Flask puro, e por fim pra FastAPI.
02 O Broker self-service: API + fila + worker + banco
O coração operacional é um broker que provisiona recursos sob demanda, de forma assíncrona. O desenho:
- App web (FastAPI) recebe a requisição do cliente: “provisione um load balancer pra mim”.
- O web não faz o trabalho ele mesmo. Ele larga os detalhes da tarefa numa fila (SQS).
- Um worker consome a fila e executa o provisionamento de verdade: criar registros DNS, criar uma distribuição CloudFront, fazer chamadas de API. Tudo assíncrono.
- O worker grava o resultado num banco (DynamoDB).
- O cliente fica fazendo polling: “já ficou pronto? já ficou pronto?”. Quando o worker termina e escreve o status, o web responde “pronto”, ou “deu erro”.
Por que separar web de worker com uma fila no meio? Porque provisionamento é lento e pode falhar. Desacoplar a requisição rápida (HTTP) do trabalho pesado (minutos de chamadas a cloud) dá resiliência: se o worker cai, a tarefa continua na fila; o web nunca trava esperando. Esse é o padrão request › enqueue › async worker › status polling, e ele vale pra qualquer operação cara (geração de imagem, disparo em massa, deploy, cobrança).
03 Control plane dinâmico: separe a lógica de configuração da entrada do usuário
Aqui entra a peça mais inteligente. Eles queriam trocar load balancers enterprise (com custo de licença) por um proxy commodity open-source: o Envoy. O Envoy aceita configuração dinâmica via API e recarrega em runtime, então você sobe milhares de proxies parados e empurra config nova quando alguém precisa, sem redeploy.
Pra gerenciar isso ele construiu um management server / control plane (que ele abriu como open source chamado Sovereign, em FastAPI). O control plane recebe duas coisas:
- Templates: a lógica de configuração por tipo de recurso do Envoy (clusters, routes, listeners).
- Contexto: os dados dinâmicos, que vêm do banco (via broker) e de outras fontes (um bucket S3 que muda com o tempo).
Quando um proxy pede config, o control plane pega o contexto, injeta nos templates, renderiza a configuração do Envoy e devolve. O contexto muda ao longo do tempo, o template cospe config diferente, o proxy muda de comportamento, sem ninguém logar em servidor nenhum.
04 Infraestrutura como código para o que é de longo prazo
Os proxies não nascem do nada. Eles são provisionados por um template de CloudFormation (infraestrutura como código na AWS). O que entra nesse template, em blocos previsíveis e reutilizáveis: VPC, subnet, internet gateway, security group, key pair, IAM role, auto scaling group, AMI, instâncias EC2, NLB (proxy de camada 4), ACM (certificados) e alguns registros Route 53. Parâmetros são passados em runtime: segredos e chaves entram aí, não ficam no template.
Com esses blocos básicos, eles criaram ~2.000 proxies em ~13 regiões. É infraestrutura long-lived (pré-provisionada, fica de pé o tempo todo), descrita em código, reproduzível e versionada.
05 Imagens imutáveis: build once, run everywhere
A AMI (imagem da máquina) que a CloudFormation referencia não é montada na hora; é construída antes num pipeline próprio com HashiCorp Packer + SaltStack (gerenciamento de configuração, primo de Ansible/Puppet/Chef). O fluxo: Packer sobe uma EC2 numa conta de dev, joga a config do SaltStack nela, roda o provisionamento (instala pacotes, põe arquivos, sobe serviços, em ordem e de forma declarativa), e então tira um snapshot e transforma em AMI.
O que vai dentro da imagem (cada um é um “state” do SaltStack): instalar e configurar Envoy, agente de observabilidade (logs, traces, métricas), segurança e hardening, network tuning, containers, tracing, e os sidecars. A AMI sai pronta; a CloudFormation provisiona EC2s a partir dela; tudo já sobe rodando.
06 Centralize as preocupações transversais na borda
Esta é a tese que justifica a plataforma inteira. Pense numa requisição do cliente que passa pelo NLB, chega ao proxy, e segue pro backend. Antes de chegar no backend existe um monte de “preocupação transversal”: autenticação, autorização, proteção contra DDoS, rate limiting, access logs.
A pergunta: você resolve isso uma vez na borda, ou obriga mil times de backend a resolverem cada um por si? Resolver na borda economiza tempo, dinheiro e entrega features mais rápido pra todo mundo. Obrigar mil times a reimplementar auth e rate limiting seria um desperdício colossal e ainda atrasaria o produto.
Como cada preocupação foi resolvida ali na frente:
- DDoS: pelo CloudFront.
- Access logs: nativamente no proxy, via network filters do Envoy (no HTTP Connection Manager). Tudo configurado de forma dinâmica pelos templates.
- Autenticação: por um sidecar (mais sobre isso no passo 07).
07 Extensibilidade via sidecar
Nem tudo cabe nativo no proxy. Para preocupações mais complexas, eles usaram o modelo sidecar: o Envoy “conversa pro lado” com serviços locais (containers) que rodam na mesma máquina do proxy. Cada sidecar tem sua própria lógica, separada do proxy, e também recebe configuração dinâmica pela rede localmente.
Times diferentes contribuíram sidecars: o de autenticação foi escrito por ele (em Rust); autorização e rate limiting, por outros times. Esses sidecars eram baixados e configurados na AMI pelo próprio fluxo de provisionamento de imagem (passo 05). Resultado: um proxy programável, extensível por vários times sem tocar no core, cada peça evoluindo no seu ritmo.
08 Adoção forçada pela plataforma
Construir a plataforma é metade do trabalho; fazer o resto da empresa usar é a outra. A migração teve duas frentes: trazer os produtos grandes pra plataforma, e migrar todos os microsserviços. A segunda foi mais fácil, porque dava pra forçar pela própria plataforma: eles cortaram o load balancer básico antigo, você não conseguia mais expor seu serviço publicamente por ele. Pra ir pra internet, tinha que passar pela infra de load balancing centralizada e configurar isso explicitamente, o que virou um sinal claro de intenção (“eu quero esse serviço público”). Antes, um serviço podia ficar público por acidente, mal protegido.
Assim, Jira, Confluence, Bitbucket, Status Page e muitos outros entraram atrás da infra de borda. A plataforma era genérica e multi-tenant, mas teve que aguentar os casos especiais dos produtos grandes (levou alguns anos de features pra suportar todos).
09 Manutenibilidade: documentar, onboardar, vigiar o churn
O sistema rodou 8 anos, então a parte mais subestimada apareceu: manter. No começo de qualquer serviço você precisa onboardar gente, escrever documentação e treinar, pra que saibam contribuir, debugar e ficar de plantão (saber o que cada mensagem de log significa, que métrica olhar quando algo quebra, como resolver os problemas esperados). E precisa antecipar os modos de falha: e se a AWS cair e o banco ficar inacessível? E se o SQS parar e nenhum provisionamento rodar? E se o proxy receber uma config válida porém destrutiva, que mata o tráfego, como você percebe?
Com o tempo, gente entra e sai, traz opiniões novas, mexe no código. Surge o conceito de churn: a área do código que mais muda é previsível, e churn é um cheiro. É um sinal de que aquela parte vai continuar crescendo em tamanho e complexidade, e algo precisa ser feito antes de virar bagunça. O acoplamento se infiltra devagar: você muda uma coisa num canto e quebra outra, e tem que desembaraçar. Construir é fácil; mudar ao longo do tempo, e continuar conseguindo mudar, é o difícil.
10 O lado humano: diplomacia, comunicação e mentoria
A última camada não está no quadro branco, mas é o que sustenta as outras nove. Em 8 anos, o que ele mais desenvolveu foram habilidades de diplomacia, resolução de conflito, persuasão, ensino e mentoria. Personalidades diferentes geram atrito inevitável; o que dá pra fazer é ter autoconsciência, entender a outra pessoa, antecipar o conflito e agir pra a relação funcionar. O feedback recorrente dos colegas foi que ele estava sempre disponível pra ajudar e conseguia destrinchar temas difíceis em algo compreensível, construindo o modelo mental do sistema na cabeça dos outros.
// OS PRINCÍPIOS EM UMA LINHA
Dez decisões, dez frases
“Centralize a lógica e resolva as preocupações cedo na cadeia de requisições.”
01 · Contract-first: a forma nasce do contrato, não do framework.
02 · Desacople o lento do rápido com uma fila e um worker.
03 · Separe a lógica (templates) da entrada (parâmetros validados).
04 · O que é longo-prazo e crítico vira código declarativo.
05 · Imagem imutável: build once, run identical.
06 · Centralize a preocupação transversal cedo, na borda.
07 · Núcleo estável + extensões isoladas (sidecars/plugins).
08 · Torne o caminho certo o único caminho (default seguro).
09 · Projete pra mudança: documente, onboarde, vigie o churn.
10 · Comunicação é arquitetura: o que ninguém entende, ninguém mantém.
Use como base toda vez que for desenhar ou revisar um sistema. Entradas simples pro usuário, complexidade resolvida por dentro, e lógica centralizada cedo: é isso que faz uma plataforma durar.
// Fonte: I was laid off by Atlassian (Vasilios Syrakis) · destilado por Naia · ecossistema Avalanche