🔄 CI/CD — Pipelines

Integração e entrega contínua — automatize do commit ao deploy em produção

🔄 O que é CI/CD?

CI (Continuous Integration) é a prática de integrar código frequentemente ao repositório principal, com build e testes automáticos a cada commit. O objetivo é detectar problemas cedo.

CD (Continuous Delivery/Deployment) estende o CI automatizando a entrega do software até produção:

  • Continuous Delivery — o artefato está sempre pronto para deploy, mas o acionamento é manual
  • Continuous Deployment — cada commit aprovado vai automaticamente para produção
💡 Regra de ouro do CI: Se o build quebrou, corrigir é a prioridade número 1 do time — ninguém faz merge enquanto o pipeline estiver vermelho.

🗺️ Fluxo do Pipeline

Um pipeline CI/CD típico passa pelas seguintes etapas:

PIPELINE CI/CD — FLUXO COMPLETO Developer │ │ git push / pull request ▼ [ SOURCE ] ──── GitHub / CodeCommit / Bitbucket │ │ trigger automático ▼ [ BUILD ] ├── Instalar dependências ├── Compilar código ├── Build da imagem Docker └── Push para registry (ECR / Docker Hub) │ ▼ [ TEST ] ├── Testes unitários ├── Testes de integração ├── Análise de código (SonarQube, ESLint) └── Scan de segurança (Trivy, Snyk) │ │ aprovação automática (ou manual para prod) ▼ [ DEPLOY — STAGING ] ├── Deploy no ambiente de homologação └── Testes de smoke / E2E │ │ aprovação manual (gate de produção) ▼ [ DEPLOY — PRODUCTION ] ├── Rolling update / Blue-Green / Canary └── Notificação (Slack, email, PagerDuty)

⚙️ GitHub Actions

O GitHub Actions é a ferramenta de CI/CD nativa do GitHub. Pipelines são definidos em arquivos YAML dentro de .github/workflows/.

Pipeline completo: build, test e push para ECR

# .github/workflows/ci.yml
name: CI — Build e Push ECR

on:
  push:
    branches: [main, develop]
  pull_request:
    branches: [main]

env:
  AWS_REGION: us-east-1
  ECR_REPOSITORY: minha-app

jobs:
  build-and-push:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout código
        uses: actions/checkout@v4

      - name: Configurar credenciais AWS
        uses: aws-actions/configure-aws-credentials@v4
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          aws-region: ${{ env.AWS_REGION }}

      - name: Login no Amazon ECR
        id: login-ecr
        uses: aws-actions/amazon-ecr-login@v2

      - name: Rodar testes
        run: |
          npm ci
          npm test

      - name: Build e push da imagem
        env:
          REGISTRY: ${{ steps.login-ecr.outputs.registry }}
          IMAGE_TAG: ${{ github.sha }}
        run: |
          docker build -t $REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG .
          docker push $REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
          # Tag latest também
          docker tag $REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG \
            $REGISTRY/$ECR_REPOSITORY:latest
          docker push $REGISTRY/$ECR_REPOSITORY:latest

Pipeline de deploy após o build:

# .github/workflows/deploy.yml
name: CD — Deploy ECS

on:
  workflow_run:
    workflows: [CI — Build e Push ECR]
    branches: [main]
    types: [completed]

jobs:
  deploy:
    if: ${{ github.event.workflow_run.conclusion == 'success' }}
    runs-on: ubuntu-latest
    steps:
      - name: Configurar AWS
        uses: aws-actions/configure-aws-credentials@v4
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          aws-region: us-east-1

      - name: Deploy no ECS
        run: |
          aws ecs update-service \
            --cluster producao \
            --service minha-app \
            --force-new-deployment
⚠️ Nunca coloque credenciais AWS diretamente no YAML. Use sempre GitHub Secrets (Settings → Secrets and variables → Actions).

🚀 AWS CodePipeline

O CodePipeline é o serviço de CI/CD gerenciado da AWS. Integra nativamente com CodeCommit, CodeBuild, CodeDeploy, S3, ECR e ECS.

EstágioServiço AWSFunção
SourceCodeCommit / GitHub / S3Detecta mudanças no repositório
BuildCodeBuildCompila, testa e gera artefatos
TestCodeBuildTestes automatizados
DeployCodeDeploy / ECS / CloudFormationPublica em staging/produção
ApprovalSNS + ManualGate de aprovação humana
# Criar pipeline via AWS CLI
aws codepipeline create-pipeline \
  --pipeline file://pipeline.json \
  --region us-east-1

# Ver status do pipeline
aws codepipeline get-pipeline-state \
  --name meu-pipeline \
  --region us-east-1

# Acionar manualmente
aws codepipeline start-pipeline-execution \
  --name meu-pipeline \
  --region us-east-1

🔨 AWS CodeBuild — buildspec.yml

O CodeBuild executa builds em containers gerenciados. O arquivo buildspec.yml define os comandos de cada fase:

# buildspec.yml — build de imagem Docker e push para ECR
version: 0.2

env:
  variables:
    AWS_DEFAULT_REGION: us-east-1
    IMAGE_REPO_NAME: minha-app
  parameter-store:
    IMAGE_TAG: /codebuild/image-tag

phases:
  pre_build:
    commands:
      - echo Fazendo login no ECR...
      - aws ecr get-login-password | docker login --username AWS --password-stdin $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com
      - COMMIT_HASH=$(echo $CODEBUILD_RESOLVED_SOURCE_VERSION | cut -c 1-7)
      - IMAGE_TAG=${COMMIT_HASH:=latest}

  build:
    commands:
      - echo Rodando testes...
      - npm ci && npm test
      - echo Buildando imagem Docker...
      - docker build -t $IMAGE_REPO_NAME:$IMAGE_TAG .
      - docker tag $IMAGE_REPO_NAME:$IMAGE_TAG $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME:$IMAGE_TAG

  post_build:
    commands:
      - echo Fazendo push da imagem...
      - docker push $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME:$IMAGE_TAG
      - printf '[{"name":"minha-app","imageUri":"%s"}]' $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME:$IMAGE_TAG > imagedefinitions.json

artifacts:
  files:
    - imagedefinitions.json   # usado pelo CodeDeploy para atualizar o ECS

🐳 Deploy Automatizado no ECS

Com a imagem no ECR, o deploy no ECS pode ser feito de forma totalmente automatizada:

# Atualizar serviço ECS com nova imagem (rolling update)
aws ecs update-service \
  --cluster meu-cluster \
  --service minha-app \
  --force-new-deployment \
  --region us-east-1

# Aguardar estabilização
aws ecs wait services-stable \
  --cluster meu-cluster \
  --services minha-app \
  --region us-east-1

# Verificar tasks em execução
aws ecs list-tasks \
  --cluster meu-cluster \
  --service-name minha-app \
  --region us-east-1
💡 O arquivo imagedefinitions.json gerado pelo CodeBuild informa ao CodePipeline qual imagem usar no deploy do ECS — é a "cola" entre os estágios de build e deploy.

🎯 Estratégias de Deploy

Escolha a estratégia certa para minimizar risco e downtime:

🔄 Rolling Update

Substitui instâncias antigas gradualmente. Simples, sem custo extra. Risco: versões mistas por alguns minutos.

🔵🟢 Blue/Green

Dois ambientes idênticos. O tráfego é chaveado de uma vez. Rollback instantâneo. Custo: dobra a infra temporariamente.

🐦 Canary

Envia % pequeno do tráfego para a nova versão (ex: 5%). Aumenta gradualmente se estável. Ideal para validar em produção.

🔒 Feature Flags

Deploy do código desativado. Ativa por usuário/grupo sem novo deploy. Máximo controle, requer implementação no código.

EstratégiaDowntimeRollbackCustoComplexidade
RollingZeroLentoBaixoBaixa
Blue/GreenZeroInstantâneoAltoMédia
CanaryZeroRápidoMédioAlta
Feature FlagsZeroInstantâneoBaixoAlta

✅ Boas Práticas de CI/CD

  • Pipeline rápido: mantenha o CI abaixo de 10 minutos — pipelines lentos são ignorados
  • Fail fast: coloque os testes mais rápidos primeiro (unitários antes de integração)
  • Imutabilidade: nunca altere uma imagem já publicada — sempre gere uma nova com nova tag
  • Secrets seguros: use GitHub Secrets, AWS SSM Parameter Store ou Secrets Manager — nunca variáveis hardcoded
  • Ambientes separados: dev → staging → produção, com aprovação manual antes de produção
  • Notificações: configure alertas no Slack/Teams para falhas no pipeline
  • Rollback automatizado: monitore métricas pós-deploy e reverta automaticamente se houver degradação
  • Versionamento de artefatos: use o hash do commit como tag da imagem Docker — rastreabilidade total
💡 Dica: Comece com GitHub Actions para projetos novos — é gratuito para repositórios públicos e tem integração nativa com AWS via actions oficiais. Para projetos já na AWS, o CodePipeline é a escolha natural.