Pipeline de CI/CD: projetando o seu próprio robô de deployment

Automação não é algo desconhecido

Da última vez, aprendi uma lição dura por meio de 10 minutos de downtime e de um relatório de incidente. Deployment não é mágica: ele precisa ser uma sequência de dispositivos de segurança rigorosos, “Git, registro – Test, validação – Build, empacotamento – Deploy, entrega”.

Agora o objetivo ficou claro. Eu não posso continuar verificando com as minhas próprias mãos, toda vez, esses dispositivos de segurança complexos e irritantes. Preciso de um “robô diligente” que trabalhe por mim mesmo depois que eu for embora ou quando eu estiver de férias.

“Automação? Isso não é grandioso demais?”

No começo, isso me assustou, mas pensando bem, eu já tinha experimentado algo muito parecido. Era o “Docker”, que vimos na série anterior.

Quando escrevemos em um Dockerfile “instale o Ubuntu, instale o Java, copie o código”, o Docker lê isso e monta sozinho o ambiente do servidor. Graças a isso, fomos libertados do trabalho braçal de ficar digitando comandos manualmente.

Um “pipeline de CI/CD” funciona exatamente da mesma forma. Se o Docker automatizou a “configuração do servidor”, o pipeline automatiza “todo o processo de deployment”. A única diferença é que o palco ficou maior: saiu do meu computador para um mundo mais amplo chamado “GitLab e servidor de produção”.

Se o Dockerfile é o manual de montagem do servidor, o pipeline é o manual de operação da fábrica.

CI/CD: a esteira automatizada

Agora vamos instalar uma “linha de automação” no nosso “centro logístico digital”. Parece grandioso, mas o princípio é simples.

1. CI (Continuous Integration, integração contínua)

  • Significado: “Juntar continuamente o código dos desenvolvedores em um só e verificá-lo.”
  • Papel: [Build + Test]. É a etapa em que, assim que eu envio o código, a máquina confere: “A sintaxe está certa?”, “Alguma funcionalidade existente quebrou?”. Os produtos defeituosos são barrados aqui.

2. CD (Continuous Delivery/Deployment, entrega ou deployment contínuos)

  • Significado: “Entregar ao cliente o código que já passou pela verificação.”
  • Papel: [geração da imagem + deployment no servidor]. É a etapa em que o produto aprovado na verificação (Docker Image) é carregado no caminhão, enviado ao servidor de produção e colocado para rodar.

O projeto da pipeline: .gitlab-ci.yml

“Então, como é que damos trabalho a esse robô?” No GitLab, basta criar um arquivo chamado .gitlab-ci.yml na raiz do projeto. Esse é exatamente o “roteiro de trabalho” que será entregue ao robô.

Lembra da dor do deployment manual que eu enfrentei da última vez? Vamos transformar exatamente esse processo em código. Assim como ao escrever um Dockerfile, basta ir registrando tudo linha por linha.

# .gitlab-ci.yml (a folha de tarefas)

stages:          # 1. Define a ordem total do trabalho
  - test         #   (Etapa 1: verificacao)
  - build        #   (Etapa 2: empacotar)
  - deploy       #   (Etapa 3: entrega)

# [Etapa 1] Test: maquina, verifica se meu codigo esta ok (CI)
unit_test_job:
  stage: test
  image: openjdk:17-alpine # Executar em um ambiente com Java instalado
  script:
    - ./gradlew test       # "Roda os testes!" (evita o erro anterior)

# [Etapa 2] Build: se os testes passarem, gere uma imagem (CI)
build_image_job:
  stage: build
  image: docker:latest     # Executar em um ambiente com Docker instalado
  script:
    - docker build -t my-app:v1 .  # "Cria a imagem!"
    - docker push my-regisry/my-app:v1 # "Envie para o registry!" (tag de rollback obrigatoria)

# [Etapa 3] Deploy: agora coloca isso no servidor de producao (CD)
deploy_job:
  stage: deploy
  script:
    - ssh user@server "docker service update my-app" # "Atualiza o servidor!"

Esse único arquivo basta. No momento em que eu faço um git push, ou seja, no trigger, o GitLab lê esse roteiro e acorda um robô operário chamado “GitLab Runner” para colocá-lo para trabalhar.

[Check] Os dispositivos de segurança que precisamos garantir

Dentro dessa pipeline estão incorporados os três dispositivos de segurança que eu senti na pele da última vez.

  1. Git (Trigger):
    • O próprio ato de eu dar push no código a partir da minha máquina local vira o “botão de início” da pipeline. Se não ficar um registro (Commit), o deployment também não começa.
  2. Unit Test (Quality Gate):
    • E se o teste falhar no unit_test_job? A pipeline “para” na hora (Fail). Isso bloqueia na raiz a passagem de produtos defeituosos para a etapa seguinte (build/deploy). (Agora não dá mais para pular os testes com a desculpa de estar ocupado!)
  3. Docker Image (Artifact):
    • A imagem gerada na etapa de build fica guardada com segurança no Docker Hub. Mesmo que o servidor caia mais tarde, basta ter essa imagem para recuperar tudo em 1 segundo.
Um código que não passa nos testes jamais pode ser carregado no caminhão de deployment.

Conselho prático: pipeline é um ser vivo

Não tente escrever uma pipeline perfeita desde o começo. Eu mesmo, no início, criei apenas duas etapas, build e deploy, e só depois de causar um incidente é que acrescentei a etapa de test antes delas.

  • Fase inicial: build -> deploy (o importante, por enquanto, era automatizar)
  • Fase intermediária: test -> build -> deploy (dispositivo de segurança adicionado)
  • Fase avançada: test -> análise estática (SonarQube) -> build -> deploy no servidor de desenvolvimento -> (aprovação) -> deploy no servidor de produção

Uma pipeline é um “sistema vivo” que continua evoluindo de acordo com o ritmo de crescimento da nossa equipe.

Encerrando: escrevemos as instruções, mas quem realmente trabalha?

Agora o projeto perfeito, .gitlab-ci.yml, está pronto. Mas um roteiro escrito no papel não se move sozinho. Assim como um Dockerfile ainda precisa do Docker Daemon instalado para poder rodar, o roteiro da pipeline também precisa de um “robô de chão de fábrica” que realmente sue para construir e executar o código.

O nome desse robô é “GitLab Runner”. O gerente da fábrica, ou seja, o GitLab Server, apenas dá as instruções. O trabalho de verdade é executado por esse runner.

Na próxima vez, vamos instalar esse runner no meu computador ou em um servidor separado, conectá-lo ao GitLab e colocar a pipeline para funcionar de verdade. Finalmente é o momento em que o primeiro botão da automação é abotoado.

Deixe um comentário