O Twelve-Factor App é uma metodologia desenvolvida por Adam Wiggins, cofundador da Heroku, que concentra uma série de melhores práticas obtidas com base na experiência da empresa, durante o desenvolvimento e deploy de uma série de aplicações SaaS.
Atualmente ele possui uma grande adoção em sistemas distribuídos, principalmente microsserviços, pois suas práticas e estratégias permitem a evolução destes sistemas de forma consistente, portável e performática.
Como o nome já diz, as melhores práticas são 12. Abaixo falaremos um pouco sobre cada uma delas.
1) Base de Código
A ideia nesta prática é a utilização de um VCS para controlar a base de código (como o Git, Subversion e o Mercurial), seguindo sempre a regra de um-para-um: uma aplicação = uma base de código. Segundo a metodologia, não devemos ter múltiplas apps em uma mesma base de código, e se tivermos diversas bases, cada uma delas deverá ser a base de um app compatível com o Twelve-Factor App.
Outro aspecto importante é que a mesma base de código deve permitir vários deploys, em qualquer ambiente, em diversas versões.
2) Dependências
A segunda prática fala sobre o gerenciamento de dependências. Uma aplicação nunca deve necessitar de dependências implícitas existentes no sistema. Ela deve declarar explicitamente através de um manifesto, deixando claro o que é necessário para sua execução/publicação. Isso é importante para garantir a consistência das dependências em todos os seus deploys. Praticamente toda linguagem moderna possui um gerenciador de pacotes que resolve esta questão.
A metodologia explica também a importância existente no isolamento das dependências. Isso implica em evitar que alguma dependência indesejável, inerente ao sistema, seja utilizada pela aplicação. Algumas linguagens possuem ferramentas para isto, como o Python que possui o VirtualEnv.
3) Configuração
Aqui a metodologia trata sobre gerenciamento de configurações. Na prática, configurações são os aspectos que variam na aplicação de deploy para deploy, como credenciais e conexões de bancos de dados. Esta separação deve ser bem clara.
Configurações hardcoded são consideradas uma péssima prática, mas a metodologia também fala sobre problemas em arquivos de configuração, como formatos específicos e controle de atualização. A sugestão é a utilização de variáveis de ambiente para armazenar estas configurações, visto que são agnósticas a tecnologia e são fáceis de serem isoladas e visualizadas.
4) Serviços de Apoio
A próxima prática explica como a aplicação deve se relacionar com serviços de apoio (bancos de dados, serviços de mensageria, ou qualquer outro serviço externo a aplicação). Devemos desenvolver a aplicação mantendo o baixo acoplamento com estes serviços, de forma que, para substituí-los, alterações na base de código não sejam necessárias, bastando pequenas alterações em configurações.
5) Construa, lance, execute
Aqui a metodologia sugere que exista uma separação clara entre as etapas necessárias para colocarmos uma versão em execução. Do mais complexo para o mais simples:
- Construção (build): a partir de uma versão da base de código devem ser obtidas e construído o pacote com os ativos;
- Lançamento (release): une o pacote gerado na etapa anterior, com as devidas configurações, preparando o ambiente para ser executado;
- Execução (run): inicia os processos no ambiente de execução, disponibilizando a aplicação para uso.
Os lançamentos devem ser imutáveis e devidamente identificados. A imutabilidade permite facilmente a execução de rollbacks em caso de falhas.
6) Processos
A metodologia diz que os processos gerados por uma aplicação devem ser stateless, ou seja, não armazenar estado. Qualquer persistência necessária deve ser delegada a um serviço de apoio, como um banco de dados.
Se necessário, é possível fazer um pequeno cache em memória, para determinadas transações, mas a aplicação não deve presumir que este cache estará disponível futuramente, pois ele é incerto.
Isso é extremamente importante em sistemas distribuídos, onde recursos podem ser voláteis e sujeitos a regras de balanceamento de carga.
7) Vinculo de Portas
Para o Twelve-Factor App, a aplicação deve ser autocontida. Devemos expor a aplicação através de uma vinculação de porta (como http://localhost:3001), sem depender de recursos externos para tal (como um servidor web existente nos ambientes de execução). Isso possibilita que nossa aplicação se torne um serviço de apoio por si só, e seja utilizada por outros serviços.
8) Concorrência
Aqui a metodologia sugere que, ao desenvolver nossa aplicação, nos preocupemos em projetá-la como processos pequenos, um para cada carga de trabalho. Isso facilita que a aplicação trabalhe com scale out/in dos devidos processos, sem necessariamente fazer scale up/down da infraestrutura.
9) Descartabilidade
Segundo a metodologia, processos devem ser descartáveis. Devemos garantir a inicialização rápida e o desligamento gracioso, encerrando qualquer procedimento interno, e consequentemente evitando inconsistências. Os processos também devem estar preparados para falhas catastróficas. Para isto podemos utilizar algum serviço de mensageria, servindo de buffer de tarefas.
10) Paridade Dev/Prod
O Twelve-Factor foi arquitetado com implantação continua em mente, visando reduzir as diferenças entre DEV e PROD em três aspectos distintos:
- Temporal: Permitir o deploy de uma alteração em um curto espaço de tempo (minutos, horas);
- Pessoal: Em uma cultura DevOps, as pessoas que desenvolvem o código e as pessoas que operacionalizam os deploys são as mesmas, ou estão próximas delas;
- Ferramentas: Os ambientes devem ser idênticos, na medida do possível. Isso garante que a aplicação terá o mesmo comportamento em todos eles, sem sofrer consequências por versões ou ferramentas diferentes.
11) Logs
A aplicação não deve se preocupar com o gerenciamento dos arquivos de log. Ela deve escrever as entradas em um fluxo (como o stdout), que será tratado e encaminhado pelo ambiente de execução às devidas ferramentas (como o CloudWatch da AWS). Nas ferramentas, os logs podem ser agregados e disponibilizados para consulta e análise.
12) Processos Administrativos
Um processo administrativo, como aplicar uma database migration em determinado ambiente, deve ser aplicado como um processo único e pontual, no próprio ambiente. Desta forma, ele irá executar com as mesmas características dos processos de longa duração daquele ambiente.
Conclusão
O Twelve-Factor foi publicado no final de 2011, então não é uma metodologia nova, mas oferece uma base sólida de práticas para utilizarmos no desenvolvimento, que auxiliam na evolução de aplicações oferecidas como serviço (mas não se limitando a esta categoria). Com o constante crescimento deste tipo de produto, a metodologia se faz cada vez mais importante e necessária. E você? Aplica o Twelve-Factor? Deixe seu comentário!
Grande abraço e até a próxima!