
Criamos uma ferramenta que integra o Docker e o Maven para ajudar centenas de nossos desenvolvedores a gerenciar ambientes complexos de desenvolvimento com centenas de serviços, enquanto fazem um esforço mínimo. Esta é uma história sobre como uma ideia maluca se tornou realidade. Esta é a história de
Carnotzet .
Tudo começou há cerca de cinco anos (aproximadamente data de publicação em 3 de agosto de 2017), a Swissquote cresceu e se desenvolveu rapidamente. Naquela época, tínhamos cerca de 70 desenvolvedores trabalhando em projetos Java grandes (aproximadamente monolíticos), exigindo que cada um deles passasse de 1 a 2 dias para configurar o lançamento do projeto localmente. Detestamos perder tempo com tarefas repetitivas! Portanto, foi decidido melhorar esse processo usando o Vagrant e o Chef para automatizar a implantação do nosso ambiente de desenvolvimento local. Isso marcou o início de nosso primeiro projeto Sandbox (Sandbox, aprox.)
Gostaríamos de compartilhar ambientes de desenvolvimento e teste leves, reproduzíveis, isolados e portáteis.
Por um tempo, tudo ficou tranquilo. Os desenvolvedores poderiam simplesmente fazer o download do projeto, executar "vagrant up" e começar a trabalhar. Usamos essa abordagem por cerca de dois anos e ficamos bastante satisfeitos.
Posteriormente, o trabalho nessas grandes aplicações se tornou mais difícil devido ao fato de a lógica de negócios se tornar mais complexa (etiqueta branca de nossa plataforma de negociação). E decidimos fazer o que a maioria das organizações fez em 2014: quebrar a lógica em microsserviços.
Tudo correu bem e, em 2016, tínhamos cerca de 150 serviços (micro, aprox.) Em produção. Mas os scripts do Chef usados para configurar as máquinas virtuais cresceram e estão fora de controle. Os ambientes de desenvolvimento tornaram-se muito mais complicados para alguns aplicativos com cerca de 30 dependências. Também descobrimos que o conhecimento do Chef não fazia parte do conjunto padrão de habilidades de nossos desenvolvedores. Por esse motivo, muitas pessoas simplesmente fizeram o script funcionar, às vezes, copiando exemplos ruins. Tentando não quebrar a configuração de outras equipes, eles criaram brunches de longa duração para suas próprias necessidades de equipe e, como resultado, o código de configuração do ambiente de desenvolvimento não era mais público.

Nós tivemos que consertar isso.
As seguintes fraquezas da nossa caixa de proteção foram identificadas:
- Precisa conhecer o Chef. E para desenvolvedores existentes e para iniciantes, aprender essa estrutura foi um prazer bastante caro.
Além disso, isso era redundante apenas para o ambiente de desenvolvimento / teste. - Não havia como fácil abstração / composição ou reutilização de parte da configuração do ambiente. Isso levou ao fato de que as pessoas tiveram que se aprofundar em todos os detalhes e nuances da configuração de dependência de seus projetos, que geralmente eram suportados por outras equipes. Isso levou a discordâncias e interação desnecessária entre as equipes.
Para corrigir o primeiro ponto, foi decidido mudar para o Docker. Ele tem um limite de entrada mais baixo e também oferece outros benefícios, como padronização, suporte a PaaS e implantação mais fácil em vários ambientes.
Também consideramos usar apenas docker-compose. Parecia muito promissor, mas, apesar do nome, carecia de possibilidades de composição e, ao mesmo tempo, de abstração e reutilização. São esses aspectos que precisamos. Sonhamos com a capacidade de pegar o ambiente de desenvolvimento / teste existente, adicionar um serviço a ele e, opcionalmente, redefinir parte de sua configuração. Queríamos conseguir isso sem ter que copiar a configuração do serviço adicionado ou nos aprofundar nos detalhes das dependências transitivas e suas configurações.
Foi então que tivemos a ideia: “E se pegarmos o Maven, o sistema de gerenciamento de dependências que usamos para criar nossos aplicativos java, e começarmos a usá-lo para criar nossos ambientes?” Isso nos permitiria abstrair nossas dependências transitivas, configurações de pacotes, criar versões delas e reutilizá-las. Também não será necessário aprender um novo sistema de gerenciamento de dependências.
Após várias tentativas, chegamos à seguinte solução:
- Cada artefato do Maven representa um ambiente totalmente funcional que pode ser usado como uma dependência em outros ambientes. (o ambiente mínimo pode ser representado por um serviço, por exemplo, um banco de dados)
- Os arquivos JAR contêm configuração. Variáveis de ambiente, arquivos de configuração do aplicativo, nome do Docker de imagem etc.
- Essa configuração pode ser substituída em módulos localizados mais alto na hierarquia de dependências, se necessário.
- A biblioteca Java pode elevar o ambiente completo (usando o docker-compose under the hood) de um módulo Maven (GAV ou pom.xml)
O Maven torna possível distribuir e versão desses artefatos (“artefatos do ambiente”) e podemos compartilhar facilmente o código fonte entre as equipes. O processo ficou mais simples e os desenvolvedores começaram a usar módulos de outras equipes. E também crie e mantenha o seu próprio.
Como bônus, todas as ferramentas que facilitam o trabalho com o Maven podem ser usadas aqui. Como exemplo, o gráfico de dependência gerado usando o IntelliJ IDEA agora nos mostra um diagrama da arquitetura para a interação de nossas dependências :)

Arquitetura de um exemplo de
aplicativo de votação do docker-composeAo mesmo tempo, houve algumas dificuldades de implementação, como forçar todas as equipes a empacotar aplicativos usando o Docker (dockerize) e as configurações de pacotes em módulos Maven separados. Por todas as contas, ficou mais fácil importar aplicativos de outras equipes e oferecer suporte a ambientes de desenvolvimento complexos.
Começamos a trabalhar nessa direção há cerca de um ano e agora temos cerca de 200 desses módulos usados para desenvolvimento e teste. Chegamos à conclusão de que essa biblioteca também é ótima para gerenciar o ambiente temporário para testes de ponta a ponta em nossa plataforma de CI.
Atualmente, estamos estudando como reutilizar essa tecnologia para gerenciar nossos ambientes de integração / UAT, lançando contêineres no Kubernetes em vez de compor o docker, e assim garantir atualizações contínuas e elasticidade da computação em ambientes significativamente maiores.
Espero que você fique feliz em saber que nosso projeto foi aberto sob a licença Apache 2.0 e está disponível no Github:
github.com/swissquote/carnotzetUse :)