
Construir un pipeline ELT en AWS con S3, Glue y Athena
¿Por qué ELT en lugar de ETL?
Los procesos tradicionales de ETL (Extraer, Transformar, Cargar) transforman los datos antes de cargarlos en un almacén. ELT (Extraer, Cargar, Transformar) invierte el enfoque: primero cargar, después transformar.
¿Por qué importa? Los volúmenes de datos actuales son enormes. Transformar antes de cargar genera cuellos de botella y exige recursos de cómputo costosos que quedan ociosos entre transformaciones.
Con ELT puedes:
- Cargar datos crudos rápido en almacenamiento económico (S3)
- Transformar bajo demanda cuando realmente lo necesites
- Escalar cómputo de forma independiente al almacenamiento
- Conservar los datos crudos para casos de uso futuros que aún no imaginas
Figura 1: Arquitectura de alto nivel de un pipeline ELT en AWS
El stack ELT en AWS
Este pipeline usa tres servicios principales de AWS:
- Amazon S3: Almacenamiento de objetos para datos crudos y transformados
- AWS Glue: Servicio ETL serverless para transformación de datos
- Amazon Athena: Motor de consultas SQL serverless sobre datos en S3
Juntos forman un pipeline de datos totalmente serverless y de pago por uso que escala de gigabytes a petabytes.
Figura 2: Cómo trabajan juntos S3, Glue y Athena
Visión general de la arquitectura
Así fluyen los datos en el pipeline:
Sistemas fuente → S3 (Zona cruda) → Glue (Transformar) → S3 (Zona curada) → Athena (Consultas)
Zonas de datos en S3
Organizamos los buckets de S3 en zonas lógicas:
- Zona cruda:
s3://your-bucket/raw/- Datos fuente sin procesar - Zona de staging:
s3://your-bucket/staging/- Transformaciones intermedias - Zona curada:
s3://your-bucket/curated/- Datos finales listos para consulta
Esta separación aporta:
- Lineaje de datos: Siempre puedes rastrear hasta el origen
- Reprocesamiento: Reconstruir datos curados desde crudos es sencillo
- Cumplimiento: Los datos crudos se conservan para auditorías
Figura 3: Estructura del bucket S3 con zonas de datos
Paso 1: Configurar los buckets de S3
Primero, crea tu bucket de S3 con una organización clara:
aws s3 mb s3://your-company-data-lake --region us-east-1
Luego crea la estructura de zonas:
aws s3api put-object --bucket your-company-data-lake --key raw/
aws s3api put-object --bucket your-company-data-lake --key staging/
aws s3api put-object --bucket your-company-data-lake --key curated/
Configuración importante en S3:
- Control de versiones: Actívalo para recuperación de datos
- Políticas de ciclo de vida: Mover datos antiguos a Glacier después de 90 días
- Cifrado: Activar SSE-S3 o SSE-KMS
- Bloquear acceso público: Siempre activado en data lakes
Figura 4: Configuración del bucket S3 en la consola de AWS
Paso 2: Crear crawlers de AWS Glue
Los Glue Crawlers descubren automáticamente el esquema de tus datos. Escanean S3 y crean o actualizan el Glue Data Catalog.
Configurar un crawler
-
Ve a la consola de AWS Glue → Crawlers → Agregar crawler
-
Configurar fuente de datos: Apunta a tu zona cruda en S3
- Ruta:
s3://your-company-data-lake/raw/source-system/
- Ruta:
-
Rol IAM: Crea un rol con permisos de S3 y Glue:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:GetObject", "s3:PutObject" ], "Resource": "arn:aws:s3:::your-company-data-lake/*" }, { "Effect": "Allow", "Action": [ "glue:*" ], "Resource": "*" } ] } -
Salida: Crear base de datos
raw_datay tablasource_system
Figura 5: Configuración de un Glue Crawler en la consola de AWS
Ejecutar el crawler
Los crawlers pueden ejecutarse por horario o bajo demanda. En producción, programa su ejecución:
- Cada hora: Para fuentes de datos de alta frecuencia
- Diario: Para procesamiento por lotes
- Por evento en S3: Disparar vía EventBridge cuando lleguen archivos nuevos
Figura 6: Configuración del horario del crawler
Paso 3: Crear trabajos ETL en Glue
Los trabajos ETL de Glue transforman tus datos. Puedes escribirlos en Python o Scala, o usar el editor visual.
Ejemplo de trabajo Glue en Python
import sys
from awsglue.transforms import *
from awsglue.utils import getResolvedOptions
from pyspark.context import SparkContext
from awsglue.context import GlueContext
from awsglue.job import Job
args = getResolvedOptions(sys.argv, ['JOB_NAME', 'input_path', 'output_path'])
sc = SparkContext()
glueContext = GlueContext(sc)
spark = glueContext.spark_session
job = Job(glueContext)
job.init(args['JOB_NAME'], args)
# Leer desde el catálogo de Glue
datasource = glueContext.create_dynamic_frame.from_catalog(
database="raw_data",
table_name="source_system"
)
# Transformar: limpiar y enriquecer datos
def clean_record(record):
# Eliminar nulos, estandarizar formatos
record["processed_date"] = datetime.now().isoformat()
return record
cleaned = Map.apply(
frame=datasource,
f=clean_record,
transformation_ctx="cleaned"
)
# Escribir en la zona curada
glueContext.write_dynamic_frame.from_options(
frame=cleaned,
connection_type="s3",
connection_options={
"path": args['output_path'],
"partitionKeys": ["year", "month", "day"]
},
format="parquet"
)
job.commit()
Figura 7: Código del trabajo ETL de Glue en la consola de AWS
Configuración del trabajo
- Tipo de worker: G.1X (2 vCPU, 8 GB) para la mayoría de cargas
- Número de workers: Empieza con 2, escala según el volumen de datos
- Tiempo límite del trabajo: Configura 2 horas por seguridad
- Versión de Glue: Usa la más reciente (4.0+) para soporte de Python 3.10
Figura 8: Configuración del trabajo de Glue
Paso 4: Consultar con Amazon Athena
Cuando los datos están en S3 (crudos o curados), Athena permite consultarlos con SQL estándar.
Configurar Athena
-
Crear base de datos:
CREATE DATABASE IF NOT EXISTS curated_data LOCATION 's3://your-company-data-lake/curated/'; -
Crear tabla (si no usas el catálogo de Glue):
CREATE EXTERNAL TABLE curated_data.transactions ( transaction_id string, customer_id string, amount decimal(10,2), transaction_date timestamp ) PARTITIONED BY (year int, month int, day int) STORED AS PARQUET LOCATION 's3://your-company-data-lake/curated/transactions/'; -
Cargar particiones:
MSCK REPAIR TABLE curated_data.transactions;
Figura 9: Ejecutar consultas en Athena
Consejos para optimizar consultas
- Particionar: Siempre particiona por columnas de fecha
- Formatos columnares: Parquet u ORC, no CSV
- Limitar columnas: SELECT solo lo que necesites
- Usar WHERE pronto: Filtrar antes de los JOIN
-- Bien: particionado y filtrado
SELECT customer_id, SUM(amount) as total
FROM curated_data.transactions
WHERE year = 2025 AND month = 1
GROUP BY customer_id;
-- Mal: escaneo completo de tabla
SELECT * FROM curated_data.transactions;
Figura 10: Resultados de consulta y métricas de rendimiento
Orquestar el pipeline
En producción necesitas orquestación. Opciones:
Opción 1: AWS Glue Workflows
Constructor visual de flujos en la consola de Glue:
- Crear workflow
- Agregar disparadores (crawler → trabajo ETL → crawler)
- Definir dependencias
- Programar o disparar por eventos
Figura 11: Diagrama del workflow de Glue
Opción 2: EventBridge + Step Functions
Más control y mejor manejo de errores:
{
"Comment": "ELT Pipeline Orchestration",
"StartAt": "RunCrawler",
"States": {
"RunCrawler": {
"Type": "Task",
"Resource": "arn:aws:states:::glue:startCrawler.sync",
"Parameters": {
"CrawlerName": "raw-data-crawler"
},
"Next": "TransformData"
},
"TransformData": {
"Type": "Task",
"Resource": "arn:aws:states:::glue:startJobRun.sync",
"Parameters": {
"JobName": "transform-job"
},
"End": true
}
}
}
Figura 12: Máquina de estados de Step Functions para orquestar el pipeline
Optimización de costos
Este stack serverless es rentable, pero los costos pueden dispararse si no se gestionan:
Costos de S3
- Almacenamiento: $0.023/GB/mes (Standard)
- Peticiones: $0.0004 por 1,000 peticiones GET
- Optimización: Usa políticas de ciclo de vida para pasar a Glacier
Costos de Glue
- Crawler: $0.44 por DPU-hora (mínimo 10 minutos)
- Trabajo ETL: $0.44 por DPU-hora
- Optimización: Ajusta el tamaño de los workers, usa instancias spot
Costos de Athena
- Consulta: $5 por TB escaneado
- Optimización:
- Usar Parquet (columnar, comprimido)
- Particionar tablas
- Proyección de columnas
Ejemplo real: Un pipeline diario de 100 GB cuesta aproximadamente:
- Almacenamiento S3: $2.30/mes
- Glue (1 hora/día): $13.20/mes
- Athena (10 consultas/día, 1 GB cada una): $0.50/mes
- Total: ~$16/mes
Figura 13: Desglose mensual de costos de un pipeline ELT típico
Buenas prácticas
- Evolución del esquema: Usa Glue Schema Registry para versionado de esquemas
- Manejo de errores: Implementa colas dead-letter para registros fallidos
- Monitoreo: Configura alarmas en CloudWatch por fallos de trabajos
- Seguridad: Cifra datos en reposo y en tránsito, usa roles IAM
- Pruebas: Prueba transformaciones con datos de muestra antes de corridas completas
- Documentación: Documenta el lineaje de datos y la lógica de transformación
Figura 14: Panel de CloudWatch para monitoreo del pipeline
Errores comunes
- Sobre-particionar: Demasiadas particiones pequeñas vuelven lentas las consultas
- Sub-particionar: Los escaneos completos de tabla son costosos
- Ignorar el tamaño de archivos: Apunta a archivos Parquet de 128 MB a 1 GB
- Sin lógica de reintento: Los fallos transitorios requieren reintentos automáticos
- Rutas fijas en código: Usa trabajos parametrizados para flexibilidad
Conclusión
Los pipelines ELT en AWS con S3, Glue y Athena ofrecen una base escalable y rentable para arquitecturas de datos modernas. Son serverless: no hay que administrar infraestructura y escalan con el volumen de datos.
La clave es empezar simple: cargar datos crudos en S3, transformarlos con Glue y consultar con Athena. Cuando crezcan las necesidades, agrega orquestación, monitoreo y optimización.
En SolarDevs hemos construido pipelines ELT que procesan terabytes al día para clientes de distintos sectores. El patrón está probado, las herramientas son maduras y los costos son predecibles.
Siguientes pasos:
- Empieza con una sola fuente de datos
- Automatiza una transformación
- Consulta los resultados
- Itera y expande
El data lake te está esperando.
Construye tu futuro.
¿Listo para transformar tu infraestructura con agentes de IA inteligentes?
Iniciar descubrimiento