DEV Community

Alvaro Garcia
Alvaro Garcia

Posted on

Introducción a los Data Lakes Parte 3

Hola a todos! Llegamos al final de la serie. En la primera parte vimos qué es un Data Lake y por qué importa. En la segunda parte conocimos los 5 servicios que forman el núcleo: S3, Glue, Athena, Lake Formation y Lambda.

Hoy dejamos la teoría de lado. Vamos a construir el Data Lake completo, con todo el código disponible en un repo abierto para que lo despliegues en tu propia cuenta de AWS en minutos.

Acá estamos. Manos a la obra.


Qué vamos a construir

El escenario es simple y realista: una empresa con varias sucursales que suben sus ventas diarias como archivos CSV. Cada vez que llega un archivo nuevo, el pipeline se dispara solo y transforma esos datos crudos en datos consultables con SQL.

El flujo de punta a punta:

  1. Un CSV llega a la raw zone de S3
  2. El evento PutObject dispara una función Lambda
  3. Lambda lanza un Glue Job que transforma el CSV a Parquet y lo escribe en la processed zone
  4. Un Glue Crawler mantiene actualizado el Data Catalog
  5. Athena consulta los datos procesados con SQL estándar
  6. Lake Formation controla quién puede ver qué

La arquitectura completa: cada servicio hace una sola cosa, y se conectan a través de eventos.

Todo lo que vimos en los posts anteriores, funcionando junto. Y lo mejor: todo el código está en un repo público, definido como infraestructura con AWS CDK en Python.


El repo: infraestructura como código con CDK

En lugar de armar todo a mano desde la consola (clic acá, clic allá, y dentro de 6 meses nadie se acuerda de qué configuró), todo el Data Lake está definido como código con AWS CDK en Python.

📦 Repo: github.com/alvarongg/serverless-datalake-aws

¿Por qué CDK y no la consola? Tres razones:

  • Reproducible: lo despliegas en cualquier cuenta con un solo comando
  • Versionado: cada cambio en la infraestructura queda en el historial de Git
  • Documentación viva: el código es la arquitectura — no hay un diagrama desactualizado en un wiki

Si estás arrancando con Data Lakes, hacer todo por consola una vez es un buen ejercicio para entender las piezas. Pero para cualquier cosa que vaya a producción, infraestructura como código no es opcional.


Cómo está organizado el proyecto

La estructura del repo es deliberadamente simple — un solo stack de CDK que contiene todo el Data Lake:

serverless-datalake-aws/
├── app.py                      # Entry point de CDK
├── datalake/
│   └── datalake_stack.py       # El stack completo: S3, Lambda, Glue, Athena, Lake Formation
├── lambda_src/
│   └── trigger_pipeline.py     # La función que escucha eventos de S3
├── glue_src/
│   └── transform_job.py        # El script del Glue Job (CSV → Parquet)
├── sample_data/
│   └── generate_ventas.py      # Generador de CSVs de ejemplo
├── requirements.txt
└── README.md
Enter fullscreen mode Exit fullscreen mode

¿Por qué un solo stack? Para un proyecto de este tamaño, separar en múltiples stacks agrega complejidad sin beneficio. Un cdk deploy y tenés el Data Lake entero corriendo. Cuando el proyecto crece (múltiples equipos, múltiples ambientes), ahí sí tiene sentido separar — pero ese es un problema que vas a tener recién cuando lo tengas.


Las piezas del stack

Veamos qué define el stack, pieza por pieza.

El bucket con sus zonas

El bucket de S3 se crea con las tres zonas que ya conocemos de la parte 2, separadas por prefijos:

bucket = s3.Bucket(
    self, "DataLakeBucket",
    encryption=s3.BucketEncryption.S3_MANAGED,
    block_public_access=s3.BlockPublicAccess.BLOCK_ALL,
    versioned=True,
)
Enter fullscreen mode Exit fullscreen mode

Fijate dos decisiones que no son negociables: cifrado activado y acceso público bloqueado. Son dos líneas de código que te ahorran un incidente de seguridad.

La Lambda que dispara el pipeline

La función Lambda es la misma idea que vimos en la parte 2, pero ahora desplegada de verdad, con su trigger configurado en el código:

trigger_fn = _lambda.Function(
    self, "TriggerPipelineFn",
    runtime=_lambda.Runtime.PYTHON_3_12,
    handler="trigger_pipeline.lambda_handler",
    code=_lambda.Code.from_asset("lambda_src"),
)

bucket.add_event_notification(
    s3.EventType.OBJECT_CREATED,
    s3n.LambdaDestination(trigger_fn),
    s3.NotificationKeyFilter(prefix="raw/"),
)
Enter fullscreen mode Exit fullscreen mode

El detalle importante es el NotificationKeyFilter: solo los archivos que llegan a raw/ disparan el pipeline. Si Lambda escuchara todo el bucket, el propio Glue Job escribiendo en processed/ volvería a disparar el pipeline... y bienvenido al loop infinito que te explota la factura.

El filtro de prefijo no es un detalle estético. Es la diferencia entre un pipeline event-driven y un loop infinito que procesa sus propias salidas.

El Glue Job: de CSV a Parquet

El Glue Job toma el CSV crudo y lo escribe como Parquet particionado por fecha en la processed zone. ¿Por qué Parquet? Lo adelanté en el post anterior: Athena cobra por datos escaneados, y Parquet es un formato columnar comprimido que puede reducir el escaneo hasta un 80%.

El mismo dataset, dos formatos: Parquet escanea una fracción de los datos y la factura de Athena lo agradece.

El Crawler y la base de datos

El stack también define la base de datos del Glue Data Catalog y un Crawler apuntando a la processed zone. Cada vez que el job termina, el catálogo se actualiza y las tablas nuevas (o las particiones nuevas) quedan disponibles para Athena sin intervención manual.

Lake Formation y los permisos

Por último, el stack registra el bucket en Lake Formation y define los permisos sobre la base de datos. En un proyecto real acá es donde definirías qué equipo ve qué tablas y qué columnas — en el repo dejé el esqueleto con un permiso de ejemplo para que veas el patrón y lo extiendas según tu caso.


Desplegarlo en tu cuenta

Con el repo clonado y tus credenciales de AWS configuradas:

# Instalar dependencias
pip install -r requirements.txt

# Bootstrap de CDK (solo la primera vez en la cuenta/región)
cdk bootstrap

# Desplegar el Data Lake completo
cdk deploy
Enter fullscreen mode Exit fullscreen mode

Eso es todo. Un comando y CDK crea el bucket, la Lambda, el job, el crawler, la base de datos y los permisos. Al terminar, el output del deploy te muestra el nombre del bucket para que empieces a subir archivos.


El momento mágico

Ahora viene la mejor parte. Generamos datos de ejemplo y los subimos a la raw zone:

# Generar un CSV de ventas de ejemplo
python sample_data/generate_ventas.py

# Subirlo a la raw zone
aws s3 cp ventas_2026-06-10.csv s3://<tu-bucket>/raw/ventas/
Enter fullscreen mode Exit fullscreen mode

Y... no hacemos nada más. El archivo llega, Lambda lo detecta, el Glue Job lo transforma, el Crawler actualiza el catálogo. Todo solo.

Unos minutos después, abrimos Athena y consultamos:

SELECT
    sucursal,
    SUM(monto) AS total_ventas
FROM datalake_db.ventas
WHERE fecha = '2026-06-10'
GROUP BY sucursal
ORDER BY total_ventas DESC;
Enter fullscreen mode Exit fullscreen mode

Subiste un CSV y unos minutos después lo estás consultando con SQL. Sin servidores, sin clusters, sin conexiones. Eso es un Data Lake serverless funcionando.


¿Cuánto costó la demo?

Les debo el número porque es de los más compartibles del post: correr esta demo completa — deploy, varios archivos procesados, queries en Athena — cuesta centavos de dólar. El desglose:

Servicio Uso en la demo Costo aproximado
S3 Algunos MB almacenados < USD 0.01
Lambda Un puñado de invocaciones USD 0 (free tier)
Glue Job Pocos minutos de DPU USD 0.10–0.50
Glue Crawler Ejecuciones cortas < USD 0.05
Athena KBs escaneados (gracias, Parquet) < USD 0.01

Importante: cuando termines de experimentar, cdk destroy elimina todo el stack. No dejes recursos huérfanos dando vueltas — el Glue Crawler con schedule es el clásico que te aparece en la factura del mes siguiente.


Cierre de la serie

Recapitulemos el camino que hicimos en estos tres posts:

  1. Parte 1: qué es un Data Lake, sus desafíos y cómo fluyen los datos
  2. Parte 2: los 5 servicios de AWS que forman el núcleo serverless
  3. Parte 3: el pipeline completo, construido como código y desplegable en minutos

El repo queda abierto: github.com/alvarongg/serverless-datalake-aws. Si lo desplegás, lo rompés o lo mejorás, los issues y pull requests son bienvenidos.

¿Y ahora qué? Tener el Data Lake funcionando es la mitad del trabajo. La otra mitad es evitar que con el tiempo se convierta en un Data Swamp — y de eso, justamente, viene el próximo post.

Si tienen preguntas, las leo en los comentarios.

Abrazo grande, hasta la próxima 🚀

Top comments (0)