DEV Community

Francisco Escobar
Francisco Escobar

Posted on

Pipeline Seguro de DevOps en AWS: Guía Completa para Principiantes

🎯 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
Enter fullscreen mode Exit fullscreen mode

¿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
Enter fullscreen mode Exit fullscreen mode

🔐 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"
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

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"}'
Enter fullscreen mode Exit fullscreen mode

¿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"
Enter fullscreen mode Exit fullscreen mode

🔧 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:
    - '**/*'
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

🚀 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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

📊 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
            }
        ]
    )
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

🔄 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"
              }
            ]
          }
        ]
      }
    ]
  }
}
Enter fullscreen mode Exit fullscreen mode

🛡️ 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/*"
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

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"
                }
            }
        ]
    }'
Enter fullscreen mode Exit fullscreen mode

📈 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
Enter fullscreen mode Exit fullscreen mode

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)
)
Enter fullscreen mode Exit fullscreen mode

✅ 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()
Enter fullscreen mode Exit fullscreen mode

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/
Enter fullscreen mode Exit fullscreen mode

🎯 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>
Enter fullscreen mode Exit fullscreen mode

Error: "Deployment failed"

# Verificar instancias EC2
aws deploy get-deployment --deployment-id <deployment-id>

# Revisar CodeDeploy agent
sudo service codedeploy-agent status
Enter fullscreen mode Exit fullscreen mode

📚 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)