TriadWorks - Deploy automatizado: feito é melhor que perfeito
Todos estes anos de consultoria na TriadWorks nos fez perceber que a maioria das empresas e projetos não dão a importância devida para automatização dos seus processos de desenvolvimento. Tarefas rotineiras como build, deploy e release de novas versões da aplicação são feitas de forma totalmente manual. Todas essas tarefas deveriam ser simples e executadas diversas vezes por dia, mas na realidade elas são evitadas por causa do alto custo da sua execução e por medo de quebrar algo em produção.
Deploy significa disponibilizar a aplicação para uso. Por exemplo, um processo manual de deploy pode consistir em exportar um WAR no Eclipse, acessar a página de administração do Tomcat e fazer o upload do WAR.
Esses processos de desenvolvimento manuais, demorados e problemáticos já estão tão enraizados na cultura das empresas que todos consideram uma prática normal; o jeito difícil é o padrão e as equipes não conseguem enxergar que há espaço para melhorias. Essa zona de conforto das equipes é o que sempre nos preocupou, pois no final das contas são as empresas que estão pagando muito caro e entregando software com menor frequência.
No mundo Java não há mais desculpas para fazer build manual, já que podemos contar com ferramentas como Ant, Maven e Gradle para automatizar todo o processo. Estas ferramentas se preocupam em configurar, compilar e empacotar a aplicação em um arquivo JAR/WAR através de 1 ou 2 comandos. Por exemplo, numa aplicação Web para gerar o WAR via Maven basta executarmos o seguinte comando:
Este comando executará todas as fases de build de um projeto Maven: ele validará, compilará, rodará os testes automatizados, empacotará a aplicação num WAR e copiará este arquivo para um diretório pré-configurado. Tudo de forma automatizada!
Build manual traz inúmeros riscos para o projeto e automatizá-lo te ajudará a sanar a maioria deles! Sendo bem direto: fazer build pela IDE não é mais permitido para qualquer projeto minimamente sério.
Deploy manual também não vale
Apesar do build já ser uma prática comum, o deploy, que é um processo fundamental para entrega de software, ainda é deixado de lado e feito manualmente nos servidores da empresa ou do cliente. Para piorar, o deploy da aplicação normalmente fica na mão de 1 única pessoa, que por sua vez tem todo o passo a passo na cabeça. Basta ele sair da empresa que os diversos problemas relacionados a centralizar conhecimento aparecem.
Para maioria das empresas e projetos, o processo de deploy é algo muito simples. Não passa de uma lista de passos que devem ser executadas numa determinada ordem. Se você parar por um momento e escrever estes passos num arquivo TXT as chances são de que você acabe com uma lista muito parecida com a lista abaixo:
rodar o build para gerar o WAR;
fazer o upload do WAR gerado para o servidor de produção;
apagar o WAR antigo do Tomcat;
copiar o WAR novo para o Tomcat;
reiniciar o Tomcat;
Estes passos podem variar de acordo com a aplicação e ambiente de produção, mas no geral não foge muito desse script. Embora simples, executar cada passo manualmente além de demorado, abre brechas para erros bobos, como por exemplo esquecer de excluir o WAR antigo ou mesmo esquecer de parar o Tomcat antes de tudo. Como qualquer tarefa manual, quanto maior sua frequência maior são as chances de erros.
Por ser um processo demorado e arriscado, é comum que ele seja feito com menos frequência, o que vai de contra aos princípios ágeis na qual diz: se o processo incomoda então faça-o com maior frequência.
Se fazer tudo isso manualmente traz tantos problemas, por que as equipes não automatizam uma vez por todas?
Automatize seu deploy com Shell Script
Todas as vezes que sugerimos implementar um processo de deploy automatizado num projeto/empresa a equipe foi contra por achar que se tratava de algo complexo; a implementação sempre foi deixada para mais tarde.
Não é por acaso, quando pesquisamos sobre o assunto caímos em artigos com soluções sofisticadas com uso de ferramentas como Puppet, Chef, Ansible, ou servidores distribuídos nas nuvens via containers que se integram com caches, monitores, bancos de dados e sistemas externos. Some a isso os eventos onde os palestrantes apresentam soluções robustas e complexas, o que mina todo o tesão do desenvolvedor em querer automatizar o deploy na sua empresa. Principalmente quando ele está dando seus primeiros passos nas práticas de DevOps.
Não se engane, todas essas práticas e ferramentas são importantes, contudo você não precisa delas ao implementar seu primeiro deploy automatizado.
Independente do que muitos "experts" digam, você não precisa de Puppet, Chef, Docker ou outra tecnologia para ter um deploy automatizado; você não precisa aprender todas essas ferramentas de imediato, não no seu primeiro script de deploy. O que estou querendo dizer, é que uma simples solução em Shell Script para deployar sua aplicação em um servidor remoto via SSH resolve seu problema. Basta você enumerar todos os passos necessários para fazer o deploy e, em seguida, escrever seu script. Pegando os passos listados no inicio desse artigo como exemplo, nosso script não seria muito diferente deste:
# 1. rodar o build para gerar o WAR;
# 2. fazer o upload do WAR gerado para o servidor de produção;
scp build/war/MyApp-v2.4.war admin@myapp.com.br:/tmp/MyApp.war
# 3. parar o Tomcat;
ssh root@myapp.com.br '/tomcat_home/bin/shutdown.sh'
ssh root@myapp.com.br 'sleep 5'
# 4. apagar o WAR antigo do Tomcat;
ssh root@myapp.com.br 'rm -rf /tomcat_home/webapps/MyApp'
ssh root@myapp.com.br 'rm -rf /tomcat_home/webapps/MyApp.war'
# 5. copiar o WAR novo para o Tomcat;
ssh root@myapp.com.br 'cp MyApp.war /tomcat_home/webapps'
# 6. reiniciar o Tomcat;
ssh root@myapp.com.br '/tomcat_home/bin/startup.sh'
Repare que transcrevemos todos os passos manuais para um script automatizado; o que fazíamos manualmente agora a máquina fará para nós! A partir de agora basta executar este script do seu Terminal favorito e seu deploy acontecerá como um passe de mágica:
Dica: podemos diminuir a interação humana ao trabalhar com chave pública-privada para que o SSH não solicite a senha a cada comando. Dessa forma, podemos até mesmo rodar esse script num servidor de Integração Contínua como Jenkins ou TeamCity.
Você não precisa de muito conhecimento nem tempo para escrever um script shell; em algumas horas você aprende os comandos básicos e implementa um script para fazer o deploy da sua aplicação. Se brincar, nem isso você precisa! Basta copiar todos os comandos que você fazia no console para o script.
Não se envergonhe por não usar uma ferramenta da moda, como Ansible ou Chef. Para quem não tinha NADA, o bom e velho script shell é um grande começo! Você ficaria surpreso quantas coisas podemos fazer com este idoso!
Seja paciente, após amadurecer seu processo de deploy você pode investir algum tempo para aplicar padrões que diminuam o risco da implantação; usar ferramentas sofisticadas como Ansible para deployar a aplicação em múltiplos servidores; fazer backup dos dados na S3 da Amazon; evoluir o schema do banco; fazer o rollback em caso de erro etc. Em casos avançados, você pode fazer deploy do ambiente inteiro através de ferramentas de container como Vagrant ou Docker.
Enfim, fazer aquele deploy na sexta-feira às 17h não deveria ser mais problema quando temos um processo de deploy automatizado.
E aí, como você faz o deploy da sua aplicação? Você consegue aproveitar o script acima na sua empresa?