🎯 Objetivo del Proyecto
Crear un pipeline de CI/CD completamente funcional y seguro en AWS que automatice el proceso de desarrollo, pruebas y despliegue de aplicaciones, implementando las mejores prácticas de seguridad y monitoreo.
📋 Arquitectura del Proyecto
Servicios principales:
- CI/CD: CodeCommit + CodeBuild + CodeDeploy
- Seguridad: Secrets Manager, Parameter Store, IAM roles
- Monitoreo: CloudWatch, CloudTrail, Config
🚀 Fase 1: Preparación del Entorno
Paso 1.1: Configurar CodeCommit (Repositorio)
# 1. Crear repositorio en CodeCommit
aws codecommit create-repository --repository-name mi-app-segura
# 2. Configurar credenciales Git
aws configure set credential.helper '!aws codecommit credential-helper $@'
aws configure set credential.UseHttpPath true
# 3. Clonar el repositorio
git clone https://git-codecommit.us-east-1.amazonaws.com/v1/repos/mi-app-segura
¿Qué es CodeCommit?
Es el servicio de control de versiones de AWS, similar a GitHub pero completamente integrado con otros servicios AWS.
Paso 1.2: Estructura del Proyecto
mi-app-segura/
├── src/
│ ├── app.py
│ └── requirements.txt
├── tests/
│ └── test_app.py
├── buildspec.yml
├── appspec.yml
└── deploy/
└── install_dependencies.sh
🔐 Fase 2: Configuración de Seguridad
Paso 2.1: Crear Roles IAM
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "codebuild.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
Roles necesarios:
-
CodeBuildServiceRole
: Para que CodeBuild pueda ejecutar builds -
CodeDeployServiceRole
: Para que CodeDeploy pueda desplegar aplicaciones -
EC2InstanceRole
: Para que las instancias EC2 puedan interactuar con CodeDeploy
Paso 2.2: Configurar Secrets Manager
# Crear un secreto para la base de datos
aws secretsmanager create-secret \
--name "prod/myapp/database" \
--description "Database credentials for production" \
--secret-string '{"username":"admin","password":"SuperSecurePassword123"}'
¿Por qué usar Secrets Manager?
- Rotación automática de credenciales
- Cifrado en reposo y en tránsito
- Auditoría completa de accesos
Paso 2.3: Configurar Parameter Store
# Parámetros de configuración
aws ssm put-parameter \
--name "/myapp/database/host" \
--value "prod-db.cluster-xyz.us-east-1.rds.amazonaws.com" \
--type "String"
aws ssm put-parameter \
--name "/myapp/api/key" \
--value "api-key-12345" \
--type "SecureString"
🔧 Fase 3: Configuración del Pipeline de Build
Paso 3.1: Crear buildspec.yml
version: 0.2
phases:
install:
runtime-versions:
python: 3.9
commands:
- echo "Installing dependencies..."
- pip install -r requirements.txt
pre_build:
commands:
- echo "Running pre-build tasks..."
- python -m pytest tests/ -v
build:
commands:
- echo "Building the application..."
- echo "Build completed on `date`"
post_build:
commands:
- echo "Running post-build tasks..."
- echo "Creating deployment package..."
artifacts:
files:
- '**/*'
Paso 3.2: Configurar CodeBuild
# Crear proyecto de build
aws codebuild create-project \
--name "mi-app-build" \
--source type=CODECOMMIT,location=https://git-codecommit.us-east-1.amazonaws.com/v1/repos/mi-app-segura \
--artifacts type=S3,location=mi-bucket-artifacts \
--environment type=LINUX_CONTAINER,image=aws/codebuild/amazonlinux2-x86_64-standard:3.0 \
--service-role arn:aws:iam::123456789012:role/CodeBuildServiceRole
🚀 Fase 4: Configuración del Despliegue
Paso 4.1: Crear appspec.yml
version: 0.0
os: linux
files:
- source: /
destination: /var/www/html/myapp
hooks:
BeforeInstall:
- location: deploy/install_dependencies.sh
timeout: 300
ApplicationStart:
- location: deploy/start_server.sh
timeout: 300
ValidateService:
- location: deploy/validate_service.sh
timeout: 300
Paso 4.2: Configurar CodeDeploy
# Crear aplicación
aws deploy create-application \
--application-name "mi-app-deploy" \
--compute-platform "Server"
# Crear grupo de despliegue
aws deploy create-deployment-group \
--application-name "mi-app-deploy" \
--deployment-group-name "production" \
--service-role-arn "arn:aws:iam::123456789012:role/CodeDeployServiceRole" \
--ec2-tag-filters Key=Environment,Value=Production,Type=KEY_AND_VALUE
📊 Fase 5: Monitoreo y Observabilidad
Paso 5.1: Configurar CloudWatch
# Ejemplo de métricas personalizadas en la aplicación
import boto3
cloudwatch = boto3.client('cloudwatch')
def put_custom_metric(metric_name, value, unit='Count'):
cloudwatch.put_metric_data(
Namespace='MyApp/Performance',
MetricData=[
{
'MetricName': metric_name,
'Value': value,
'Unit': unit
}
]
)
Paso 5.2: Configurar CloudTrail
# Crear trail para auditoría
aws cloudtrail create-trail \
--name "mi-app-audit-trail" \
--s3-bucket-name "mi-bucket-cloudtrail" \
--include-global-service-events \
--is-multi-region-trail
Paso 5.3: Configurar Config
# Habilitar Config para compliance
aws configservice put-configuration-recorder \
--configuration-recorder name=default,roleARN=arn:aws:iam::123456789012:role/ConfigRole \
--recording-group allSupported=true,includeGlobalResourceTypes=true
🔄 Fase 6: Automatización del Pipeline
Paso 6.1: Crear CodePipeline
{
"pipeline": {
"name": "mi-app-pipeline",
"roleArn": "arn:aws:iam::123456789012:role/CodePipelineRole",
"artifactStore": {
"type": "S3",
"location": "mi-bucket-artifacts"
},
"stages": [
{
"name": "Source",
"actions": [
{
"name": "Source",
"actionTypeId": {
"category": "Source",
"owner": "AWS",
"provider": "CodeCommit",
"version": "1"
},
"configuration": {
"RepositoryName": "mi-app-segura",
"BranchName": "main"
},
"outputArtifacts": [
{
"name": "SourceOutput"
}
]
}
]
},
{
"name": "Build",
"actions": [
{
"name": "Build",
"actionTypeId": {
"category": "Build",
"owner": "AWS",
"provider": "CodeBuild",
"version": "1"
},
"configuration": {
"ProjectName": "mi-app-build"
},
"inputArtifacts": [
{
"name": "SourceOutput"
}
],
"outputArtifacts": [
{
"name": "BuildOutput"
}
]
}
]
},
{
"name": "Deploy",
"actions": [
{
"name": "Deploy",
"actionTypeId": {
"category": "Deploy",
"owner": "AWS",
"provider": "CodeDeploy",
"version": "1"
},
"configuration": {
"ApplicationName": "mi-app-deploy",
"DeploymentGroupName": "production"
},
"inputArtifacts": [
{
"name": "BuildOutput"
}
]
}
]
}
]
}
}
🛡️ Fase 7: Hardening de Seguridad
Paso 7.1: Principio de Menor Privilegio
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"secretsmanager:GetSecretValue"
],
"Resource": "arn:aws:secretsmanager:us-east-1:123456789012:secret:prod/myapp/*"
},
{
"Effect": "Allow",
"Action": [
"ssm:GetParameter",
"ssm:GetParameters"
],
"Resource": "arn:aws:ssm:us-east-1:123456789012:parameter/myapp/*"
}
]
}
Paso 7.2: Cifrado en Tránsito y Reposo
# Habilitar cifrado en S3
aws s3api put-bucket-encryption \
--bucket mi-bucket-artifacts \
--server-side-encryption-configuration '{
"Rules": [
{
"ApplyServerSideEncryptionByDefault": {
"SSEAlgorithm": "AES256"
}
}
]
}'
📈 Fase 8: Monitoreo y Alertas
Paso 8.1: Crear Alarmas CloudWatch
# Alarma para fallos de despliegue
aws cloudwatch put-metric-alarm \
--alarm-name "DeploymentFailures" \
--alarm-description "Alert when deployment fails" \
--metric-name "DeploymentFailures" \
--namespace "AWS/CodeDeploy" \
--statistic "Sum" \
--period 300 \
--threshold 1 \
--comparison-operator "GreaterThanOrEqualToThreshold" \
--evaluation-periods 1
Paso 8.2: Dashboard de Monitoreo
# Crear dashboard personalizado
import boto3
cloudwatch = boto3.client('cloudwatch')
dashboard_body = {
"widgets": [
{
"type": "metric",
"properties": {
"metrics": [
["AWS/CodePipeline", "PipelineExecutionSuccess", "PipelineName", "mi-app-pipeline"],
["AWS/CodeBuild", "Builds", "ProjectName", "mi-app-build"],
["AWS/CodeDeploy", "Deployments", "ApplicationName", "mi-app-deploy"]
],
"period": 300,
"stat": "Sum",
"region": "us-east-1",
"title": "Pipeline Health"
}
}
]
}
cloudwatch.put_dashboard(
DashboardName='MyAppPipeline',
DashboardBody=json.dumps(dashboard_body)
)
✅ Fase 9: Testing y Validación
Paso 9.1: Pruebas Automatizadas
# test_app.py
import unittest
from src.app import app
class TestApp(unittest.TestCase):
def setUp(self):
self.app = app.test_client()
def test_health_check(self):
response = self.app.get('/health')
self.assertEqual(response.status_code, 200)
def test_security_headers(self):
response = self.app.get('/')
self.assertIn('X-Frame-Options', response.headers)
self.assertIn('X-Content-Type-Options', response.headers)
if __name__ == '__main__':
unittest.main()
Paso 9.2: Validación de Seguridad
# Escaneo de vulnerabilidades
pip install safety bandit
# Verificar dependencias
safety check
# Análisis de código estático
bandit -r src/
🎯 Mejores Prácticas Implementadas
Seguridad
- ✅ Separación de secretos y configuración
- ✅ Roles IAM con permisos mínimos
- ✅ Cifrado en reposo y tránsito
- ✅ Auditoría completa con CloudTrail
- ✅ Escaneo de vulnerabilidades automatizado
DevOps
- ✅ Pipeline completamente automatizado
- ✅ Pruebas automatizadas en cada commit
- ✅ Despliegues blue/green
- ✅ Rollback automático en caso de fallas
- ✅ Integración continua y entrega continua
Monitoreo
- ✅ Métricas en tiempo real
- ✅ Alertas proactivas
- ✅ Dashboard centralizado
- ✅ Logs estructurados
- ✅ Trazabilidad completa
💡 Troubleshooting Común
Error: "Build failed"
# Verificar logs de CodeBuild
aws codebuild batch-get-builds --ids <build-id>
# Revisar permisos del rol
aws iam get-role-policy --role-name CodeBuildServiceRole --policy-name <policy-name>
Error: "Deployment failed"
# Verificar instancias EC2
aws deploy get-deployment --deployment-id <deployment-id>
# Revisar CodeDeploy agent
sudo service codedeploy-agent status
📚 Recursos Adicionales
🎉 Conclusión
Este proyecto demuestra cómo implementar un pipeline de CI/CD completamente seguro y monitoreado en AWS. Los principales beneficios incluyen:
- Automatización completa del proceso de desarrollo a producción
- Seguridad integrada en cada etapa del pipeline
- Monitoreo proactivo para detectar y resolver problemas rápidamente
- Escalabilidad para manejar aplicaciones de cualquier tamaño
- Cumplimiento con estándares de seguridad empresariales
Este pipeline puede servir como base para cualquier proyecto de desarrollo moderno, proporcionando una foundation sólida para el crecimiento y la evolución de tus aplicaciones.
¿Tienes preguntas sobre algún paso específico? ¡Déjame saber en los comentarios!
Top comments (0)