Passei a maior parte da minha carreira em startups, onde, muitas vezes, você trabalha com orçamento curto, equipe enxuta e um prazo batendo na porta. É muito fácil ceder à pressão e cortar caminhos para entregar algo hoje, mas o preço é que, em alguns anos, você pode acabar com uma bagunça tecnológica tão grande que vai começar a odiar o que faz e entrar em burnout.
Infelizmente, falo por experiência própria. Uma vez fiz o trabalho de três pessoas e, depois de três anos nesse ritmo, cheguei a um ponto em que pouco me importava com qualquer coisa e só queria ficar em silêncio olhando para o teto o dia inteiro.
Não se preocupe, isso já faz tempo, e me recuperei totalmente desde então. Além disso, com bastante disciplina, consegui evitar que a mesma coisa acontecesse de novo nas etapas seguintes da minha carreira. Com o tempo, fui destilando alguns ingredientes-chave para manter minha vontade de inovar a todo vapor no longo prazo.
Hoje, tenho a sorte de ocupar uma posição em que posso compartilhar minha experiência e ajudar outras pessoas a tirar seus sonhos do papel.
Esta é a minha história e a minha experiência. Você certamente tem a sua, e eu adoraria ouvi-la.
O time dos sonhos
Imagine um time de desenvolvimento de software com 5 a 10 pessoas que:
- Continua entregando novas funcionalidades dentro do prazo
- Sabe das indisponibilidades antes dos próprios clientes
- Corrige bugs rapidamente — e por "corrigido" quero dizer corrigido em produção, não na branch main do git
- Tem espaço para pesquisar e explorar novas tecnologias
E que consegue manter esse ritmo por anos sem perder o gás!
Parece bom demais para ser verdade? — Vamos descobrir. É assim que eu começaria um projeto novo hoje. Será um projeto baseado em nuvem, no meu caso, no GCP.
1\. Conheça suas premissas
A segurança costuma ser deixada de lado. Os desenvolvedores acham o tema difícil e estudam só o suficiente para passar dos padrões mínimos da nuvem e começar a construir as coisas. Afinal, seus clientes não compram segurança — eles compram funcionalidades; e, na visão deles, a segurança do produto é algo "já garantido".
Infelizmente, essa abordagem leva rápido a maus hábitos — "chaves de segurança em git público", alguém? : )
Pontos-chave:
- Mantenha um patamar de segurança dentro do time em relação à tecnologia que você usa. Por exemplo, ao começar em uma nova nuvem, garanta que todos (e não só o pessoal de DevOps) saibam o básico. No GCP, por exemplo, um desenvolvedor médio consegue se familiarizar com o modelo de segurança em poucas horas.
- Tenha uma pessoa de referência para orientar sobre boas práticas de segurança. Se não houver alguém assim no time, o Google, no nosso exemplo, tem parceiros pagos justamente para garantir que você sempre tenha com quem trocar ideia sobre o assunto.
Lembre-se do modelo de responsabilidade compartilhada das nuvens — elas fornecem blocos seguros, mas cabe a você combiná-los de forma segura.
Depois de entender suas premissas de segurança, aí sim dá para começar a arquitetar.
2\. Arquitete, mas com os pés no chão
Todo mundo sonha que sua empresa vire o próximo Twitter, Uber ou Google. Mas essas empresas não nasceram em escala global da noite para o dia.
O desafio é começar pequeno, mas sempre com espaço para crescer. Para isso, sugiro ter uma pequena força-tarefa dentro do time encarregada de garantir que o grupo não fique refém demais do pensamento tático — algo que acontece naturalmente quando se entra na cadência de "empurrar funcionalidades sem parar". Essa força-tarefa fica de olho para que os trade-offs certos sejam feitos. Por exemplo:
- Certa vez, desenvolvi um gerenciador de batch jobs para o banco de dados ElasticSearch. Implementá-lo de forma ativo/ativo e com escala horizontal teria exigido 10 vezes mais esforço; por outro lado, uma versão singleton aguentava um crescimento de carga de 100 vezes; e tudo bem se ele ficasse offline por 10 a 15 minutos por causa de um bug ou manutenção.
Nesse caso, escolhemos conscientemente ter um componente como ponto único de falha na nossa arquitetura, porque era bom o suficiente para as necessidades do negócio.
- Como estratégia, você pode querer desenvolver um produto agnóstico em relação à nuvem. Pode escolher Kubernetes (K8s) como plataforma de aplicação, e isso, por si só, já cobre cerca de 80% do objetivo. Mesmo assim, você ainda vai se conectar a serviços fora do K8s do seu provedor de nuvem, como Load Balancers, filas de mensagens etc.; e caberá à sua força-tarefa de arquitetura garantir que nenhum serviço exclusivo de um provedor seja escolhido no calor de um deadline. E, quando for o caso, que seja uma escolha consciente e bem documentada.
Seus tech leads mais sêniores naturalmente vão assumir esse papel, mas o ideal é formalizar isso e garantir que a voz deles seja ouvida. Discussões de post-mortem que começam com "eu te avisei há seis meses que isso ia desmoronar" são sinal de que sua força-tarefa de arquitetura precisa de ajustes. O lema é "confiar nos times".
Para que a força-tarefa de arquitetura dê certo — e para que todo o time se beneficie — é fundamental que os Product Owners e a gestão confiem que os desenvolvedores estão agindo com as melhores intenções. Desenvolvedores responsáveis tendem a ceder com facilidade à pressão por funcionalidades, o que rapidamente degenera no modo "eu te avisei…".
3\. Comece o código pela parte de CI/CD
O título acima pode soar um pouco radical, mas espero ter chamado sua atenção. A armadilha clássica é "funcionalidades agora, testes depois". Sob pressão de prazo, os testes geralmente são os primeiros a serem cortados.
Vou compartilhar uma história pessoal. Tive um projeto com uma ótima arquitetura, mas com uma peça faltando — investimos zero tempo pensando em como íamos testar nosso produto. Na quinta sprint, percebemos que gastávamos sempre 2 a 3 dias antes da sprint review numa "loucura de integração", e isso piorava de sprint para sprint. Nosso segundo erro foi que não conseguimos sair do modo frenético de funcionalidades e comunicar de forma clara à gestão de produto que precisávamos voltar à prancheta e fazer ajustes de design relacionados ao CI (RE: as notas sobre confiar nos times no capítulo anterior). Um ano depois, terminamos com um CI improvisado que quebrava mais do que funcionava e era fonte constante de frustração para os desenvolvedores. Essa grande bola de neve ficou tão grande que, mesmo com carta branca para investir e arrumar, não conseguíamos chegar a um consenso dentro do time sobre a melhor forma de rearquitetá-lo.
Duas coisas acontecem quando você incorpora CI e CD à sua arquitetura central:
- Você vai começar a se perguntar como saber se o sistema está funcionando. Isso vai te levar naturalmente a instrumentar seu código para coletar métricas operacionais.
- Quando for depurar falhas noturnas de CI, você vai desenvolver tanto as habilidades quanto as ferramentas (por exemplo, logs adequados e coleta de dados de tracing) para analisar e corrigir problemas que já aconteceram. Essas são exatamente as habilidades e técnicas de que seu time vai precisar para depurar incidentes em produção.
Como efeito colateral, você terá sistemas de logging e monitoramento implantados antes mesmo de entrar em produção. Um alerta sobre frameworks de monitoramento e logging: o custo operacional, seja em SaaS ou em solução própria, pode crescer muito rápido — recomendo fortemente estimar os custos potenciais e levar isso em conta na decisão.
Depois que sua prática de CI estiver estabelecida de forma satisfatória, aí sim você pode, de vez em quando, se dar ao luxo de "funcionalidades agora, testes depois". E por "depois" quero dizer "na próxima sprint", a menos que seja uma funcionalidade descartável, pontual, de demo, que você vai desativar com feature flags.
Cada nuvem tem seus próprios serviços nativos de monitoramento e logging, que podem ou não ser a melhor escolha para você. Com K8s, a parte de CD já está bem encaminhada, mas a parte de CI vai exigir uma boa pesquisa do seu lado. Cada um dos três grandes hyperscalers oferece ferramentas de CI, mas, sinceramente, esse não é o forte deles.
4\. Quem constrói, opera
"You build it — you run it" é praticamente regra em empresas pequenas, já que simplesmente não existe um muro de SRE para jogar as coisas por cima. A pergunta, portanto, não é quem é o dono da produção, mas sim como é a experiência de ser dono dos workloads em produção.
O legal é que, se você cuidou dos passos anteriores, ser dono da produção vai ser algo muito natural para o time. Vamos ver por quê:
- Você começou pela segurança, então já tem separação de perímetros estabelecida. Sabe onde procurar problemas; ou seja, situações em que código de desenvolvimento se conecta por acidente ao banco de produção e causa estragos simplesmente saem de cena.
- Sua arquitetura é realista e adequada ao seu time. É clara e fácil de entender. Por exemplo, você não mantém sistemas distribuídos complexos a menos que precise e tenha condições de cuidar deles à altura. Munido das suas ferramentas de observabilidade, consegue encontrar a origem dos problemas rapidamente.
- Seu CI é estável e confiável, e seu CD é tranquilo. Por isso, quando há um bug para corrigir, os processos de teste e deploy são rápidos, fáceis e livres de carga cognitiva e estresse. Isso minimiza o desgaste causado por bugs e evita a situação de Manutenção Contínua.
Suas aplicações já têm observabilidade embutida, então tudo o que você precisa fazer é configurar dashboards de monitoramento e definir alertas.
Um aspecto menos óbvio do ownership de produção, especialmente para os desenvolvedores, é o custo de operar o produto. Pessoalmente, acredito que os desenvolvedores devem entender os modelos de cobrança da nuvem e quanto seu software consome em dinheiro, pelas razões abaixo:
Evite surpresas na fatura
Você precisa entender o modelo de cobrança da nuvem para projetar seu sistema do jeito certo (bill shock, alguém?) — tanto a arquitetura da aplicação quanto a de CI/CD. Para fechar o ciclo, configure budgets e alertas de cobrança.
Conheça seu Custo Unitário
É muito útil para o pessoal de produto e vendas conhecer o seu "custo unitário". Por exemplo, se seu produto monitora dispositivos de borda, o "custo unitário" é quanto cada dispositivo monitorado contribui para sua fatura de nuvem. Esse número é muito útil para desenvolver modelos de negócio e tirar o achismo do planejamento de capacidade.
Com suas métricas de aplicação no lugar, geralmente é fácil ligar a lógica do seu app aos custos por meio de uma análise mais profunda dos dados de cobrança.
5\. Pessoas trabalham para pessoas
Adoramos nossos bits, bytes e lógica formal, mas, no fim das contas, somos um bando de humanos trabalhando juntos.
Entramos em startups porque acreditamos em algo e estamos animados com isso.
Gestores, confiem que seus desenvolvedores estão agindo com as melhores intenções. Questionem as ideias deles, mas deixem espaço para inovar. Fiquem atentos a sinais de que seus devs estão entrando em modo defensivo — a partir daí, toda funcionalidade de repente vira algo complexo de implementar, e seu projeto começa a estagnar.
Dá para falar de nuvens e tecnologia o dia inteiro, mas, se o trabalho não for prazeroso, a inovação não vai durar.