ETL low cost con Fabric versión 2 – Encender la capacidad

3 Feb, 2025
Nelson López Centeno ,

Siguiendo con la nueva versión de nuestra serie sobre ETL «low cost» con Fabric, esta vez proponemos una técnica más completa para controlar la capacidad Fabric desde un servidor «on premise», con el objetivo de minimizar el tiempo que la capacidad permanece encendida pero sin hacer nada.

Recordamos que en esta serie estamos trabajando con dos áreas de trabajo: una con capacidad Fabric que sólo se enciende para hacer la ETL, y otra con licencia Pro con un modelo semántico de Power BI en modo de almacenamiento importar.

En esta entrada explicamos como hemos implementado un mecanismo que nos permite hacer lo siguiente desde un servidor «on premise»:

  • Encender la capacidad Fabric
  • Inciar una canalización de datos que orquesta toda la ETL y actualiza el modelo semántico
  • Monitorizar la actualización del modelo semántico de Power BI
  • Apagar la capacidad Fabric
Este mecanismos lo hemos implementado en nuestra herramienta de línea de comando pbicmd para que se pueda programar su ejecución automática.

Diagrama que muestra un área de trabajo Fabric, otro área de trabajo con licencia Pro o PPU y un servidor on premise que enciende y apaga la capacidad Fabric.

Preparativos

Para probar este mecanismo, hemos creado un modelo semántico muy sencillo que consiste en una sola tabla con los viajes de los taxis de Nueva York en un mes.

Dichos datos ya están cargados en una tabla en un Lakehouse en el área de trabajo con capacidad Fabric.

Por otra parte, hemos creado un informe con Power BI Desktop que importa los datos de la tabla de taxis utilizando el punto de conexión SQL del Lakehouse, y hemos publicado dicho informe en el área de trabajo con licencia Pro.

Volviendo al área de trabajo con capacidad Fabric, hemos creado una canalización de datos que actualiza los datos del modelo semántico de Power BI que está en el área de trabajo con licencia Pro.
En un caso real, esta canalización es la que orquestaría toda la ETL, antes de actualizar el modelo semántico, pero para esta demostración la hemos querido mantener lo más sencilla posible.

Encendido y apagado de la capacidad Fabric

En la versión anterior de esta serie ya comentamos varias opciones para encender y apagar la capacidad.

En este caso nos interesa poderlo hacer desde la línea de comandos de un servidor «on premise», por lo que vamos a utilizar nuestra herramienta pbicmd.

En dicha herramienta ya tenemos un comandos que nos permite encender y apagar la capacidad. Pero todo el mecanismo que vamos a describir aquí lo hemos incorporado como un nuevo comando.

Para implementar el encendido y el apagado hemos utilizado directamente la API REST de Azure para manejar recursos, y que en este caso consiste en hacer una solicitud HTTP GET a uno de estos URLs:

Encender la capacidad Fabric:
https://management.azure.com/{capacity_id}/resume?api-version=2022-07-01-preview
Apagar la capacidad Fabric:
https://management.azure.com/{capacity_id}/suspend?api-version=2022-07-01-preview

Actualización del modelo semántico de Power BI

Al crear la canalización de datos nos encontramos con un problema, porque aunque existe una actividad para actualizar un modelo semántico, no funciona con modelos semánticos que estén en áreas de trabajo con licencia Pro.

Afortunadamente, podemos implementar la actualización del modelo semántico con la API REST de Power BI. Y para más fortuna, existe la librería Semantic Link con la que es muy fácil hacerlo.

Por cierto, Semantic Link tiene la función refresh_dataset para actualizar un modelo semántico, pero le sucede lo mismo que a la actividad de la canalización de datos, que no funciona con modelos semánticos en áreas de trabajo con licencia Pro.

Pero gracias a una charla de Rafael Báguena conocimos que Semantic Link cuenta con la clase PowerBIRestClient, con la que la actualización de un modelo semántico en un área de trabajo Pro se puede implementar con este código Python:

import sempy.fabric as fabric

WORKSPACE_ID = "xxxxxxxx-xxxx-xxxx-xxx-xxxxxxxxxxxx"
DATASET_ID = "xxxxxxxx-xxxx-xxxx-xxx-xxxxxxxxxxxx"
RETRY_COUNT = 3

pbi = fabric.PowerBIRestClient()
body = {
  "notifyOption": "MailOnFailure",
  "retryCount": RETRY_COUNT
}
pbi.post(f"https://api.powerbi.com/v1.0/myorg/groups/{WORKSPACE_ID}/datasets/{DATASET_ID}/refreshes", json=body)   

Con este código hemos creado, en el área de trabajo Fabric, un notebook Python, y en la canalización de datos hemos configurado una actividad para que ejecute está notebook.

En el notebook hemos colocado las variables WORKSPACE_ID, DATASET_ID y RETRY_COUNT en una celda de parámetros, para que sean configurables desde la canalización de datos, y a esta le hemos agregado una actividad para que envíe un mensaje a Teams si se detecta un error al tratar de actualizar el modelo semántico.

Canalización de datos que actualiza un modelo semántico de Power BI

Ejecución automática de la canalización de datos

El siguiente objetivo es ejecutar automáticamente la canalización de datos cuando se encienda la capacidad.

Primer intento:
Con la API REST de Fabric es posible ejecutar tareas, incluyendo las canalizaciones de datos, pero en este momento existe una dificultad, porque esta funcionalidad no admite la autenticación con una entidad de servicio, lo que impide utilizarlo para automatizar.

Esta es nuestra opción favorita, por lo que en cuanto se pueda, actualizaremos este post y la herramienta pbicmd.

Segundo intento:
Para superar esta dificultad se nos ocurrió configurar un desencadenador (trigger) en la canalización de datos, que se active al crearse un fichero en una cuenta de almacenamiento de Azure, que es el único tipo de desencadenador que se puede crear, por ahora. Pero, le vemos el inconveniente de tener que contar con una cuenta de almacenamiento de Azure, además de la capacidad Fabric.

Tercer intento:
Pero no todo está perdido, porque resulta que utilizando directamente Activator si se puede configurar un evento para detectar cuando se crea un fichero en OneLake, y configurar una alerta que ejecute la canalización de datos.

Es curioso, porque los desencadenadores de las canalizaciones de datos utilizan Activator, y OneLake utiliza una cuenta de almacenamiento de Azure, pero así son las cosas, por ahora.

Por desgracia, esto no funcionó del todo bien en las prueba que hicimos, por ejemplo, con una capacidad F2 algunas veces no se ejecutaba la alerta por falta de recursos.

Cuarto intento (final, por ahora):
Ya casi sin nuevas ideas, lo que se nos ha ocurrido es lo siguiente:

  • Al inicio de la canalización de datos, revisar una carpeta del Lakehouse para comprobar si existe un fichero que se haya modificado en los últimos 5 minutos. A este fichero le llamamos fichero de control.
  • Si NO existe el fichero de control, no hacer nada más.
  • Si EXISTE el fichero de control, borrarlo y continuar con la ETL. La eliminación del fichero se hace con un notebook de Python.
  • Programar la canalización de datos para que se ejecute cada 3 minutos

Nueva versión de la canalización de datos para hacer la ETL donde primero se comprueba si existe un fichero nuevo.

Entonces, nuestro gran plan rocambolesco para automatizar la ejecución de la canalización de datos consiste en lo siguiente:

  • En un Lakehouse del área de trabajo con capacidad Fabric crear una carpeta para guardar el fichero de control.
  • Luego de encender la capacidad Fabric, crear un fichero de control en el Lakehouse.
  • Cuando transcurra un máximo de 3 minutos se ejecutará la canalización de datos y encontrará el nuevo fichero de control por lo que continuará con la ETL.
  • Si la ETL dura más de 3 minutos, la canalización de datos volverá a ejecutarse, pero no encontrará el fichero de control, por lo que no seguirá con la ETL.

Tanto el encendido de la capacidad Fabric como la creación del fichero de control se harán desde un servidor «on premise» con la herramienta pbicmd.

Creación del fichero desde el cliente

Para crear el fichero de control en el Lakehouse podemos utilizar la API REST de Azure Data Lake Storage Gen2, teniendo en cuenta que el nombre de la cuenta de almacenamiento siempre es onelake.dfs.fabric.microsoft.com y que el nombre del contenedor es el nombre (si no tiene espacios) o el ID del área de trabajo.

Para crear un fichero vacío hay que hacer una solicitud HTTP PUT con este URL:

https://onelake.dfs.fabric.microsoft.com/[workspace_id]/[lakehouse_id]/Files/[control_directory]/[file_name]?resource=file
La última parte del URL, ?resource=file, es muy importante para que funcione.

[control_directory] tiene que coincidir con la ruta a la carpeta de control que se creó en el Lakehouse.
[file_name] es el nombre que tendrá el fichero de control.

Monitorización de la actualización del modelo semántico

Ye hemos logrado echar a andar la canalización de datos desde el cliente, y ahora necesitamos saber cuando ha terminado la ETL para apagar la capacidad.

Lo que se nos ocurrió fue utilizar la API REST de Power BI para obtener la historia de actualizaciones de un modelo semántico y poder detectar si ha habido una nueva actualización del modelo semántico en el área de trabajo con licencia Pro, luego de que se inició la canalización de datos.

Por tanto, la aplicación se mantiene en un bucle donde cada varios minutos obtiene los detalles de la última actualización hasta que sucede una de dos cosas: se detecta que se ha actualizado el modelo semántico, o se llega a un límite de intentos.
En cualquiera de los dos casos, el próximo paso es apagar la capacidad, luego de esperar un par de minutos.

Comando fabricetl de pbicmd

Lo que hemos descrito en este post lo hemos implementado en el nuevo comando fabricetl de nuestra herramienta de línea de comando pbicmd.

Para resumir, el comando hace lo siguiente:

  • Enciende una capacidad Fabric
  • Crea un fichero de control en un Lakehouse
  • Se queda esperando a que un modelo semántico se actualice
  • Apaga la capacidad

Es necesario pasarle varios parámetros para indicarle la capacidad Fabric, las áreas de trabajo, el Lakehouse, el modelo semántico, la ruta de la carpeta de control y el nombre del fichero de control.
Todos estos parámetros se explican en la documentación de pbicmd.

Permisos de la entidad de servicio

Para finalizar, quiero comentar sobre la autenticación, ya que se están utilizando APIs de Azure, Fabric y Power BI que requieren autenticación. Además, para que la herramienta pbicmd se pueda ejecutar de manera automática, es necesario autenticarse con una entidad de servicio, la cual se configura en Azure, como explicamos en un blog anterior.

En este caso, hay que otorgar permisos adicionales a la entidad de servicio::

  • En el portal de Azure, accede a la capacidad Fabric y, en la opción de Control de Acceso (IAM), agrega la entidad de servicio con el rol de Colaborador. Esto es necesario para poder encender y apagar la capacidad.
  • En las dos áreas de trabajo, tanto en la que tiene capacidad Fabric como en la que tiene licencia Pro, se debe conceder acceso a la entidad de servicio con el rol de Colaborador.