Deploys manuais não escalam. Cada etapa manual é uma fonte potencial de erros e, quanto mais rápido o seu time entrega, mais esses erros se acumulam. Um pipeline de CI/CD construído sobre Docker e AWS remove o trabalho manual do caminho crítico: o código é compilado, testado, empacotado como container e implantado em produção sem intervenção humana em cada etapa.
Este post percorre um pipeline completo usando AWS CodePipeline, AWS CodeBuild, Amazon ECR e Amazon ECS.
Por que Docker e AWS para CI/CD?
Containers Docker oferecem comportamento consistente entre ambientes. O que roda localmente roda da mesma forma no CI e em produção. Os serviços AWS cuidam de escalonamento e segurança no nível de infraestrutura, e o CodePipeline une os estágios em um único fluxo de trabalho automatizado.
Pré-requisitos
- Uma conta AWS com privilégios administrativos.
- Conhecimento básico de Docker e conceitos de conteinerização.
- Familiaridade com ECS e ECR.
- Uma aplicação de exemplo (este guia usa Node.js).
Arquitetura do Pipeline
O pipeline possui três estágios:
- Source: O código é enviado para um sistema de controle de versão (AWS CodeCommit ou GitHub).
- Build: O CodeBuild constrói a imagem Docker e executa os testes.
- Deploy: A imagem é enviada para o ECR e o ECS a implanta em um cluster.
Etapa 1: Configurando o Repositório de Origem
Para uma integração perfeita com a AWS, o AWS CodeCommit é a escolha mais direta.
-
Acesse o console do AWS CodeCommit.
-
Crie um novo repositório chamado
my-app-repo. -
Clone o repositório para sua máquina local:
git clone https://git-codecommit.us-east-1.amazonaws.com/v1/repos/my-app-repo -
Adicione o código da sua aplicação e faça o push:
git add . git commit -m "Initial commit" git push origin master
Etapa 2: Conteinerizando a Aplicação
Crie um Dockerfile para definir como sua aplicação é empacotada.
Dockerfile de exemplo para Node.js
# Use Node.js LTS version as the base image
FROM node:18-alpine
# Set the working directory in the container
WORKDIR /usr/src/app
# Copy package.json and package-lock.json
COPY package*.json ./
# Install dependencies
RUN npm install --production
# Copy the rest of the application code
COPY . .
# Expose the application port
EXPOSE 3000
# Start the application
CMD ["node", "app.js"]
Alguns pontos importantes: use uma imagem base mínima para manter a imagem pequena, copie apenas os arquivos necessários para otimizar o cache de build e execute containers como usuário não-root por segurança.
Etapa 3: Especificação de Build para o CodeBuild
O AWS CodeBuild precisa de um arquivo buildspec.yml na raiz do seu repositório.
buildspec.yml de exemplo
version: 0.2
phases:
pre_build:
commands:
- echo Logging into Amazon ECR...
- $(aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin <AWS_ACCOUNT_ID>.dkr.ecr.us-east-1.amazonaws.com)
- REPOSITORY_URI=<AWS_ACCOUNT_ID>.dkr.ecr.us-east-1.amazonaws.com/my-app-repo
build:
commands:
- echo Building the Docker image...
- docker build -t $REPOSITORY_URI:latest .
post_build:
commands:
- echo Pushing the Docker image...
- docker push $REPOSITORY_URI:latest
artifacts:
files:
- '**/*'
Substitua <AWS_ACCOUNT_ID> pelo seu ID real de conta AWS.
Etapa 4: Configurando o Amazon ECR
O Amazon ECR armazena suas imagens Docker.
- Acesse o console do Amazon ECR.
- Crie um novo repositório chamado
my-app-repo. - Anote o URI do repositório para uso no
buildspec.yml.
Etapa 5: Configurando o AWS CodeBuild
- Acesse o console do AWS CodeBuild.
- Crie um novo projeto de build chamado
my-app-build. - Configure:
- Source Provider: AWS CodeCommit.
- Repository:
my-app-repo. - Environment: runtime Ubuntu Standard, Docker habilitado, modo Privileged ativado (necessário para builds Docker).
- Buildspec: Use o buildspec.yml do código-fonte.
Etapa 6: Configurando o AWS CodePipeline
- Acesse o console do AWS CodePipeline.
- Crie um novo pipeline chamado
my-app-pipeline. - Estágio Source: AWS CodeCommit,
my-app-repo, branchmaster. - Estágio Build: AWS CodeBuild, projeto
my-app-build. - Estágio Deploy: AWS ECS,
my-ecs-cluster,my-app-service.
Etapa 7: Configurando o Amazon ECS
Criando um Cluster ECS
- Acesse o console do Amazon ECS.
- Crie um cluster chamado
my-ecs-cluster. Use Fargate se quiser evitar o gerenciamento de instâncias EC2.
Definindo uma Task Definition
- Acesse Task Definitions.
- Crie
my-app-taskcom:- Task Role: IAM role com as permissões necessárias.
- Network Mode:
awsvpcpara Fargate. - Container: nome
my-app-container, imagem do ECR, porta 3000 mapeada para o host 80.
Criando um Service
- Acesse Services e crie
my-app-service. - Launch type: Fargate. Task definition:
my-app-task. Habilite rolling updates.
Etapa 8: Testando o Pipeline
-
Faça uma alteração no código localmente.
-
Faça push para o master:
git add . git commit -m "Updated application" git push origin master -
Acompanhe o progresso do pipeline no console do CodePipeline.
-
Verifique o novo deploy no console do ECS.
Melhorando o Pipeline
Testes Automatizados
Adicione comandos de teste ao buildspec.yml antes da etapa de build Docker:
phases:
build:
commands:
- echo Running unit tests...
- npm test
- echo Building Docker image...
- docker build -t $REPOSITORY_URI:latest .
Infraestrutura como Código
Defina todos os recursos AWS em templates do CloudFormation ou Terraform. Manter o código de infraestrutura no controle de versão junto ao código da aplicação torna a configuração do ambiente reproduzível e as alterações auditáveis.
Gerenciamento de Dependências com CodeArtifact
O AWS CodeArtifact armazena e serve pacotes npm de forma privada. Isso é útil para compartilhar bibliotecas internas entre serviços sem publicá-las no registro público do npm.
Boas Práticas de Segurança
- Atribua IAM roles com privilégios mínimos a cada componente do CodeBuild e ECS.
- Armazene segredos no AWS Secrets Manager, não em variáveis de ambiente ou código-fonte.
- Configure VPCs, subnets e security groups para restringir o acesso à rede.
- Habilite CloudTrail e CloudWatch para logging de auditoria.
Monitoramento e Logging
- O CloudWatch Logs coleta a saída das tasks do ECS.
- O AWS X-Ray rastreia requisições pela aplicação implantada.
- Configure o Amazon SNS para enviar notificações quando os estágios do pipeline falharem.
Otimização de Custos
- Use capacidade Spot do ECS para workloads que tolerem interrupções.
- Dimensione corretamente a CPU e memória das tasks com base nas métricas reais do CloudWatch, em vez de estimativas.
- Revise e exclua regularmente imagens ECR não utilizadas e task definitions do ECS.
Conclusão
Uma vez que esse pipeline está no lugar, implantar uma alteração requer apenas um git push. O CodePipeline cuida do resto: constrói a imagem, executa os testes, faz o push para o ECR e implanta a nova versão no ECS. O custo de configuração é real, mas se paga rapidamente em tempo economizado e incidentes em produção evitados.