Tal y como mencionaba en el artículo Preparando datos, lo más importante es ser consciente de qué herramienta utilizar en cada escenario. Todo depende del caso de uso, la experticia del equipo, el tiempo disponible y el nivel de complejidad; al final, siempre se trata de trade-offs.
Con el objetivo de tener un panorama lo más completo posible, en este laboratorio exploraremos otro camino para llegar a Roma. En esta ocasión utilizaremos AWS Glue de principio a fin para preparar nuestro ya conocido dataset de tarjetas. El enfoque será distinto: esta vez me centraré en el proceso, ya que el análisis del dataset lo abordamos previamente en el artículo mencionado.
La intención es recorrer el flujo completo, desde que un nuevo archivo es escrito en Amazon S3 hasta que los datos quedan disponibles para su consumo analítico. Para ello, construiremos un pipeline que se dispare automáticamente ante la llegada de nuevos datos, ejecute las transformaciones necesarias y actualice los metadatos en el catálogo.
🧩 Componentes del laboratorio
Para este laboratorio utilizaremos los siguientes componentes:
🪣 Amazon S3
Como almacenamiento de los datasets para fines académicos.⏱️ Amazon EventBridge
Encargado de disparar el proceso de transformación ante la llegada de un nuevo archivo.🔁 AWS Glue Workflow
Responsable de la orquestación y de definir la secuencia de pasos necesarios para una limpieza, transformación y entrega exitosa.🛠️ AWS Glue Job
Donde se realizan las limpiezas y transformaciones básicas de los datos.🗂️ AWS Glue Crawler
Encargado de poblar y actualizar el Data Catalog.
⚙️ Algunas decisiones técnicas
Ahora que conocemos las herramientas que nos apoyarán, el siguiente diagrama define de forma conceptual la arquitectura que soporta el flujo.
En este caso de uso no conocemos de antemano el momento en el que ingresarán nuevos archivos para ser procesados. No existe una periodicidad definida: los archivos se cargarán conforme se disponga de nuevos datos. No hay un proceso que deposite información cada 24 horas ni una fuente que genere archivos de forma continua.
Bajo estas condiciones, una arquitectura orientada a eventos es la opción más adecuada. Con este enfoque, el procesamiento ocurre únicamente cuando es necesario, evitando ejecuciones innecesarias y consumo de recursos en vano. Archivo nuevo, ejecución nueva.
Para lograr este desacople, Amazon EventBridge actúa como la capa intermedia del flujo. Esto nos permite aislar la ingesta del procesamiento y nos da flexibilidad ante cambios futuros. Hoy el evento dispara un Glue Workflow; mañana podría activar otros destinos o incluso múltiples flujos en paralelo, sin necesidad de rediseñar la arquitectura.
Los pipelines event-driven son ampliamente utilizados porque:
- ⚡ Se integran de forma natural con arquitecturas serverless.
- 🧩 Reducen la complejidad operativa.
- ⏳ Evitan dependencias temporales artificiales.
En nuestro caso, los datos se procesan cuando llegan. Si no llega nada, no hay ejecuciones ni consumo de recursos asociados.
🔁 Orquestación con Glue Workflow
Otro elemento clave del flujo es AWS Glue Workflow. Su función no es transformar datos, sino orquestar el proceso: definir qué operaciones se ejecutan y en qué orden. Conceptualmente, cumple un rol similar al que podría desempeñar AWS Step Functions en otros escenarios.
El Workflow nos permite coordinar los distintos componentes del pipeline y asegurar que cada paso se ejecute solo cuando el anterior ha finalizado correctamente, aportando control y claridad al proceso completo.
🗂️ Separación por capas: raw y curated
Uno de los principios que seguimos en este laboratorio es la separación por capas, comenzando por raw y avanzando hacia curated. Esta distinción no es meramente organizativa; responde a necesidades de trazabilidad, control y calidad del dato.
📥 Capa raw
La capa raw representa el punto de entrada del dato. Aquí se almacenan los archivos tal y como llegan desde la fuente, sin aplicar transformaciones ni validaciones complejas.
Sus principales características son:
- 📄 Los datos se preservan en su forma original.
- 🔒 No se modifica el contenido; únicamente se almacena.
- ♻️ Sirve como respaldo para reprocesamientos, auditorías o correcciones futuras.
En este laboratorio, Amazon S3 actúa como la capa raw, recibiendo el dataset de tarjetas cada vez que un nuevo archivo es cargado.
📊 Capa curated
La capa curated contiene los datos limpios, transformados y listos para consumo. En esta etapa se aplican las reglas necesarias para que el dataset pueda ser utilizado de forma confiable por procesos analíticos.
En esta capa:
- 🧮 Se normalizan columnas y tipos de datos.
- 🧹 Se corrigen inconsistencias básicas.
- 📐 Se definen esquemas más estables y predecibles.
Esta separación permite mantener una arquitectura ordenada, auditable y preparada para evolucionar a medida que el pipeline crece en complejidad.
Para serles honesta, comencé abordando el core del problema: la definición básica de Amazon S3 y el Glue Job encargado de las transformaciones. Sin embargo, al construir el flujo de manera evolutiva, algunos “detalles” quedaron fuera del radar y terminaron complicando el proceso más de lo necesario.
Hubo un punto en el que cada pieza parecía estar correctamente configurada: el evento se disparaba, el trigger funcionaba, incluso validé el flujo utilizando CloudWatch como destino y, aun así, el pipeline no lograba ejecutarse de principio a fin. Después de darle varias vueltas al problema, caí en cuenta de lo más obvio: los permisos.
Sí, fue uno de esos momentos frustrantes en los que todo está bien… excepto lo fundamental. Precisamente por esa experiencia, y para evitar que el laboratorio se vuelva innecesariamente complejo, en las siguientes secciones abordaré todas las consideraciones de configuración desde el inicio, incluyendo roles y permisos, con el objetivo de que el recorrido sea lo más smooth posible y el pipeline funcione correctamente desde el primer intento.
🪣 S3: definamos el almacenamiento
Como en la mayoría de los pipelines de datos, el punto de inicio será nuestro bucket de Amazon S3. En este laboratorio, una de las primeras consideraciones es la organización del almacenamiento, para lo cual definiremos dos directorios (o prefijos):
/raw/curated
Tal y como lo explicamos previamente, los datos de origen se mantienen separados en la capa raw. Aquí es donde esperaremos la llegada de nuevos archivos de precios, sin aplicar ningún tipo de transformación.
Por su parte, en la capa curated depositaremos los datos ya procesados: limpios, con los tipos de datos adecuados y listos para su consumo analítico.
⚠️ Consideración importante: integración con EventBridge
Dado que utilizaremos Amazon EventBridge para disparar el pipeline, es fundamental activar las notificaciones de EventBridge en el bucket. Sin este paso, los eventos de creación de objetos no podrán ser capturados y el flujo no se iniciará.
🔐 Permisos a nivel de bucket
Aunque aún no hemos definido todos los componentes del pipeline, es importante anticipar los permisos necesarios desde el inicio. A nivel de bucket policy, debemos permitir lo siguiente:
📡 Amazon EventBridge
Debe tener la capacidad de listar objetos y realizar operaciones de lectura (ListBucketyGetObject) para poder reaccionar a los eventos de S3.🛠️ AWS Glue
Debe ser capaz no solo de leer, sino también de escribir y eliminar objetos en la capa curated.
En este laboratorio, al tratarse de un ejercicio académico, el Glue Job reescribirá el mismo archivo de salida cuando se ejecute nuevamente. Esto implica que primero se realiza un borrado del objeto existente y luego un PutObject.
💡 Pro tip
En un escenario productivo, lo recomendable sería generar archivos nuevos, por ejemplo incorporando un timestamp en el nombre. Sin embargo, para este ejercicio simplificamos el flujo y priorizamos la claridad del proceso.
A continuación, se muestra un ejemplo de la política asociada al bucket:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowEventBridgeToReadS3Events",
"Effect": "Allow",
"Principal": {
"Service": "events.amazonaws.com"
},
"Action": [
"s3:GetObject",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::poctarjetasprecios",
"arn:aws:s3:::poctarjetasprecios/*"
]
},
{
"Sid": "AllowGlueWriteToCurated",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::072962861776:role/service-role/AWSGlueServiceRole-Pokemon"
},
"Action": [
"s3:PutObject",
"s3:DeleteObject",
"s3:AbortMultipartUpload"
],
"Resource": "arn:aws:s3:::poctarjetasprecios/curated/*"
}
]
}
En la siguiente sección entraremos de lleno en AWS Glue, comenzando por la definición del Job y las consideraciones clave para evitar errores comunes durante la ejecución del pipeline.
🧪 AWS Glue: Jobs, Crawlers y Workflow Orchestration
Recordemos que AWS Glue es un servicio de integración de datos totalmente gestionado que facilita la descubierta, preparación y catalogación de datos para casos de uso de analítica, machine learning y data engineering.
En este laboratorio utilizaremos Glue de forma integral:
🛠️ Glue Jobs
Para realizar las transformaciones y limpiezas de los datos.🗂️ Glue Crawlers
Para poblar y actualizar el Glue Data Catalog.🔁 Glue Workflow Orchestration
Para coordinar la ejecución de todo el proceso.
Tal y como discutimos en el artículo anterior, el dataset utilizado nos servirá más adelante para entrenar un modelo que permita estimar el valor de mercado de una tarjeta. Los detalles completos del dataset pueden consultarse en ese artículo; sin embargo, a continuación haré una breve reseña de sus características más relevantes desde la perspectiva de transformación.
Las variables más importantes de una carta incluyen su rareza, tipo, hits y precios. En este dataset, los campos de precio se encuentran representados como strings, y la variable marketprice —que será la que deseamos predecir— presenta una cantidad significativa de valores nulos.
Por lo tanto, antes de poder utilizar los datos, es necesario:
- 🔄 Realizar cambios de tipo de datos en las columnas de precio.
- 🧹 Eliminar las filas cuyo valor de
marketpricesea nulo.
⚠️ Diferencias importantes con Data Wrangler
Un punto importante a destacar es la diferencia con el enfoque utilizado previamente con Data Wrangler. Con AWS Glue, las transformaciones y limpiezas deben implementarse mediante scripts, lo que implica un mayor control, pero también una mayor responsabilidad sobre el proceso.
Los cambios de tipo de datos no pueden realizarse de forma directa. Antes de aplicar el type casting, es necesario limpiar los valores, eliminando cualquier carácter que no corresponda al tipo esperado, como:
- 💲 símbolos de moneda (
$) - ␣ espacios en blanco
- 🔣 otros caracteres no numéricos
Una vez realizada esta limpieza, es posible convertir las columnas al tipo de dato adecuado. Finalmente, se procede a eliminar columnas que no aportan valor para el análisis o el entrenamiento del modelo, dejando un dataset más limpio y enfocado.
🧱 Construyendo el Job paso a paso
En este laboratorio iniciaremos la creación de un AWS Glue Job utilizando el editor de scripts, con el objetivo de comprender la estructura mínima necesaria para ejecutar un Job de forma exitosa antes de avanzar hacia transformaciones más complejas.
🆕 Creación del Job
- En la consola de AWS Glue, nos dirigimos al menú ETL Jobs.
- Seleccionamos Create Job y elegimos la opción Script Editor.
⚙️ Selección del Engine
- Como Engine, seleccionamos Spark.
Esto nos permite trabajar con un Job basado en Apache Spark y acceder directamente al editor de código para definir la lógica del procesamiento.
Una vez dentro del editor:
- 🧽 Eliminamos todo el código generado automáticamente.
- 🧩 Construimos el script paso a paso, comenzando con el ejemplo más básico para validar la ejecución del Job.
✅ Primer script: validación de ejecución
Para esta primera prueba no es necesario importar librerías adicionales ni utilizar el contexto de Glue. Utilizamos únicamente el siguiente código:
print("Glue Job ejecutado correctamente")
Este script cumple un propósito claro: verificar que el Job puede ejecutarse correctamente, que el rol IAM está bien configurado y que la infraestructura de ejecución se aprovisiona sin errores.
⚙️ Configuración de Job Details
En la sección Job Details definimos los siguientes parámetros:
🏷️ Name
Nombre identificador del Job dentro de AWS Glue.📝 Description
Descripción breve del propósito del Job, útil para fines de documentación y mantenimiento.🔐 IAM Role
Rol que utilizará el Job para ejecutarse.
Este rol debe contar al menos con la políticaAWSGlueServiceRole, además de los permisos necesarios para acceder a los recursos que el Job vaya a utilizar (por ejemplo, Amazon S3).
⚠️ Sin un rol válido, el Job no puede ejecutarse.
🧱 Worker Type
Para efectos de este laboratorio seleccionamos G.1X, que corresponde al tipo de worker con las especificaciones más bajas disponibles para Spark Jobs.
Un worker es la unidad de capacidad de cómputo que el servicio utiliza para ejecutar un Job. Cada uno provee recursos de CPU, memoria y almacenamiento temporal, y es sobre estos recursos donde se ejecutan las tareas de Apache Spark asociadas al Job.
El número y tipo de workers determinan la capacidad de procesamiento, el tiempo de ejecución y el costo del Job.🔢 Requested number of workers
Por defecto, AWS Glue asigna 10 workers, lo cual incrementa innecesariamente los costos en pruebas simples.
Para minimizar costos, configuramos el valor mínimo permitido, que en este caso es 2 workers.🐍 Language
Seleccionamos Python como lenguaje del Job.
Una vez definidos estos detalles, salvamos y ejecutamos el Job. Podemos ver el detalle de la ejecución en OutputLogs, como se muestra en la siguiente imagen.
💡 Pro Tip
En el caso de los AWS Glue Jobs, los costos están asociados directamente a la ejecución del Job. Asegúrate de que los Jobs se encuentren en estado Completed una vez finalizados.
Para un laboratorio de este tipo, utiliza el worker más pequeño disponible y una cantidad máxima de 2 workers para minimizar costos.
🛠️ Continuemos con el Job real
Ahora que ya hemos validado la ejecución de nuestro primer AWS Glue Job, es momento de avanzar hacia el Job real, es decir, el código que implementa las transformaciones necesarias sobre el dataset.
En esta etapa pasamos de un Job de verificación a un Job funcional, cuyo objetivo es leer los datos desde la capa raw, limpiarlos, transformarlos y escribir el resultado en la capa curated.
🎯 Objetivo del Job
El Job realizará las siguientes acciones, en orden:
Importar las librerías necesarias
Incluiremos los módulos requeridos para trabajar con Spark y AWS Glue.Inicializar una sesión de Spark
Esta sesión será la base sobre la cual se ejecutarán todas las operaciones de lectura, transformación y escritura de datos.Definir la ruta de entrada en Amazon S3
Declararemos como variable el path donde se encuentra el archivo a transformar, correspondiente a la capa raw.Cargar los datos en un DataFrame
Leeremos el archivo desde S3 y cargaremos su contenido en un DataFrame de Spark (puedes pensarlo como una tabla en memoria).
Indicaremos que la primera fila del archivo contiene los headers de las columnas.
Antes de aplicar cualquier transformación de tipo de dato, realizaremos una limpieza previa. Las columnas de precio contienen caracteres no numéricos, por lo que primero eliminaremos símbolos y valores indeseados mediante una función de limpieza, y solo después aplicaremos el type casting correspondiente.
Filtrar registros con valores nulos
Eliminaremos las filas cuyo valor en la columnamarketpricesea nulo, ya que no aportan valor para el análisis ni para el entrenamiento posterior del modelo.Escribir el resultado en la capa curated
Finalmente, persistiremos el DataFrame transformado en Amazon S3, dentro del prefijo correspondiente a la capa curated.
💡 Pro Tip
Antes de aplicar transformaciones y escribir los datos de salida, es una buena práctica ejecutar undf.show().
Esto nos permite visualizar los datos y validar los tipos asociados a cada columna. En este punto, y dado que estamos leyendo un archivo CSV, observarás que todas las columnas se interpretan inicialmente como strings, lo cual refuerza la necesidad de realizar las transformaciones de tipo de dato de forma explícita.
A continuación, revisaremos el código final del Job. Incluiré comentarios en cada sección para que el flujo sea más sencillo de seguir y puedas identificar claramente el propósito de cada bloque.
# Importamos las librerías mínimas
from pyspark.sql import SparkSession
from pyspark.sql.functions import col, regexp_replace
# Abrimos la sesión de Spark
spark = SparkSession.builder.getOrCreate()
# En esta variable dejamos la ruta del archivo que esperamos cargar
ruta_s3 = "s3://poctarjetasprecios/raw/BaseSetProductsAndPrices.csv"
# Cargamos el DataFrame indicando que la primera fila contiene los headers
df = spark.read.option("header", "true").csv(ruta_s3)
# En este vector definimos las columnas a limpiar y convertir
# En este paso solo se define el plan de ejecución; Spark aún no aplica las transformaciones
price_columns = [
"lowPrice",
"midPrice",
"highPrice",
"marketPrice",
"directLowPrice"
]
for c in price_columns:
df = df.withColumn(
c,
regexp_replace(col(c), "[^0-9.]", "").cast("double")
)
# Filtramos únicamente los registros con marketPrice no nulo
df = df.filter(col("marketPrice").isNotNull())
# Definimos la ruta de salida en la capa curated
ruta_curated = "s3://poctarjetasprecios/curated/product_prices2/"
# Ahora sí, Spark ejecuta el plan definido y
df.write.mode("overwrite").parquet(ruta_curated)
Esto ya transforma nuestro archivo.
Ahora necesitamos el Crawler.
🗂️ Creación del Glue Crawler
Posteriormente, procedí a crear el Glue Crawler, configurando los siguientes parámetros clave:
🏷️ Nombre del crawler
Identificador claro y descriptivo.🪣 Fuente de datos (Data Source)
Amazon S3, apuntando específicamente al prefijo donde se encuentra el dataset curated.🧾 Prefijo para el nombre de la tabla
Definido para mantener consistencia y evitar confusiones en el catálogo.⏱️ Frecuencia de ejecución
Configurado para ejecutarse bajo demanda, con el objetivo de evitar ejecuciones innecesarias y posibles impactos en la facturación.🔐 Rol de IAM
El rol asociado al crawler debe contar, como mínimo, con permisos de lectura sobre el bucket de S3 donde residen los datos, además de permisos para escribir metadatos en el Glue Data Catalog.
🔁 Orquestación del flujo con AWS Glue Workflow
Una vez validado el Glue Job de transformación, el siguiente paso fue orquestar el flujo completo utilizando AWS Glue Workflow. El objetivo no es solo ejecutar tareas de forma aislada, sino definir explícitamente el orden y la dependencia entre ellas, algo fundamental en cualquier proceso de preparación de datos.
El workflow implementado sigue una lógica simple pero correcta:
Inicio del flujo
El workflow se dispara de forma controlada (manual o posteriormente mediante eventos), actuando como punto de entrada del proceso.Ejecución del Glue Job
El Glue Job se encarga de leer los datos desde la zona raw en Amazon S3, realizar transformaciones mínimas y escribir el resultado en la zona curated.Trigger condicional
Se utiliza un trigger condicional para garantizar que el siguiente paso solo se ejecute si el Glue Job finaliza correctamente.
Esta validación es importante para evitar catalogar datos incompletos o inconsistentes en caso de fallos durante la transformación.Ejecución del Glue Crawler
Finalmente, el Glue Crawler escanea los datos ya procesados en la capa curated y actualiza el Glue Data Catalog. De esta forma, los datos quedan disponibles para su consumo posterior mediante servicios como Amazon Athena.
🧩 Separación de responsabilidades
Este enfoque permite desacoplar responsabilidades de forma clara:
- 🛠️ El Job se enfoca en la transformación.
- 🗂️ El Crawler se enfoca en el descubrimiento y la catalogación.
- 🔁 El Workflow define la secuencia y las dependencias entre ambos.
💡 Pro Tip
Ejecuta el workflow de manera separada antes de integrarlo con el pipeline. De esta forma podrás validar que este componente se ejecuta correctamente de manera aislada.
Último paso: automatización con Amazon EventBridge
El paso final del laboratorio consiste en utilizar Amazon EventBridge para disparar automáticamente el flujo cada vez que un nuevo archivo es cargado en Amazon S3.
En teoría, esta es la parte más sencilla; en la práctica, fue la que más tiempo me tomó resolver.
Y vale la pena decirlo abiertamente: el problema no fue técnico, sino de orden. Pasé por alto dos aspectos básicos:
- Los permisos necesarios para que AWS Glue pudiera ser invocado.
- La habilitación de notificaciones de eventos desde S3.
Esta experiencia deja una lección importante: antes de asumir que el problema es complejo, conviene revisar siempre lo más evidente, especialmente permisos e integraciones entre servicios.
Dado que estos prerrequisitos ya habían sido configurados al inicio del laboratorio, el último paso se redujo a crear una regla en Amazon EventBridge con la siguiente lógica:
- Origen del evento: Amazon S3
- Tipo de evento: Creación de objetos (Object Created)
- Destino: AWS Glue Workflow
Con esta configuración, cada vez que un archivo nuevo ingresa al bucket (o prefijo) definido, el workflow se ejecuta automáticamente, iniciando el proceso de transformación y catalogación de datos.
Destinos del evento
Amazon EventBridge permite configurar hasta cinco destinos por regla.
En este caso, además del Glue Workflow, se habilitó Amazon CloudWatch únicamente con fines de observabilidad y validación del evento, aunque no es estrictamente necesario para el funcionamiento del flujo.
A partir de este punto, el proceso queda completamente automatizado:
cada nuevo archivo que llega a S3 desencadena todas las acciones esperadas sin intervención manual, cerrando así el ciclo completo de ingesta, transformación y catalogación.
Conclusiones
Una vez finalizado este laboratorio, se logra implementar una automatización de extremo a extremo para la preparación de un conjunto de datos, integrando varios servicios administrados de AWS y entendiendo el rol específico que cada uno cumple dentro del pipeline.
El uso de AWS Glue Jobs resulta especialmente adecuado cuando se trabaja con datasets de tamaño considerable, donde el procesamiento distribuido de Spark permite escalar transformaciones de forma eficiente.
Por su parte, AWS Glue Workflow simplifica la orquestación del proceso, permitiendo definir dependencias claras entre tareas sin necesidad de introducir herramientas adicionales de orquestación.
Como en toda arquitectura de datos, todo se trata de trade-offs. Elegir Glue implica aceptar ciertos tiempos de arranque y costos asociados a la infraestructura gestionada, a cambio de reducir la complejidad operativa y el mantenimiento.
Durante el desarrollo del laboratorio, hay varios puntos clave que conviene tener siempre presentes:
Spark no ejecuta las transformaciones inmediatamente.
Las operaciones se evalúan de forma perezosa (lazy evaluation) y solo se materializan cuando se ejecutan acciones definitivas comowrite,showocount. Tener esto claro ayuda a entender el comportamiento del job y a razonar sobre su desempeño.Los permisos y las relaciones de confianza entre servicios son críticos.
La correcta configuración de IAM roles, policies y trust relationships entre S3, Glue y EventBridge es indispensable para evitar fricciones innecesarias al implementar el pipeline.Optimización de costos en laboratorios.
Para fines didácticos, es recomendable utilizar el tipo y la cantidad de workers más económicos posibles, evitando dejar los valores por defecto y controlando activamente los costos.Tiempo de arranque de AWS Glue Jobs.
Los Glue Jobs requieren tiempo para aprovisionar la infraestructura. Un tiempo inicial de arranque es normal y no debe generar alarma; sin embargo, es importante verificar siempre que los jobs finalicen correctamente y no queden en estadorunningostoppedde forma inesperada.
En conjunto, este laboratorio no solo permite construir un pipeline funcional, sino también comprender mejor las decisiones técnicas y operativas que acompañan el uso de servicios administrados para la preparación y automatización de datos en AWS.







Top comments (0)