Crea un lakehouse de Iceberg gobernado con BigLake y Dataplex

1. Introducción

En una nube de datos empresarial moderna, en la que los datos residen en varios sistemas de almacenamiento físico, existe un enorme desafío arquitectónico de seguridad fragmentada.

¿Cómo te aseguras de que los datos sensibles (como los importes de las transacciones financieras) estén protegidos de manera coherente cuando se almacenan físicamente en formatos de código abierto, como Parquet, en el almacenamiento de Google Cloud y se consultan con varios motores diferentes, como BigQuery SQL o Apache Spark?

En este codelab, compilarás una arquitectura de lakehouse de datos administrado que resuelve estos problemas con tablas de Apache Iceberg, BigQuery y Dataplex Universal Catalog. Usarás la infraestructura como código (IaC) para definir políticas de seguridad de confianza cero y cómo se aplican de forma dinámica en diferentes motores de procesamiento.

Requisitos previos

  • Un proyecto de Google Cloud con facturación habilitada.
  • Conocimientos básicos de los conceptos de SQL, IAM y Cloud Storage

Qué aprenderás

Descripción general de la arquitectura: Gobernanza universal en Iceberg

6f05a096ec94f996.png

Para lograr un control de acceso detallado (como la seguridad a nivel de columna y el enmascaramiento de datos) en los formatos de datos de código abierto, debes establecer una arquitectura de seguridad estricta y unificada.

Como se ilustra en el diagrama, este patrón de lakehouse gobernado se basa en dos pilares principales para resolver el desafío de la seguridad fragmentada:

🛡️ Las capas de arquitectura seguras (izquierda)

En lugar de permitir que los usuarios o los motores externos accedan directamente a Cloud Storage, que solo admite una seguridad amplia a nivel del bucket, puedes crear una base segura.

  • Formato abierto y metadatos administrados: Los datos permanecen físicamente en Cloud Storage con el formato abierto Apache Iceberg (Parquet), mientras que BigLake administra sin problemas los metadatos de control.
  • Límite de seguridad lógica: Desvinculas el acceso al almacenamiento físico del acceso lógico a los datos con una conexión segura de recursos de Cloud. A los usuarios finales nunca se les otorga acceso físico directo a IAM a los archivos sin procesar de GCS.
  • Delegación de procesamiento de confianza cero: Para garantizar que ningún motor de ejecución pueda omitir las reglas de administración, todas las solicitudes de lectura de datos se enrutan estrictamente a través de la API de BigQuery Storage. Esto se aplica tanto si la consulta se origina en el SQL nativo de BigQuery como en Apache Spark de código abierto.

🎯 Aplicación de políticas centralizada (correcta)

Con la base segura establecida, Dataplex actúa como el cerebro unificado para la administración:

  • Definir una vez, aplicar en todas partes: Defines tus etiquetas de política en Dataplex solo una vez, y la arquitectura aplica reglas de enmascaramiento coherentes de forma universal en todos los tiempos de ejecución admitidos.
  • Enmascaramiento de datos dinámico: Cuando se consultan los datos, el sistema evalúa la identidad del usuario sobre la marcha. Si bien los usuarios autorizados verán los valores sin máscara sin procesar (p.ej., 100.0) tanto en SQL como en Spark, los usuarios restringidos recibirán automáticamente valores NULL con máscara para las columnas restringidas en ambos motores.
  • Linaje de datos automatizado: A medida que los datos fluyen y se transforman, Dataplex captura automáticamente los metadatos de transformación, lo que proporciona auditabilidad y trazabilidad integradas de extremo a extremo sin necesidad de código de registro personalizado.

2. Configuración y requisitos

Inicia Cloud Shell

Si bien Google Cloud y Spanner se pueden operar de manera remota desde tu laptop, en este codelab usarás Google Cloud Shell, un entorno de línea de comandos que se ejecuta en la nube.

En Google Cloud Console, haz clic en el ícono de Cloud Shell en la barra de herramientas en la parte superior derecha:

Activar Cloud Shell

El aprovisionamiento y la conexión al entorno deberían tomar solo unos minutos. Cuando termine el proceso, debería ver algo como lo siguiente:

Captura de pantalla de la terminal de Google Cloud Shell que muestra que el entorno se conectó

Esta máquina virtual está cargada con todas las herramientas de desarrollo que necesitarás. Ofrece un directorio principal persistente de 5 GB y se ejecuta en Google Cloud, lo que permite mejorar considerablemente el rendimiento de la red y la autenticación. Todo tu trabajo en este codelab se puede hacer en un navegador. No es necesario que instales nada.

Inicializa el entorno

Abre Cloud Shell y configura las variables de tu proyecto para asegurarte de que todos los comandos se dirijan a la infraestructura correcta.

export PROJECT_ID=$(gcloud config get-value project)
export REGION="us-central1"
export ICEBERG_BUCKET="iceberg-retail-demo-${PROJECT_ID}"
export DATASET_ID="lakehouse_retail_demo"
export CONN_NAME="iceberg-bq-conn-demo"

Luego, definiremos nuestros dos arquetipos.

export USER_ANALYST="retail-analyst-demo"
export EMAIL_ANALYST="${USER_ANALYST}@${PROJECT_ID}.iam.gserviceaccount.com"

export USER_MANAGER="retail-manager-demo"
export EMAIL_MANAGER="${USER_MANAGER}@${PROJECT_ID}.iam.gserviceaccount.com"
export CURRENT_USER=$(gcloud config get-value account)

Habilita las APIs

Habilita los servicios de Google Cloud necesarios.

gcloud services enable \
  bigquery.googleapis.com \
  bigqueryconnection.googleapis.com \
  datacatalog.googleapis.com \
  bigquerydatapolicy.googleapis.com \
  datalineage.googleapis.com \
  dataplex.googleapis.com \
  dataproc.googleapis.com \
  storage-component.googleapis.com

Descarga el código fuente del codelab

Para evitar saturar Cloud Shell, realizarás un sparse checkout para descargar solo las secuencias de comandos de Python necesarias para este codelab desde el repositorio de Google Cloud DevRel.

# Shallow clone without full history
git clone --depth 1 --filter=blob:none --sparse https://github.com/GoogleCloudPlatform/devrel-demos.git
cd devrel-demos

# Download only the specific folder
git sparse-checkout set data-analytics/governed-lakehouse
cd data-analytics/governed-lakehouse

Crear almacenamiento

Crea el bucket para almacenar los datos de Iceberg gobernados y altamente seguros.

gcloud storage buckets create gs://${ICEBERG_BUCKET} --location=${REGION}

Prepara la identidad y la seguridad

Configura la conexión de recursos de Cloud. Esta es la única entidad que posee las llaves físicas permanentes de IAM para leer los archivos Iceberg sin procesar.

# Create the BigQuery connection
bq mk --connection \
    --connection_type=CLOUD_RESOURCE \
    --location=${REGION} \
    ${CONN_NAME}

# Retrieve the connection's automatically generated Service Account
export BQ_CONN_SVC_ACCT=$(bq show --format=json --connection ${REGION}.${CONN_NAME} \
    | jq -r '.cloudResource.serviceAccountId')

# Grant Storage Object Admin to the connection for the Iceberg bucket
gcloud storage buckets add-iam-policy-binding gs://${ICEBERG_BUCKET} \
    --member="serviceAccount:${BQ_CONN_SVC_ACCT}" \
    --role="roles/storage.objectAdmin" \
    --quiet

A continuación, configura los arquetipos de usuario. A los usuarios se les otorga acceso lógico, no acceso al almacenamiento físico. Para evitar errores causados por retrasos en la propagación de IAM, primero crearás las cuentas, esperarás unos segundos y, luego, les asignarás sus roles.

echo "Creating Service Accounts..."
for USER in "${USER_ANALYST}" "${USER_MANAGER}"; do
    gcloud iam service-accounts create ${USER} --display-name="Lakehouse ${USER}"
done

echo "⏳ Waiting 15 seconds for IAM propagation..."
sleep 15

echo "Granting IAM Roles to Service Accounts..."
for USER in "${USER_ANALYST}" "${USER_MANAGER}"; do
    EMAIL="${USER}@${PROJECT_ID}.iam.gserviceaccount.com"
    
    # Allow Cloud Shell to impersonate them for testing
    gcloud iam service-accounts add-iam-policy-binding ${EMAIL} \
        --member="user:${CURRENT_USER}" \
        --role="roles/iam.serviceAccountTokenCreator" \
        --quiet

    # Allow logical viewing of the catalog, querying, and running Dataproc jobs
    for ROLE in "roles/datacatalog.viewer" "roles/bigquery.dataViewer" "roles/bigquery.user" "roles/bigquery.connectionUser" "roles/serviceusage.serviceUsageConsumer" "roles/dataproc.worker"; do
        gcloud projects add-iam-policy-binding ${PROJECT_ID} \
            --member="serviceAccount:${EMAIL}" \
            --role="${ROLE}" \
            --quiet
    done
done

# Grant the Manager data creation rights
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
    --member="serviceAccount:${EMAIL_MANAGER}" \
    --role="roles/bigquery.dataEditor" \
    --quiet

echo "✅ Identity and Security setup completed!"

3. Crea tablas nativas de Iceberg a través de BigLake

Usarás las capacidades nativas de BigLake para crear las tablas administradas de Iceberg.

Crea el conjunto de datos de BigQuery

Primero, crea un conjunto de datos de BigQuery para agrupar lógicamente nuestras tablas de Iceberg.

echo "Creating BigQuery Dataset..."
bq mk --location=${REGION} --dataset ${PROJECT_ID}:${DATASET_ID}

Crea las tablas de Iceberg

A continuación, ejecuta los siguientes comandos para crear las tablas. Observa el bloque OPTIONS en el que especificamos table_format = 'ICEBERG' y lo asignamos directamente a nuestro bucket y conexión de Cloud Storage.

echo "Creating Iceberg tables..."

# Inventory table
bq query --use_legacy_sql=false \
"CREATE OR REPLACE TABLE \`${PROJECT_ID}.${DATASET_ID}.inventory\` (
    product_id INT64, 
    product_name STRING, 
    stock_count INT64
) 
WITH CONNECTION \`${REGION}.${CONN_NAME}\` 
OPTIONS (
    file_format = 'PARQUET',
    table_format = 'ICEBERG',
    storage_uri = 'gs://${ICEBERG_BUCKET}/inventory/'
);"

# Transactions table
bq query --use_legacy_sql=false \
"CREATE OR REPLACE TABLE \`${PROJECT_ID}.${DATASET_ID}.transactions\` (
    id INT64, 
    item STRING, 
    amount FLOAT64, 
    transaction_date DATE
) 
WITH CONNECTION \`${REGION}.${CONN_NAME}\` 
OPTIONS (
    file_format = 'PARQUET',
    table_format = 'ICEBERG',
    storage_uri = 'gs://${ICEBERG_BUCKET}/transactions/'
);"

Cómo completar las tablas con datos

Por último, inserta datos de muestra en las tablas de Iceberg recién creadas.

echo "Inserting data into Iceberg tables..."

# Insert into Inventory table
bq query --use_legacy_sql=false \
"INSERT INTO \`${PROJECT_ID}.${DATASET_ID}.inventory\` (product_id, product_name, stock_count)
VALUES (101, 'Widget A', 500), (102, 'Widget B', 250), (103, 'Widget C', 800);"

# Insert into Transactions table
bq query --use_legacy_sql=false \
"INSERT INTO \`${PROJECT_ID}.${DATASET_ID}.transactions\` (id, item, amount, transaction_date)
VALUES 
    (1, 'Widget A', 100.0, DATE '2024-01-01'), 
    (2, 'Widget B', 150.0, DATE '2024-01-02'), 
    (3, 'Widget C', 50.0, DATE '2024-01-03');"

Ahora tienes dos tablas Iceberg completamente funcionales. BigLake administra los metadatos, pero los archivos Parquet físicos residen de forma segura en tu bucket de GCS.

Simula una canalización de ETL

En una situación real, los datos sin procesar suelen agregarse en tablas de resumen para los informes comerciales. Actuemos como ingenieros de datos y creemos una tabla de resumen de ventas diarias a partir de nuestros datos de transacciones sin procesar.

(Nota: Ejecuta este paso ahora para que Google Cloud tenga tiempo suficiente para procesar los metadatos en segundo plano. Descubrirás por qué esto es importante más adelante en el codelab.

echo "Creating transactions summary table..."
bq query --use_legacy_sql=false \
"CREATE TABLE \`${PROJECT_ID}.${DATASET_ID}.transactions_summary\` AS 
 SELECT transaction_date, SUM(amount) as total_sales, COUNT(id) as transaction_count 
 FROM \`${PROJECT_ID}.${DATASET_ID}.transactions\` 
 GROUP BY transaction_date;"

4. Gobernanza centralizada: Define políticas con Python

En un entorno de producción, configurar políticas de administración a través de la IU es difícil de escalar y mantener. En su lugar, se recomienda usar la infraestructura como código (IaC).

En esta sección, usarás el SDK de Python de Google Cloud para crear y aplicar de forma programática tus reglas de administración de confianza cero paso a paso.

Configura el entorno de Python

Primero, configuremos un entorno aislado de Python (venv) para evitar conflictos de bibliotecas y, luego, instalemos los SDK de Google Cloud requeridos.

Ejecute los siguientes comandos en Cloud Shell:

# Create and activate a virtual environment
python3 -m venv lakehouse_env
source lakehouse_env/bin/activate

# Install required Dataplex and BigQuery governance libraries
pip install google-cloud-datacatalog google-cloud-bigquery-datapolicies google-cloud-bigquery --quiet

echo "✅ Python environment is ready!"

Crea la taxonomía y la etiqueta de política

Una taxonomía es un contenedor lógico, y una etiqueta de política es la etiqueta específica que adjuntarás a nuestra columna sensible. Para aplicar la seguridad a nivel de columnas, primero necesitas un contenedor lógico (una taxonomía) y una etiqueta específica (una etiqueta de política).

Si observas el interior de 1_create_taxonomy.py, verás la siguiente lógica principal:

# Create Taxonomy with Fine-Grained Access Control enabled
taxonomy = datacatalog_v1.Taxonomy(
    display_name="BusinessCritical",
    activated_policy_types=[datacatalog_v1.Taxonomy.PolicyType.FINE_GRAINED_ACCESS_CONTROL]
)
created_taxonomy = client.create_taxonomy(parent=parent, taxonomy=taxonomy)

# Create Policy Tag inside the Taxonomy
policy_tag = datacatalog_v1.PolicyTag(display_name="RestrictedFinancial")
created_policy_tag = client.create_policy_tag(parent=created_taxonomy.name, policy_tag=policy_tag)

Si configuras de forma explícita el tipo de política FINE_GRAINED_ACCESS_CONTROL, transformas una etiqueta de metadatos estándar en un límite de seguridad estricto de confianza cero. De forma predeterminada, cualquier columna con esta etiqueta denegará el acceso a todos los usuarios.

Ejecuta la secuencia de comandos para crear los recursos:

python 1_create_taxonomy.py

Configura la regla de enmascaramiento (política de datos)

Ahora, define lo que sucede cuando alguien sin privilegios consulta la columna etiquetada. Crearás una política de datos que fuerce el valor a devolverse como NULL y adjuntarás esta regla al arquetipo de analista.

Dentro de 2_create_masking.py, la secuencia de comandos busca de forma dinámica el ID de la etiqueta de política que acabas de crear y aplica una política de datos:

# Define a Masking Policy that always returns NULL
data_policy = bigquery_datapolicies_v1.DataPolicy(
    data_policy_id="mask_financial_null",
    policy_tag=policy_tag_id,
    data_policy_type=bigquery_datapolicies_v1.DataPolicy.DataPolicyType.DATA_MASKING_POLICY,
    data_masking_policy=bigquery_datapolicies_v1.DataMaskingPolicy(
        predefined_expression=bigquery_datapolicies_v1.DataMaskingPolicy.PredefinedExpression.ALWAYS_NULL
    )
)

# ... (Policy creation code) ...

# Bind the Masked Reader role to the Analyst
iam_policy.bindings.add(
    role="roles/bigquerydatapolicy.maskedReader", 
    members=[f"serviceAccount:{analyst_email}"]
)

Este código crea de forma programática una regla que obliga a los valores subyacentes a mostrarse como NULL. Luego, asigna el rol de IAM maskedReader específicamente al arquetipo de analista, lo que garantiza que solo vea la versión enmascarada de los datos.

Ejecuta la secuencia de comandos para configurar la regla de enmascaramiento:

python 2_create_masking.py

Otorga acceso detallado

Debido a nuestra configuración de confianza cero, nadie puede leer la columna etiquetada en este momento. Debes otorgar acceso explícitamente al administrador y a tu cuenta personal.

Dentro de 3_grant_access.py, modifica la política de IAM de la etiqueta de política:

# Grant original data read access
iam_policy.bindings.add(
    role="roles/datacatalog.categoryFineGrainedReader",
    members=[f"serviceAccount:{manager_email}", f"user:{current_user}"]
)
client.set_iam_policy(request=iam_policy_pb2.SetIamPolicyRequest(resource=policy_tag_id, policy=iam_policy))

Agregar el rol de categoryFineGrainedReader permite que estos principales específicos omitan las reglas de enmascaramiento y lean los datos sin procesar y sin enmascarar.

Ejecuta la secuencia de comandos para otorgar acceso:

python 3_grant_access.py

Adjunta la etiqueta de política a la tabla de BigQuery

Por último, debes adjuntar esta etiqueta de política lógica a nuestro esquema de tabla física de Iceberg.

Echa un vistazo a 4_attach_tag.py. La secuencia de comandos recupera el esquema de la tabla de BigQuery, itera por los campos y adjunta la etiqueta específicamente a la columna amount:

new_schema =[]
for field in table.schema:
    if field.name == 'amount':
        # Wrap the Policy Tag ID and attach it to the column
        policy_tags_list = bigquery.PolicyTagList(names=[policy_tag_id])
        new_field = bigquery.SchemaField(
            name=field.name, field_type=field.field_type, mode=field.mode,
            description=field.description, policy_tags=policy_tags_list
        )
        new_schema.append(new_field)
    else:
        new_schema.append(field)

# Update the table schema in BigQuery
table.schema = new_schema
client.update_table(table, ["schema"])

Cuando se aplica esta actualización del esquema, BigLake vincula de inmediato nuestras etiquetas lógicas de Dataplex a los archivos Parquet físicos almacenados en tu bucket de Cloud Storage.

Ejecuta la secuencia de comandos para actualizar el esquema de la tabla:

python 4_attach_tag.py

5. Verifica las políticas de Dataplex

Es hora de probar si nuestra administración centralizada funciona. Probarás esto en dos motores diferentes para demostrar que las políticas de Dataplex se aplican de forma universal.

Verifica con el SQL nativo de BigQuery

Primero, usarás Cloud Shell para asumir la identidad de nuestros dos arquetipos y consultar la tabla con el motor de SQL nativo de BigQuery.

Prueba como administrador (usuario con privilegios):

# Impersonate the manager
gcloud config set auth/impersonate_service_account ${EMAIL_MANAGER}

# Query the transactions table
bq query --use_legacy_sql=false "SELECT * FROM \`${PROJECT_ID}.${DATASET_ID}.transactions\`"

Dado que el administrador tiene el rol de lector detallado, se mostrarán los valores de importe sin procesar.

+----+----------+--------+------------------+
| id |   item   | amount | transaction_date |
+----+----------+--------+------------------+
|  1 | Widget A |  100.0 |       2024-01-01 |
|  3 | Widget C |   50.0 |       2024-01-03 |
|  2 | Widget B |  150.0 |       2024-01-02 |
+----+----------+--------+------------------+

Prueba como analista (usuario restringido):

gcloud config set auth/impersonate_service_account ${EMAIL_ANALYST}

bq query --use_legacy_sql=false "SELECT * FROM \`${PROJECT_ID}.${DATASET_ID}.transactions\`"

Debido a la regla de enmascaramiento de Dataplex, la columna de importe se muestra como NULL para cada fila.

+----+----------+--------+------------------+
| id |   item   | amount | transaction_date |
+----+----------+--------+------------------+
|  1 | Widget A |   NULL |       2024-01-01 |
|  3 | Widget C |   NULL |       2024-01-03 |
|  2 | Widget B |   NULL |       2024-01-02 |
+----+----------+--------+------------------+

Cómo restablecer tu identidad

Limpia el estado de autenticación de Cloud Shell para volver a tu usuario administrador.

# Unset impersonation
gcloud config unset auth/impersonate_service_account

Verifica con Apache Spark (delegación de procesamiento)

¿Qué sucede si un científico de datos usa Apache Spark para leer esta tabla? Si Spark lee los archivos Parquet físicos de GCS directamente, se omiten por completo las reglas de enmascaramiento de Dataplex, ya que Cloud Storage solo comprende los permisos a nivel del bucket.

Para evitar esto, aplicas la delegación de procesamiento con el conector de Spark-BigQuery. Este conector actúa como un puente seguro que enruta las solicitudes de lectura de Spark a través de la API de BigQuery Storage para que las reglas de administración de Dataplex se evalúen de forma dinámica antes de que se envíen datos al clúster de Spark.

Observa la lógica principal dentro de la secuencia de comandos read_transactions.py que descargaste:

# Reading data via Compute Delegation (Dataplex policies are applied dynamically here)
df = spark.read \
    .format("bigquery") \
    .option("table", f"{project_id}.{dataset_id}.{table_name}") \
    .load()

print("\n=== 📊 Data Preview ===")
df.show(truncate=False)

Observa que no estamos apuntando Spark a la ruta de acceso gs:// de los archivos de Iceberg. Cuando se especifica .format("bigquery"), la API de BigQuery Storage intercepta la solicitud de lectura, verifica la identidad del usuario que ejecuta el trabajo de Spark, aplica las reglas de enmascaramiento de Dataplex y solo devuelve los datos autorizados al DataFrame de Spark.

Sube esta secuencia de comandos de PySpark a tu bucket de Cloud Storage para que Dataproc pueda acceder a ella:

# Upload script to GCS
gsutil cp read_transactions.py gs://${ICEBERG_BUCKET}/scripts/read_transactions.py

Ejecuta Spark como administrador:

Usarás Google Cloud Serverless for Apache Spark. Este servicio administrado te permite ejecutar cargas de trabajo de Spark directamente sin necesidad de aprovisionar, configurar ni administrar clústeres dedicados.

echo "🚀 Submitting Dataproc Serverless Job as [MANAGER]..."
gcloud dataproc batches submit pyspark gs://${ICEBERG_BUCKET}/scripts/read_transactions.py \
    --project=${PROJECT_ID} \
    --region=${REGION} \
    --service-account=${EMAIL_MANAGER} \
    --version=2.3 \
    -- ${PROJECT_ID} ${DATASET_ID} \
    --format="value(name)"

Observa los registros de salida del trabajo en la terminal. Debido a que el administrador tiene el rol de lector detallado, Spark recupera correctamente los importes sin procesar y sin enmascarar.

=== 📊 Data Preview ===
+---+--------+------+-------------------+
|id |item    |amount|transaction_date   |
+---+--------+------+-------------------+
|1  |Widget A|100.0 |2024-01-01         |
|2  |Widget B|150.0 |2024-01-02         |
|3  |Widget C|50.0  |2024-01-03         |
+---+--------+------+-------------------+

Ejecuta Spark como analista:

Ahora, envía exactamente el mismo trabajo de Spark, pero esta vez suplantando la identidad del arquetipo de analista.

echo "🚀 Submitting Dataproc Serverless Job as [ANALYST]..."
gcloud dataproc batches submit pyspark gs://${ICEBERG_BUCKET}/scripts/read_transactions.py \
    --project=${PROJECT_ID} \
    --region=${REGION} \
    --service-account=${EMAIL_ANALYST} \
    --version=2.3 \
    -- ${PROJECT_ID} ${DATASET_ID} \
    --format="value(name)"

Vuelve a verificar los registros. Aunque el analista ejecutó exactamente el mismo código de Spark, la API de BigQuery Storage interceptó la solicitud y aplicó la política de Dataplex. El DataFrame de Spark del analista muestra null para los importes.

=== 📊 Data Preview ===
+---+--------+------+-------------------+
|id |item    |amount|transaction_date   |
+---+--------+------+-------------------+
|1  |Widget A|null  |2024-01-01         |
|2  |Widget B|null  |2024-01-02         |
|3  |Widget C|null  |2024-01-03         |
+---+--------+------+-------------------+

Compensaciones de arquitectura: BigQuery SQL vs. Spark

Acabas de demostrar que el resultado es idéntico independientemente del motor. La política de Dataplex se aplicó correctamente. Pero, en producción, ¿cuál deberías usar?

  • BigQuery SQL: Es ideal para los flujos de trabajo en los que SQL es el motor deseado y ejecuta los cálculos directamente en el lugar. Es ideal para la inteligencia empresarial y el análisis rápidos.
  • Apache Spark: Permite cargas de trabajo más complejas gracias al uso de Python, lo que lo hace adecuado para canalizaciones avanzadas de aprendizaje automático o código heredado de Hadoop.

Conclusión clave: Sin importar qué motor se use, si se aplica la delegación de procesamiento, nunca se podrá omitir la capa de administración centralizada de confianza cero.

6. Linaje de datos automatizado

En cualquier arquitectura de datos empresariales, saber exactamente de dónde provienen tus datos y cómo se modificaron es fundamental para el cumplimiento, la depuración y el establecimiento de la confianza. Este concepto se conoce como linaje de datos. Responde preguntas fundamentales, como: "Si un administrador está viendo un informe de ventas diario, ¿qué tablas sin procesar se usaron para calcular esas cifras?".

Tradicionalmente, el seguimiento de este ciclo de vida requiere que los ingenieros de datos escriban manualmente código de registro personalizado o usen herramientas complejas de terceros para analizar secuencias de comandos de SQL. Sin embargo, en un lakehouse de Google Cloud gobernado, este seguimiento está integrado y es completamente automático.

¿Recuerdas la tabla transactions_summary que creaste a partir de la tabla de transacciones sin procesar en una sección anterior del codelab? Cuando BigQuery ejecutó esa instrucción CREATE TABLE AS SELECT, el motor de procesamiento capturó automáticamente los metadatos de transformación y los envió a Dataplex. Veamos el resultado.

Visualiza el linaje

  1. En la consola de Google Cloud, navega a Dataplex Universal Catalog > Search.
  2. Escribe lakehouse_retail_demo.transactions en la barra de búsqueda y haz clic en la tabla.
  3. Haz clic en la pestaña Linaje.

c890a11d6ea1cca4.png

Verás un gráfico interactivo generado por el motor de conocimiento de Dataplex que demuestra que la tabla de destino (transactions_summary) se derivó de la tabla Iceberg sin procesar gobernada (transactions). Lograste la trazabilidad de extremo a extremo esencial para la auditoría de datos.

7. Limpia

Sigue estos pasos para evitar que se apliquen cargos a tu cuenta de Google Cloud por los recursos que usaste en este codelab.

Cómo quitar recursos de administración de Dataplex

Antes de borrar el conjunto de datos de BigQuery o el bucket de Cloud Storage, debes quitar las reglas de administración lógica. Si observas el interior de la secuencia de comandos cleanup_governance.py del repositorio, verás la siguiente secuencia de desmontaje:

# 1. Delete Data Policy
data_policy_name = f"{parent_loc}/dataPolicies/mask_financial_null"
dp_client.delete_data_policy(name=data_policy_name)

# 2. Find and Delete Taxonomy (This auto-deletes child Policy Tags)
taxonomies = catalog_client.list_taxonomies(parent=parent_loc)
taxonomy_id = next((t.name for t in taxonomies if t.display_name == "BusinessCritical"), None)
catalog_client.delete_taxonomy(name=taxonomy_id)

El orden aquí es fundamental. Primero, la secuencia de comandos borra la política de datos (regla de enmascaramiento) porque depende de la etiqueta de política. Una vez que se quite la política, se borrará automáticamente la taxonomía principal y todos los rótulos identificadores de política subyacentes sin generar errores de dependencia de recursos.

Ejecuta la secuencia de comandos de limpieza de Python:

python cleanup_governance.py

Cómo quitar identidades, almacenamiento y recursos de procesamiento

Ahora que la capa de administración está separada, puedes borrar de forma segura las tablas de BigQuery, los buckets de Cloud Storage, las cuentas de servicio y el entorno local de Python.

Copia y ejecuta el siguiente bloque de limpieza integral en Cloud Shell:

echo "Deleting Service Accounts and Impersonation Bindings..."
export CURRENT_USER=$(gcloud config get-value account)

for USER in "${USER_ANALYST}" "${USER_MANAGER}"; do
    EMAIL="${USER}@${PROJECT_ID}.iam.gserviceaccount.com"
    
    # Remove impersonation binding
    gcloud iam service-accounts remove-iam-policy-binding ${EMAIL} \
        --member="user:${CURRENT_USER}" \
        --role="roles/iam.serviceAccountTokenCreator" \
        --quiet > /dev/null 2>&1
        
    # Delete the Service Account
    gcloud iam service-accounts delete ${EMAIL} --quiet
done

echo "Removing BigQuery Dataset and Tables..."
bq rm -f ${DATASET_ID}.transactions_summary
bq rm -f ${DATASET_ID}.transactions
bq rm -f ${DATASET_ID}.inventory
bq rm -f -d ${DATASET_ID}

echo "Removing BigQuery Cloud Resource Connection..."
bq rm --connection --location=${REGION} ${CONN_NAME}

echo "Removing Iceberg Cloud Storage Bucket..."
gcloud storage rm --recursive gs://${ICEBERG_BUCKET} --quiet

echo "Removing Auto-generated Dataproc Staging & Temp Buckets..."
for BUCKET in $(gcloud storage ls | grep -E "gs://dataproc-(staging|temp)-${REGION}"); do
    gcloud storage rm --recursive $BUCKET --quiet
done

echo "Deactivating and removing the local Python environment..."
deactivate
cd ../..
rm -rf devrel-demos

echo "✅ Clean up completed successfully!"

Si completaste estos pasos, te aseguraste de que no queden recursos huérfanos ni políticas ocultas en tu proyecto.

8. ¡Felicitaciones!

Implementaste correctamente un data lakehouse completamente gobernado y detectable.

Aprendiste lo siguiente:

  • Integración nativa de Iceberg: BigLake puede administrar de forma nativa las tablas de Iceberg de código abierto y, al mismo tiempo, almacenar los archivos físicos de forma segura en Cloud Storage.
  • Delegación de procesamiento para la seguridad: Al enrutar las consultas a través de la API de BigQuery Storage, aplicaste un enmascaramiento dinámico detallado en los archivos físicos que, de forma nativa, no pueden restringir el acceso parcial.
  • Administración independiente del motor: Las etiquetas de política te permiten definir reglas una vez y aplicarlas de forma universal, ya sea que se consulten a través de SQL nativo o de tiempos de ejecución de Apache Spark.
  • Detectabilidad de los datos: El motor de conocimiento de Dataplex realizó un seguimiento automático del linaje de datos, lo que proporcionó una capacidad de auditoría empresarial esencial.

¿Qué sigue?

  • Explora el control de acceso avanzado: Para implementar situaciones de seguridad más complejas, revisa la documentación oficial sobre la personalización de BigLake con funciones adicionales.
  • Administra datos no estructurados para la IA generativa: Descubre las tablas de objetos de BigLake. Extiende este patrón de puente seguro exacto a los archivos no estructurados (PDFs, imágenes) en Cloud Storage, y establece una base de datos segura y administrada para Vertex AI y las canalizaciones de RAG.