Pular para o conteúdo
    ← Todos os Insights

    Infraestrutura & Cloud

    CI/CD: como funciona uma pipeline moderna de desenvolvimento e infraestrutura

    Entenda como funciona uma pipeline moderna de CI/CD, desde o commit no Git até build, testes, artifacts, approvals, secrets, deployment, validação e rollback.

    Por Thiago Henrique ·

    Uma pipeline de CI/CD não é apenas um arquivo YAML que executa comandos depois de um commit.

    Ela representa o processo pelo qual uma mudança deixa o repositório, passa por validações, produz um artefato, atravessa ambientes e chega à produção de forma controlada.

    Quando esse fluxo não existe, grande parte da entrega depende de ações manuais: alguém compila a aplicação, copia arquivos, altera configurações, acessa um servidor, executa scripts, reinicia serviços e depois verifica se tudo continua funcionando.

    Esse modelo pode funcionar em ambientes pequenos.

    O problema aparece quando a frequência de mudanças aumenta, diferentes pessoas começam a atuar no mesmo sistema e desenvolvimento, homologação e produção deixam de possuir exatamente as mesmas características.

    Uma pipeline moderna procura transformar esse processo em algo reproduzível.

    O fluxo pode ser resumido assim:

    commit → validação → build → testes → artifact → homologação → aprovação → produção → validação

    Mas cada uma dessas etapas possui responsabilidades diferentes.

    É isso que vamos analisar.

    A pipeline começa antes do deploy

    CI/CD costuma ser associado diretamente ao deployment.

    Na prática, o processo começa antes.

    Uma alteração normalmente nasce em um repositório Git.

    O desenvolvedor cria uma branch, modifica arquivos, realiza commits e envia essas alterações para o repositório remoto.

    A partir daí, diferentes eventos podem iniciar uma pipeline.

    Um push em determinada branch pode disparar uma execução.

    A abertura ou atualização de um Pull Request ou Merge Request pode iniciar testes.

    Um merge na branch principal pode gerar um build.

    Também podem existir execuções manuais ou agendadas.

    No GitHub Actions, workflows podem ser executados a partir de eventos do repositório. No GitLab CI/CD, pipelines também podem ser iniciadas por commits, merge requests, schedules ou manualmente.

    O trigger define quando o processo começa.

    Mas iniciar uma pipeline não significa executar tudo indiscriminadamente.

    Uma boa configuração precisa decidir quais etapas são apropriadas para cada evento.

    Por exemplo:

    Pull Request → lint + testes + análise de segurança

    merge em main → build + artifact + homologação

    release aprovada → produção

    Isso evita gastar recursos executando ações desnecessárias e reduz o risco de uma alteração inadequada chegar ao ambiente errado.

    Stages, jobs e steps organizam o processo

    Os nomes variam entre plataformas, mas o conceito é semelhante.

    Uma pipeline é dividida em blocos lógicos.

    Um stage representa uma grande fase do processo.

    Build, Test, Security e Deploy são exemplos comuns.

    Dentro de cada stage podem existir um ou mais jobs.

    Um job é uma unidade de execução com uma responsabilidade específica.

    Dentro dele existem comandos ou steps.

    Um modelo simples poderia ser:

    Stage: Build

    • instalar dependências

    • compilar aplicação

    • gerar pacote

    Stage: Test

    • testes unitários

    • testes de integração

    • lint

    Stage: Security

    • análise de dependências

    • verificação de código

    • validação de imagens

    Stage: Deploy

    • publicar artefato

    • atualizar ambiente

    • validar aplicação

    No GitLab CI/CD, jobs são os elementos fundamentais de uma pipeline, executados por runners. Os jobs podem ser agrupados em stages; stages normalmente seguem uma sequência, enquanto jobs de um mesmo stage podem executar em paralelo.

    O Azure Pipelines utiliza uma organização semelhante, com stages contendo jobs e tasks, além de dependências, condições e mecanismos de aprovação.

    Essa divisão é importante porque torna o processo compreensível.

    Quando uma pipeline falha, a pergunta deixa de ser apenas “o deploy deu erro?”.

    Passa a ser possível identificar:

    em qual stage?

    em qual job?

    em qual comando?

    Essa visibilidade reduz o tempo de investigação.

    Uma pipeline moderna organiza a entrega em etapas rastreáveis, conectando trigger, stages, jobs, artifacts, environments e feedback contínuo.

    Build transforma código em algo implantável

    Depois que o código é validado inicialmente, uma das etapas mais comuns é o build.

    Dependendo da tecnologia, isso pode significar operações diferentes.

    Uma aplicação Java pode gerar um JAR ou WAR.

    Uma aplicação .NET pode produzir arquivos compilados.

    Uma aplicação frontend pode gerar arquivos estáticos.

    Um projeto baseado em containers pode gerar uma imagem Docker.

    O ponto central é que o build transforma o código-fonte em algo que pode ser distribuído ou executado.

    Essa etapa também precisa ser reproduzível.

    Se um build depende de configurações locais, bibliotecas instaladas manualmente ou versões não controladas, a pipeline perde parte de sua previsibilidade.

    Por isso, ambientes de build normalmente definem versões de runtime, dependências e comandos necessários para produzir o resultado esperado.

    Na AWS, o CodeBuild utiliza arquivos buildspec para definir fases, comandos, variáveis e artifacts do processo de build.

    Artifact é o resultado que atravessa a pipeline

    Depois do build, é comum surgir um artifact.

    Artifact é o resultado produzido por uma etapa e consumido pelas próximas.

    Pode ser:

    • pacote da aplicação;

    • arquivo compilado;

    • relatório de testes;

    • imagem de container;

    • template;

    • binário;

    • arquivos estáticos.

    Esse conceito é importante porque uma pipeline madura procura promover o mesmo artefato entre ambientes.

    Imagine que o sistema seja compilado novamente antes de cada deploy.

    O build de homologação poderia utilizar dependências diferentes do build de produção.

    Mesmo partindo do mesmo código, os resultados não seriam necessariamente idênticos.

    Uma estratégia mais previsível é:

    código → build → artifact versionado → homologação → produção

    O GitLab permite que jobs armazenem arquivos e diretórios como artifacts, que podem ser utilizados por etapas posteriores da pipeline.

    A ideia não é apenas guardar arquivos.

    É garantir continuidade entre as etapas.

    Testes precisam impedir que erros avancem

    Automatizar deployment sem automatizar validações apenas aumenta a velocidade com que problemas podem chegar à produção.

    Por isso, testes ocupam uma posição central dentro da pipeline.

    Um fluxo pode incluir:

    lint → testes unitários → testes de integração → testes de API → testes funcionais

    Nem todo projeto precisa executar todos esses testes.

    A escolha depende da aplicação, do risco e do custo de execução.

    O importante é que uma falha relevante interrompa o fluxo.

    Se os testes falham, o artifact não deveria seguir para as próximas etapas como se nada tivesse acontecido.

    Esse princípio transforma a pipeline em um mecanismo de controle.

    Não é apenas automação.

    É automação com critérios.

    Quality gates adicionam critérios antes de avançar

    Nem toda validação precisa ser um simples teste que retorna sucesso ou falha.

    Uma pipeline também pode trabalhar com gates.

    Por exemplo:

    • cobertura mínima de testes;

    • ausência de vulnerabilidades críticas;

    • análise de código aprovada;

    • artifact assinado;

    • revisão humana;

    • mudança autorizada.

    Esses mecanismos são especialmente úteis antes de ambientes críticos.

    Um pipeline pode passar por todas as verificações automáticas e ainda exigir uma aprovação manual antes de produção.

    Isso não contradiz automação.

    Automação não significa remover decisões humanas de todos os pontos.

    Significa automatizar aquilo que pode ser executado de forma confiável e manter controles onde eles realmente fazem sentido.

    Approvals criam uma barreira controlada antes da produção

    Imagine que uma nova versão passou pelos testes e foi implantada em homologação.

    Ela está tecnicamente pronta para produção.

    Mas a organização pode exigir revisão de change management ou confirmação de uma equipe responsável.

    Nesse caso, a pipeline pode parar.

    Somente depois da aprovação o processo continua.

    No AWS CodePipeline, por exemplo, é possível adicionar uma ação de aprovação manual em um stage. A execução fica aguardando até que alguém autorizado aprove ou rejeite a continuação.

    O Azure Pipelines também permite utilizar aprovações e gates associados às etapas de deployment.

    Esse modelo cria rastreabilidade.

    Em vez de alguém realizar um deploy manual fora da pipeline, a própria pipeline registra que houve uma aprovação antes da mudança.

    Secrets não deveriam aparecer no YAML

    Pipelines frequentemente precisam acessar recursos protegidos.

    Um job pode precisar autenticar em:

    • cloud;

    • registry de containers;

    • banco de dados;

    • API;

    • servidor;

    • repositório de artifacts.

    Isso exige credenciais.

    O erro é tratar essas credenciais como configuração comum.

    Senhas, tokens e chaves não deveriam ser gravados diretamente no arquivo da pipeline.

    O GitHub Actions possui secrets em níveis como repositório, organização e environment.

    O Jenkins oferece gerenciamento de credentials para que pipelines utilizem autenticação sem precisar inserir usuário e senha diretamente no Jenkinsfile.

    No AWS CodeBuild, a própria documentação recomenda que valores sensíveis sejam obtidos através do AWS Systems Manager Parameter Store ou AWS Secrets Manager, em vez de variáveis em texto puro.

    O princípio é simples:

    a pipeline precisa usar o segredo sem transformar o segredo em código.

    Também é importante limitar permissões.

    Uma pipeline usada apenas para publicar uma aplicação não deveria automaticamente possuir privilégios administrativos sobre toda a infraestrutura.

    Ambientes representam níveis diferentes de risco

    Desenvolvimento, homologação e produção não deveriam ser tratados da mesma forma.

    Cada ambiente possui uma finalidade.

    Desenvolvimento permite mudanças frequentes e experimentação.

    Homologação aproxima o sistema das condições esperadas de produção e permite validações adicionais.

    Produção atende usuários e normalmente exige controles mais rígidos.

    A pipeline pode refletir essa diferença.

    Por exemplo:

    dev → deploy automático

    homologação → deploy automático após testes

    produção → approval + deploy controlado

    Também podem existir variáveis, secrets e permissões específicos para cada ambiente.

    Isso evita situações como utilizar uma credencial de produção em um job de desenvolvimento.

    O mesmo artifact deveria avançar entre ambientes

    Esse é um ponto frequentemente ignorado.

    Imagine uma aplicação aprovada em homologação.

    Depois da aprovação, a pipeline executa novamente o build para produção.

    Tecnicamente, você não está promovendo exatamente aquilo que foi testado.

    Está produzindo outro artifact.

    Uma abordagem mais segura é gerar o artifact uma única vez e promovê-lo.

    O fluxo fica:

    commit → build → artifact v1.4.2 → homologação → aprovação → produção

    A aplicação implantada em produção é exatamente a mesma que passou pelas validações anteriores.

    Configurações específicas do ambiente continuam podendo mudar.

    Mas o código entregue permanece consistente.

    GitHub Actions integra workflow e repositório

    O GitHub Actions trabalha diretamente integrado aos repositórios GitHub.

    Workflows são definidos normalmente em arquivos YAML dentro de .github/workflows.

    Eles podem reagir a eventos como push, Pull Request, tags ou execução manual.

    Um workflow possui jobs, e cada job possui steps.

    Esses jobs podem utilizar runners hospedados pelo GitHub ou runners próprios.

    Para times que já utilizam GitHub como repositório, essa integração reduz a quantidade de plataformas necessárias para iniciar uma pipeline.

    Branch protection, Pull Requests, environments e secrets podem fazer parte do mesmo fluxo.

    GitLab CI/CD concentra o ciclo dentro do GitLab

    O GitLab CI/CD utiliza normalmente o arquivo .gitlab-ci.yml.

    Nele são definidos stages, jobs, regras, artifacts, variables e outras características da pipeline.

    Os jobs são executados por runners.

    Uma configuração simples pode possuir:

    build → test → deploy

    Mas projetos maiores podem criar fluxos muito mais complexos, com jobs paralelos, environments diferentes, artifacts e dependências entre etapas.

    Uma das vantagens desse modelo é manter repositório, Merge Requests e CI/CD fortemente integrados.

    Jenkins continua relevante em ambientes corporativos

    O Jenkins possui uma característica diferente.

    Ele não está necessariamente associado a uma única plataforma de repositório ou cloud.

    Isso permite integrar diferentes sistemas, ferramentas e ambientes.

    Pipelines podem ser definidas através de Jenkinsfile e integrar Git, registries, ferramentas de build, scanners, servidores, clouds e diversos outros componentes.

    Essa flexibilidade também traz responsabilidade.

    Uma instalação Jenkins precisa ser mantida.

    Plugins precisam ser administrados.

    Credenciais precisam ser protegidas.

    Agents precisam ser dimensionados.

    Permissões precisam ser controladas.

    Por isso, Jenkins continua sendo muito útil em arquiteturas que exigem forte customização ou integração com ambientes heterogêneos.

    Azure Pipelines conecta desenvolvimento e ecossistema Microsoft

    O Azure Pipelines faz parte do Azure DevOps.

    Ele pode trabalhar com diferentes linguagens, sistemas operacionais e destinos de deployment.

    Stages, jobs, tasks, environments, approvals e variables podem ser combinados para estruturar fluxos de entrega.

    Em organizações que já utilizam Azure DevOps para Boards, Repos ou gestão de projetos, pipelines podem fazer parte de uma plataforma mais ampla de engenharia.

    Também existe integração natural com recursos Azure, embora o pipeline não esteja limitado à cloud da Microsoft.

    AWS CodePipeline orquestra serviços de entrega

    Na AWS, CodePipeline atua como serviço de orquestração da pipeline.

    Ele pode conectar diferentes etapas e serviços.

    Um fluxo típico pode ser:

    Source → CodeBuild → Test → Approval → Deploy

    O CodeBuild executa tarefas de build e testes.

    Artifacts podem ser transferidos entre stages.

    Aprovações manuais podem interromper o fluxo antes da produção.

    Outros serviços AWS podem participar da entrega dependendo da arquitetura.

    Esse modelo é interessante porque separa a orquestração das ações que cada etapa precisa executar.

    Uma pipeline também pode entregar infraestrutura

    CI/CD não serve apenas para aplicações.

    Infraestrutura como código também pode utilizar pipeline.

    Imagine um repositório Terraform.

    Uma mudança é enviada através de Pull Request.

    A pipeline pode executar:

    terraform fmt → terraform validate → terraform plan

    O resultado do plan pode ser revisado.

    Depois da aprovação:

    terraform apply

    Nesse cenário, a pipeline não está entregando uma aplicação.

    Está alterando infraestrutura.

    Essa integração conecta CI/CD ao conceito de Infrastructure as Code.

    No artigo Automação de infraestrutura: Terraform, Ansible e Infrastructure as Code, vimos como infraestrutura pode ser representada e versionada como código.

    Uma pipeline adiciona uma camada importante a esse modelo:

    processo controlado para modificar esse código e aplicá-lo ao ambiente.

    CI/CD também pode controlar mudanças de infraestrutura, aplicando validações, aprovações e automação antes do provisionamento e da configuração do ambiente.

    Aplicação e infraestrutura podem participar do mesmo fluxo

    Em determinadas arquiteturas, application delivery e infrastructure delivery aparecem separadas.

    Isso pode ser desejável.

    Em outras, existe integração entre as duas.

    Uma pipeline pode:

    1. validar o código;

    2. verificar a infraestrutura necessária;

    3. criar ou alterar recursos;

    4. configurar o ambiente;

    5. publicar a aplicação;

    6. executar testes pós-deployment.

    Terraform pode cuidar do provisionamento.

    Ansible pode configurar sistemas.

    A pipeline coordena a ordem.

    Essa distinção é importante.

    Pipeline não substitui Terraform.

    Pipeline não substitui Ansible.

    Pipeline orquestra o processo no qual essas ferramentas são utilizadas.

    Deploy não deveria ser a última etapa

    Quando o deployment termina, ainda existe uma pergunta:

    o sistema realmente está funcionando?

    O processo pode executar verificações pós-deploy.

    Por exemplo:

    • endpoint HTTP responde?

    • aplicação iniciou corretamente?

    • banco está acessível?

    • serviço foi registrado?

    • métricas estão chegando?

    • erros aumentaram?

    Um deploy tecnicamente concluído pode introduzir degradação.

    Por isso, health checks e validações fazem parte de pipelines mais maduras.

    Esse conceito também se conecta ao artigo Monitoramento de infraestrutura de TI: arquitetura, métricas, protocolos e boas práticas.

    Rollback precisa estar previsto antes da falha

    Toda mudança pode apresentar problemas.

    Por isso, rollback não deveria ser uma improvisação.

    Dependendo da arquitetura, reverter pode significar:

    • restaurar artifact anterior;

    • trocar tag de imagem;

    • retornar deployment anterior;

    • reverter configuração;

    • redirecionar tráfego;

    • restaurar versão conhecida.

    Uma pipeline madura guarda informações suficientes para saber qual versão estava anteriormente em produção.

    Isso torna possível retornar a um estado conhecido.

    Nem todo rollback pode ser totalmente automático.

    Mudanças de banco de dados, por exemplo, podem exigir estratégias específicas.

    Mas o princípio permanece:

    a estratégia de recuperação deve ser definida antes do incidente.

    Uma pipeline madura precisa proteger credenciais, validar a implantação em produção e possuir um caminho conhecido de rollback quando a mudança não se comporta como esperado.

    Observabilidade também se aplica à própria pipeline

    Normalmente pensamos em observabilidade depois que a aplicação entra em produção.

    Mas a pipeline também gera informações.

    Quanto tempo o build demora?

    Quais testes falham com maior frequência?

    Quanto tempo uma alteração permanece aguardando aprovação?

    Quantos deploys falham?

    Quanto tempo leva para uma mudança sair do commit e chegar à produção?

    Esses dados mostram gargalos no processo de entrega.

    Uma pipeline que demora uma hora para retornar um erro simples prejudica o feedback ao desenvolvimento.

    Uma pipeline que falha frequentemente por problemas de infraestrutura deixa de ser confiável.

    Uma etapa manual que permanece dias aguardando aprovação pode representar outro gargalo.

    CI/CD também precisa ser tratado como sistema operacional.

    Paralelismo reduz tempo, mas exige dependências claras

    Nem todos os jobs precisam executar em sequência.

    Se lint, testes unitários e determinadas análises de segurança não dependem uns dos outros, podem executar paralelamente.

    Isso reduz o tempo total da pipeline.

    Mas paralelismo precisa respeitar dependências.

    Um job que precisa de um artifact de build não pode executar antes desse artifact existir.

    Por isso, plataformas modernas permitem definir grafos de dependência.

    Uma pipeline eficiente procura executar em paralelo aquilo que é independente e manter sequência apenas onde existe dependência real.

    Cache e artifact não são a mesma coisa

    Os dois conceitos podem parecer semelhantes porque ambos armazenam arquivos.

    Mas possuem finalidades diferentes.

    Artifact é resultado do processo.

    Cache existe principalmente para acelerar execuções futuras.

    Dependências baixadas por um gerenciador de pacotes podem ser armazenadas em cache.

    O pacote final produzido pelo build é um artifact.

    Confundir os dois pode causar problemas de consistência.

    Caches normalmente podem ser descartados e recriados.

    Artifacts importantes precisam possuir identificação, retenção e rastreabilidade compatíveis com sua função.

    Pipeline como código melhora rastreabilidade

    Quando a definição da pipeline também fica versionada, mudanças no processo de entrega passam a possuir histórico.

    Uma alteração de deploy pode ser revisada em Pull Request.

    Uma nova etapa de segurança pode ser adicionada através de commit.

    Uma mudança de variável pode ser rastreada.

    Isso aproxima operação das práticas de engenharia de software.

    Arquivos como:

    .github/workflows/deploy.yml

    .gitlab-ci.yml

    Jenkinsfile

    azure-pipelines.yml

    buildspec.yml

    representam partes do processo operacional em código.

    O benefício não está apenas na automação.

    Está na capacidade de revisar, versionar e reproduzir o processo.

    Nem toda pipeline precisa ser complexa

    Existe uma tendência de associar maturidade a quantidade de stages.

    Isso pode criar pipelines difíceis de manter.

    Uma aplicação pequena pode precisar apenas de:

    build → test → deploy

    Um sistema crítico pode exigir:

    lint → unit test → integration test → SAST → build → scan → artifact → staging → functional test → approval → production → smoke test

    As duas podem estar corretas.

    A pipeline deve refletir o risco e a necessidade do sistema.

    Adicionar ferramentas apenas para parecer mais moderno aumenta complexidade sem necessariamente aumentar confiabilidade.

    Uma pipeline madura reduz improvisação

    O principal ganho de CI/CD não está em fazer deploy mais rápido.

    Está em transformar mudança em um processo conhecido.

    Uma alteração entra pelo Git.

    Validações são executadas.

    Um artifact é produzido.

    Controles decidem se ele pode avançar.

    Ambientes recebem exatamente aquilo que foi aprovado.

    Credenciais são tratadas de forma segura.

    A implantação é verificada.

    E existe um caminho conhecido caso algo dê errado.

    Esse fluxo cria rastreabilidade do início ao fim.

    CI/CD deixa então de ser apenas uma ferramenta de desenvolvimento.

    Passa a ser uma camada de integração entre código, infraestrutura, segurança e operação.

    No artigo DevOps na prática: CI/CD, automação, infraestrutura e observabilidade, mostramos como CI/CD se conecta ao ciclo mais amplo de DevOps.

    Aqui, o objetivo foi olhar por dentro da pipeline e entender como cada etapa participa desse processo.

    VAMOS CONVERSAR

    Conte o que sua empresa precisa.

    Conte o que sua empresa precisa. Pode ser um novo projeto, uma melhoria ou um problema de TI que precisa de atenção.

    Preencha nome e mensagem para continuar. Os dados serão incluídos na conversa do WhatsApp, onde você poderá revisar e confirmar o envio.

    Rua Pereira de Almeida, 38, Casa 01 - Rio de Janeiro

    WhatsApp: (21) 98348-4145