Recentemente na Operar, tivemos um tarefa bem
comum para quem trabalha com desenvolvimento web ou áreas afins. Criar
um servidor, configurar (servidor web, firewall, chaves públicas no
molho de chaves e etc) e deixa-lo rodando e também documentar as
configurações e processos. Fazer isso não é difícil, mas manter essas informações
organizadas e com fácil acesso para outros colaboradores, não é nada
simples apenas com scripts de automação e instruções em uma wiki interna,
por exemplo.
Uma wiki interna para que outras pessoas possam consultar/alterar e fazer o
seu trabalho, não é novo para alguns, entrentanto esse modelo abre
espaço para duas pedras no caminho. A primeira é a queda de
produtividade, pois por mais que tudo esteja bem documentado, ainda é
necessário um trabalho extra para atualizar tal documento com as últimas
alterações feitas, além de ter que fazer a tarefa em si. E o outro problema é a
quebra do fluxo de trabalho, pois dependendo das alterações é necessário
escrever instruções mais detalhadas e isso é cansativo, trabalhoso e
manter isso ativo entre todos os membros pode levar um certo tempo e
disciplina. Atualmente a cultura DevOps vem trazendo uma série de
melhorias em nossos Workflows, ferramentas mais "friendly" (como os .env
e YAML's da vida), diga-se de passagem. Ferramentas essas que além de
tirar o trabalho das execuções e documentações manuais, nos permiti versionar
suas configurações e usa-las como uma documentação do estado atual das coisas,
tanto na infraestrutura como nos serviços/containers.
Infraestrutura como código e deploy também!
Dado tal cenário e uma pesquisada, encontrei uma ferramenta chamada
Terraform que é uma espécie de construtor de
infraestrutura. Com ele você declara as configurações necessárias (e
suportadas pelo serviço de Cloud alvo) em um arquivo texto para depois
aplicar as mundanças necessárias (ou
plan
como ele chama) no serviço
provedor.
Isso inclui desde a configuração do servidor até ferramentas que ajuda a
compor a infra, como domínio, firewall, zona DNS e mais qualquer
coisa que esteja disponível no seu
provider.
Em um exemplo simples do Terraform em ação, crio um arquivo main.tr eu declaro
um servidor na Digital Ocean que tem tamanho, região, nome e
imagem de distribuição. E logo em mais a baixo, declaro também um domínio a
ser criado no serviço de DNS da Digital Ocean e atrelo ao domínio o IP do
servidor nomedado como all.
# main.tr
provider "digitalocean" {}
resource "digitalocean_droplet" "all" {
image = "docker-18-04"
name = "all"
region = "fra1"
size = "s-1vcpu-1gb"
}
resource "digitalocean_domain" "domain_name" {
name = "domain.tld"
ip_address = "${digitalocean_droplet.all.ipv4_address}"
}
O Terraform tem uma gama de possíbilidades para automatizar esses
processos mais burocráticos. É possível com ele gerenciar até o ciclo de
vida de containers, redes e volumes no Docker. Se o objetivo é usar
Docker em produção, isso ajuda, você pode estabelecer logo de início uma
rede padrão para sua aplicação, por exemplo.
Pós infra e tarefas cotidianas
Outra ferramenta ótima para automatizar processos,
como instalação de pacotes, deploy da aplicação, orquestração, regras
de permissões (Linux), entre outra infinidade de possíbilidades é o
Ansible. Basicamente por meio de uma
conexão SSH, ele executa as tarefas declaradas em um arquivo YAML. Junto
com vários módulos incluidos nele, é possível
deixar fluxo de trabalho bem mais produtivo e menos oneroso, basta
organizar tudo certinho no
playbook e
ninguém sai sem deploy.
Os playbooks, seriam um conjuto de tarefas que irão ser executadas um
determinado inventário (lista de servidores que irão receber a conexão
e execução das tarefas). As tarefas podem ser
aplicadas tanto para todos ou somente para alguns, além disso, ele
também é escrito em YAML, assim como o
inventário.
Vejamos um exemplo de um playbook que reinicia ou cria um container com
um servidor web e já linka os volumes, e faz sempre pull dos commits de
algum repositório git.
# playbook.yml
---
- hosts: all
tasks:
- name: Update last version -> GIT
git:
repo: 'https://gitlab.com/gutierri/webapp.git'
dest: /srv/webapp
version: master
- name: Container webapp -> NGINX
docker_container:
image: nginx:1.15
name: webapp
state: started
restart: yes
exposed_ports:
- 80
env_file: /var/tmp/webapp/webapp.env
volumes:
- "/srv/webapp:/usr/share/nginx/html:ro"
E aqui temos o inventário (também chamado de hosts) com os servidores
alvo (webapp.local pode ser seu domínio ou IP e com conexões SSH
devidamente configuradas préviamente).
# hosts.yml
all:
hosts:
webapp.local:
Bata tudo e junte em um Makefile!
Bem, temos um toolchain bem bacana que ajusta os serviços relacionados
a infra e afins, e deploy da aplicação em um servidor web. Costumo
manter a execução das tarefas o mais simples e "esperto" possível e
dificilmente uma única ferramenta vai resolver todos os problemas, afim
de diminuir, por exemplo, o número de diferentes comandos de ferramentas
distintas que preciso lembrar. E o GNU Make meio que contorna isso, pois
posso definir uma série de comandos agrupados ou não e nomea-los pra serem executados de uma vez, a
partir daí é necessário lembrar e rodar apenas um único comando para
executar tarefas mais objetivas (as mais comuns como: deploy release e
status).
infra-deploy:
terraform apply
infra-status:
terraform plan
app-deploy:
ansible-playbook -i hosts.yml playbook.yml
all:
@echo "infra-deploy infra-status deploy"
.PHONY: infra-deploy infra-status deploy