Logo GCP con Eduardo

GCP con Eduardo

Descarga el código de la lección

Pub/Sub to BigQuery: Ingesta de Streaming sin Servidores con Terraform
✦ Guía Técnica & Arquitectura

Pub/Sub to BigQuery: Ingesta de Streaming sin Servidores con Terraform

Cómo diseñar una arquitectura de streaming en Google Cloud que conecte Pub/Sub directamente con BigQuery, eliminando un pipeline de procesamiento cuando no aporta valor y manteniendo control sobre IAM, esquemas, errores, observabilidad y FinOps.

Lo que aprenderás

El objetivo no es simplemente crear una suscripción, sino saber cuándo esta arquitectura es correcta y cuándo introduce un límite técnico que justifica Dataflow u otro componente de procesamiento.

Ingesta directa

Conecta Pub/Sub con una tabla BigQuery sin desplegar un consumidor.

IAM correcto

Diseña permisos para el servicio de Pub/Sub siguiendo mínimo privilegio.

Schema & metadata

Controla contratos de datos, columnas y metadatos de los eventos.

Producción

Incorpora DLQ, Terraform, observabilidad y decisiones de FinOps.

Stack tecnológico

Una arquitectura mínima, declarativa y orientada a servicios gestionados.

Google Cloud Pub/Sub BigQuery BigQuery Subscription Terraform Cloud IAM Dead Letter Topic Streaming Analytics ELT

La decisión arquitectónica: ¿BigQuery Subscription o Dataflow?

La pregunta correcta no es "¿qué servicio es más potente?", sino "¿necesito procesamiento entre el evento y el almacenamiento analítico?".

Patrón Latencia Procesamiento Complejidad operativa Coste / FinOps Uso recomendado
Pub/Sub → BigQuery Subscription Streaming Mínimo Baja Menor superficie operativa Ingesta directa y ELT posterior
Pub/Sub → Dataflow → BigQuery Streaming Alto Media / Alta Mayor infraestructura gestionada Transformaciones, enriquecimiento y lógica compleja
Pub/Sub → Cloud Run → BigQuery Streaming Personalizable Media Depende del patrón de ejecución Integraciones y lógica específica
Pub/Sub → Storage → BigQuery Batch / micro-batch Posterior Media Optimizable por volumen Archivado, replay y cargas desacopladas
Una BigQuery Subscription es un tipo de suscripción de exportación que escribe los mensajes en una tabla BigQuery existente a medida que se reciben, evitando la necesidad de un cliente suscriptor independiente.
⚠ Antipatrón: añadir Dataflow por reflejo

Un error frecuente en arquitecturas de streaming es introducir Pub/Sub → Dataflow → BigQuery aunque el único requisito sea persistir el evento en BigQuery.

Esto añade un componente operativo, configuración, observabilidad, capacidad de ejecución y una superficie adicional de costes sin aportar necesariamente valor funcional.

Si no necesitas transformación antes de la persistencia, una BigQuery Subscription puede ser el camino más simple. Si necesitas joins, enriquecimiento, transformaciones complejas o procesamiento avanzado, entonces Dataflow vuelve a estar justificado.

La decisión arquitectónica debe basarse en la transformación requerida, no en la potencia del servicio.

Implementación de producción con Terraform

El siguiente ejemplo crea un topic, una tabla analítica, una suscripción BigQuery, metadata de eventos y un Dead Letter Topic.

terraform {
  required_version = ">= 1.6.0"

  required_providers {
    google = {
      source  = "hashicorp/google"
      version = ">= 7.45.0"
    }
  }
}

variable "project_id" {
  type        = string
  description = "Google Cloud project ID"
}

variable "region" {
  type        = string
  default     = "europe-southwest1"
}

provider "google" {
  project = var.project_id
  region  = var.region
}

resource "google_project_service" "pubsub" {
  service            = "pubsub.googleapis.com"
  disable_on_destroy = false
}

resource "google_project_service" "bigquery" {
  service            = "bigquery.googleapis.com"
  disable_on_destroy = false
}

resource "google_pubsub_topic" "events" {
  name = "analytics-events"

  depends_on = [
    google_project_service.pubsub
  ]
}

resource "google_pubsub_topic" "dead_letter" {
  name = "analytics-events-dlq"

  depends_on = [
    google_project_service.pubsub
  ]
}

resource "google_bigquery_dataset" "analytics" {
  dataset_id = "streaming_analytics"
  location   = "EU"

  depends_on = [
    google_project_service.bigquery
  ]
}

resource "google_bigquery_table" "events" {
  dataset_id = google_bigquery_dataset.analytics.dataset_id
  table_id   = "events"

  deletion_protection = true

  schema = jsonencode([
    {
      name = "event_id"
      type = "STRING"
      mode = "REQUIRED"
    },
    {
      name = "event_type"
      type = "STRING"
      mode = "NULLABLE"
    },
    {
      name = "customer_id"
      type = "STRING"
      mode = "NULLABLE"
    },
    {
      name = "event_ts"
      type = "TIMESTAMP"
      mode = "NULLABLE"
    },
    {
      name = "payload"
      type = "JSON"
      mode = "NULLABLE"
    }
  ])
}

data "google_project" "current" {}

resource "google_project_iam_member" "pubsub_bigquery_writer" {
  project = var.project_id
  role    = "roles/bigquery.dataEditor"

  member = format(
    "serviceAccount:service-%s@gcp-sa-pubsub.iam.gserviceaccount.com",
    data.google_project.current.number
  )
}

resource "google_pubsub_subscription" "bigquery" {
  name  = "analytics-events-to-bigquery"
  topic = google_pubsub_topic.events.id

  bigquery_config {
    table         = "${var.project_id}.${google_bigquery_dataset.analytics.dataset_id}.${google_bigquery_table.events.table_id}"
    write_metadata = true
    use_table_schema = true
  }

  dead_letter_policy {
    dead_letter_topic     = google_pubsub_topic.dead_letter.id
    max_delivery_attempts = 10
  }

  depends_on = [
    google_project_iam_member.pubsub_bigquery_writer
  ]
}

El bloque bigquery_config es la pieza clave: convierte la suscripción en una ruta de entrega directa hacia BigQuery. Terraform expone opciones como use_table_schema, use_topic_schema, write_metadata, drop_unknown_fields y una cuenta de servicio específica.

El detalle que rompe despliegues: IAM

La arquitectura puede ser correcta y aun así fallar porque Pub/Sub no tiene autorización para escribir en BigQuery.

Default Service Agent

Pub/Sub utiliza normalmente su Service Agent: service-<PROJECT_NUMBER>@gcp-sa-pubsub.iam.gserviceaccount.com.

Ese principal necesita permisos adecuados sobre BigQuery, habitualmente mediante roles/bigquery.dataEditor.

Cuenta gestionada por el equipo

Para un modelo de permisos más granular puede utilizarse una cuenta de servicio gestionada por el usuario.

Esto permite separar mejor quién puede crear la suscripción de quién posee permisos efectivos de escritura sobre la tabla.

Schema design: el contrato es parte de la arquitectura

"Streaming directo" no significa "schema libre". La compatibilidad entre el mensaje y la tabla es una de las principales condiciones para que la ruta sea fiable.

Use Table Schema

Permite utilizar el esquema de BigQuery como referencia de las columnas. Los mensajes deben estar publicados en formato JSON compatible con dicho esquema.

  • Útil cuando BigQuery es el sistema de contrato.
  • Facilita controlar explícitamente las columnas.
  • Requiere disciplina de evolución de schema.

Use Topic Schema

Pub/Sub puede utilizar el schema asociado al topic y mapear los campos del mensaje con las columnas BigQuery compatibles.

  • Centraliza el contrato cerca del productor.
  • Favorece gobernanza de eventos.
  • Exige compatibilidad de nombres y tipos.
⚠ No confundas Drop Unknown Fields con evolución segura

drop_unknown_fields puede evitar que determinados campos adicionales impidan una escritura cuando se utiliza schema de topic o tabla, pero no debe utilizarse como sustituto de una estrategia formal de evolución de contratos.

En un sistema empresarial, la compatibilidad debe validarse antes de publicar cambios. El objetivo es evitar que un productor despliegue una versión que convierta el backlog de Pub/Sub en una cola de errores.

Patrones de diseño para producción

01. Event Contract First

Define primero el contrato del evento: identificador, timestamp, tipo, entidad, payload y atributos. Después diseña la tabla.

02. Raw → Curated

Mantén la ingesta lo más cercana posible al evento original y realiza transformaciones analíticas posteriormente cuando no sean necesarias durante el transporte.

03. Dead Letter by Default

Los errores de escritura no deberían convertirse en mensajes perdidos ni en reintentos infinitos. Configura una DLQ y monitoriza su crecimiento.

04. Terraform as Control Plane

Topics, subscriptions, datasets, tablas, IAM y políticas deben formar parte de infraestructura declarativa versionada.

05. Least Privilege

Evita permisos excesivos a nivel de proyecto cuando una autorización más granular sobre dataset o tabla sea suficiente.

06. Dataflow cuando existe lógica

Cuando el pipeline necesita joins, enriquecimiento, transformación compleja o procesamiento avanzado, no fuerces una BigQuery Subscription más allá de su propósito.

Framework de implementación empresarial

Una secuencia práctica para pasar de un topic de eventos a una ruta de streaming gobernada.

Define el caso de uso

Determina si necesitas únicamente persistencia analítica o si existe procesamiento obligatorio antes de escribir.

Diseña el contrato

Define schema, tipos, campos obligatorios, estrategia de compatibilidad y evolución.

Crea la tabla BigQuery

Diseña tipos, particionado, clustering y retención en función de los patrones reales de consulta.

Configura IAM

Autoriza al principal que realizará la escritura y evita conceder permisos globales innecesarios.

Implementa la BigQuery Subscription

Configura destino, schema, metadata, política de dead lettering y propiedades de entrega.

Observa el sistema

Monitoriza backlog, errores, throughput, latencia, DLQ y costes. Un pipeline sin observabilidad no está terminado.

Prueba evolución y fallo

Simula schema incompatible, pérdida de permisos, mensajes inválidos y recuperación desde DLQ antes de producción.

Checklist de arquitectura

  • ¿La transformación antes de BigQuery es realmente necesaria?
  • ¿Existe un contrato de evento explícito?
  • ¿La tabla BigQuery tiene un schema compatible?
  • ¿El Pub/Sub Service Agent tiene permisos mínimos suficientes?
  • ¿Está configurado un Dead Letter Topic?
  • ¿Se ha decidido conscientemente si escribir metadata?
  • ¿Terraform controla la infraestructura?
  • ¿Existe observabilidad sobre backlog y errores?
  • ¿Se ha probado la evolución del schema?
  • ¿Existe una estrategia para replay y recuperación?
  • ¿La arquitectura evita componentes que no aportan valor?
  • ¿El coste esperado ha sido evaluado a escala de producción?

Preguntas frecuentes

¿Se puede conectar Pub/Sub con BigQuery sin Dataflow?

Sí. Una BigQuery Subscription permite que Pub/Sub escriba directamente los mensajes recibidos en una tabla de BigQuery sin desplegar un consumidor independiente. Es especialmente adecuada cuando el objetivo es ingerir datos sin transformación compleja.

¿Cuándo debería usar Dataflow en lugar de una BigQuery Subscription?

Cuando el evento necesita procesamiento antes de llegar al modelo analítico: transformaciones complejas, enriquecimiento, joins, ventanas, lógica de negocio, normalización avanzada o pipelines que requieran capacidades propias de un motor de procesamiento.

¿Cómo configuro Pub/Sub to BigQuery con Terraform?

Utiliza google_pubsub_subscription y configura su bloque bigquery_config. Debes especificar la tabla destino y, dependiendo del diseño, opciones como use_table_schema, use_topic_schema, write_metadata, una cuenta de servicio y una política de dead lettering.

Sobre el Autor: Eduardo Martínez Agrelo

AI & Data Architect

Eduardo Martínez Agrelo es AI & Data Architect, especializado en arquitectura de datos, ingeniería de plataformas, cloud, inteligencia artificial y diseño de sistemas empresariales. Su enfoque combina profundidad técnica con decisiones arquitectónicas orientadas a escalabilidad, gobierno, rendimiento y eficiencia económica.

© 2026 Eduardo Martínez Agrelo · AI & Data Architect

Guía técnica sobre Pub/Sub to BigQuery, streaming data ingestion en GCP y arquitectura cloud orientada a producción.