Introdução ao AWS CodePipeline
O AWS CodePipeline é um serviço de integração contínua e entrega contínua (CI/CD) totalmente gerenciado que automatiza o processo de release de aplicações. Em vez de fazer deploy manualmente, você define etapas — build, teste e deploy — que executam automaticamente quando código é alterado. Isso reduz erros humanos, acelera entregas e mantém a qualidade do software em níveis altos. Neste artigo, você aprenderá desde conceitos fundamentais até padrões avançados de automação.
Arquitetura e Componentes Principais
Fluxo Básico do Pipeline
Um pipeline típico segue esta sequência: Source → Build → Test → Deploy. A etapa Source monitora seu repositório (CodeCommit, GitHub, GitLab) e dispara o pipeline automaticamente quando detecta alterações. A etapa Build compila o código usando CodeBuild. A etapa Test executa testes automatizados, e a etapa Deploy envia a aplicação para ambientes (desenvolvimento, staging, produção) usando CodeDeploy, CloudFormation ou ECS.
Componentes Essenciais
Artifacts são arquivos gerados entre etapas (binários compilados, pacotes). Actions são unidades de trabalho dentro de uma etapa (executar teste, fazer deploy). Stages agrupam actions relacionadas. Transitions controlam o fluxo entre stages — você pode exigir aprovação manual antes de prosseguir para produção.
Implementação Prática: Pipeline Completo
Configuração do Pipeline via CloudFormation
AWSTemplateFormatVersion: '2010-09-09'
Description: 'CodePipeline com Build e Deploy'
Resources:
ArtifactBucket:
Type: AWS::S3::Bucket
Properties:
BucketName: !Sub 'pipeline-artifacts-${AWS::AccountId}'
VersioningConfiguration:
Status: Enabled
CodePipelineRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service: codepipeline.amazonaws.com
Action: 'sts:AssumeRole'
ManagedPolicyArns:
- 'arn:aws:iam::aws:policy/AWSCodePipelineFullAccess'
Policies:
- PolicyName: S3Artifacts
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- 's3:GetObject'
- 's3:PutObject'
Resource: !Sub '${ArtifactBucket.Arn}/*'
MyPipeline:
Type: AWS::CodePipeline::Pipeline
Properties:
Name: MyApplicationPipeline
RoleArn: !GetAtt CodePipelineRole.Arn
ArtifactStore:
Type: S3
Location: !Ref ArtifactBucket
Stages:
- Name: Source
Actions:
- Name: SourceAction
ActionTypeId:
Category: Source
Owner: AWS
Provider: CodeCommit
Version: '1'
Configuration:
RepositoryName: my-repo
BranchName: main
OutputArtifacts:
- Name: SourceOutput
- Name: Build
Actions:
- Name: BuildAction
ActionTypeId:
Category: Build
Owner: AWS
Provider: CodeBuild
Version: '1'
Configuration:
ProjectName: !Ref BuildProject
InputArtifacts:
- Name: SourceOutput
OutputArtifacts:
- Name: BuildOutput
- Name: Deploy
Actions:
- Name: DeployToStaging
ActionTypeId:
Category: Deploy
Owner: AWS
Provider: CloudFormation
Version: '1'
Configuration:
ActionMode: CHANGE_SET_REPLACE
StackName: my-app-staging
ChangeSetName: my-app-staging-changeset
TemplatePath: BuildOutput::packaged.yaml
Capabilities: CAPABILITY_IAM
InputArtifacts:
- Name: BuildOutput
BuildProject:
Type: AWS::CodeBuild::Project
Properties:
Name: MyBuildProject
ServiceRole: !GetAtt CodeBuildRole.Arn
Artifacts:
Type: CODEPIPELINE
Environment:
ComputeType: BUILD_GENERAL1_SMALL
Image: aws/codebuild/standard:5.0
Type: LINUX_CONTAINER
Source:
Type: CODEPIPELINE
BuildSpec: |
version: 0.2
phases:
build:
commands:
- echo "Building application..."
- npm install
- npm run build
artifacts:
files:
- '**/*'
CodeBuildRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service: codebuild.amazonaws.com
Action: 'sts:AssumeRole'
ManagedPolicyArns:
- 'arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryPowerUser'
Policies:
- PolicyName: S3Access
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- 's3:GetObject'
- 's3:PutObject'
Resource: !Sub '${ArtifactBucket.Arn}/*'
Arquivo buildspec.yml Avançado
version: 0.2
env:
variables:
AWS_DEFAULT_REGION: us-east-1
parameter-store:
DOCKER_REGISTRY: /docker/registry-url
phases:
pre_build:
commands:
- echo Logging in to Amazon ECR...
- aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin $DOCKER_REGISTRY
- COMMIT_HASH=$(echo $CODEBUILD_RESOLVED_SOURCE_VERSION | cut -c 1-7)
- IMAGE_TAG=${COMMIT_HASH:=latest}
build:
commands:
- echo Build started on `date`
- echo Building the Docker image...
- docker build -t $DOCKER_REGISTRY/my-app:$IMAGE_TAG .
- docker tag $DOCKER_REGISTRY/my-app:$IMAGE_TAG $DOCKER_REGISTRY/my-app:latest
post_build:
commands:
- echo Build completed on `date`
- echo Pushing the Docker images...
- docker push $DOCKER_REGISTRY/my-app:$IMAGE_TAG
- docker push $DOCKER_REGISTRY/my-app:latest
- echo Writing image definitions file...
- printf '[{"name":"my-app","imageUri":"%s"}]' $DOCKER_REGISTRY/my-app:$IMAGE_TAG > imagedefinitions.json
artifacts:
files: imagedefinitions.json
Padrões Avançados
Aprovação Manual e Multi-Ambiente
Para pipelines em produção, implemente etapas de aprovação manual antes de alterações críticas. Use Manual como tipo de action para pausar o pipeline e exigir confirmação de um usuário autorizado. Combine isso com múltiplos stages (Dev → Staging → Prod) onde cada ambiente possui diferentes aprovadores e políticas de deployment.
Integração com Lambda e Validação Personalizada
import json
import boto3
codepipeline = boto3.client('codepipeline')
def lambda_handler(event, context):
job_id = event['CodePipeline.job']['id']
try:
# Validação customizada
test_result = run_health_check()
if test_result['status'] == 'healthy':
codepipeline.put_job_success_result(jobId=job_id)
else:
codepipeline.put_job_failure_result(
jobId=job_id,
failureDetails={'message': 'Health check failed'}
)
except Exception as e:
codepipeline.put_job_failure_result(
jobId=job_id,
failureDetails={'message': str(e)}
)
def run_health_check():
return {'status': 'healthy'}
Coloque uma Lambda como action no pipeline para executar validações customizadas, testes de fumaça, ou verificações de segurança. A função recebe metadados do job e retorna sucesso ou falha, controlando o fluxo do pipeline.
Conclusão
Dominar CodePipeline exige compreender seus componentes fundamentais (stages, actions, artifacts) e saber construir fluxos de automação. Comece simples com source → build → deploy e evolua para padrões avançados como aprovações manuais, múltiplos ambientes e validações customizadas com Lambda. A chave é iterar rapidamente: crie um pipeline básico, teste, refine políticas de segurança e escalabilidade conforme sua aplicação cresce.