GCP Arquitectura — LeadFlow Analytics

SaaS B2B · Analytics en tiempo real · europe-west1 · Generado por CULTIVA IA — Arquitecto Nube GCP

Serverless + Data Pipeline GDPR Compliant SLA 99.9% ~$847/mes
Coste mensual estimado
$847
De presupuesto $980/mes · 13.6% margen
Ahorro potencial
$193
Con Committed Use Discounts (1 año)
Servicios GCP
11
Cloud Run · BigQuery · Pub/Sub · más
Tiempo de despliegue
~45min
Con terraform apply desde cero
Diagrama de Arquitectura — Patrón Híbrido (Serverless + Data Pipeline)
┌─────────────────────────────────────────────────────────────────────────────────────────┐
│                          LeadFlow Analytics — GCP Architecture (europe-west1)           │
└─────────────────────────────────────────────────────────────────────────────────────────┘

  [Usuarios / Clientes B2B]
          │
          ▼
  ┌──────────────────┐
  │  Cloud CDN       │  ◄── Next.js static assets desde Cloud Storage
  │  + Load Balancer │
  └────────┬─────────┘
           │
    ┌──────┴──────┐
    ▼             ▼
┌──────────┐  ┌──────────────────────────────┐
│  Static  │  │    Cloud Run (API FastAPI)    │  ← 0-20 instancias auto-scale
│ Frontend │  │    europe-west1 · min=1       │  ← 512Mi CPU·1 · Secret Manager
│ (GCS)    │  └──────────┬───────────────────┘
└──────────┘             │
                   ┌──────┼──────────┐
                   ▼      ▼          ▼
            ┌──────────┐ ┌────────┐ ┌───────────┐
            │Cloud SQL │ │Pub/Sub │ │ Identity  │
            │PostgreSQL│ │(events)│ │ Platform  │
            │eu-west1  │ └────┬───┘ └───────────┘
            └──────────┘      │
                              ▼
                    ┌─────────────────┐
                    │    Dataflow     │  ← Apache Beam streaming
                    │  (stream proc)  │
                    └────────┬────────┘┌────────▼────────┐
                    │    BigQuery     │  ← Analytics warehouse
                    │  (analytics DW) │
                    └────────┬────────┘┌────────▼────────┐
                    │  Looker Studio  │  ← Dashboards para clientes
                    │   (dashboards)  │
                    └─────────────────┘

  CI/CD: GitHub → Cloud Build → Artifact Registry → Cloud Run deploy
  Secrets: Secret Manager · Logging: Cloud Logging + Monitoring · IaC: Terraform
Frontend / Edge
☁️
Cloud CDN
Assets Next.js servidos globalmente desde PoPs
~$12/mes
🪣
Cloud Storage
Bucket regional EU para SPA estático + assets
~$4/mes
🌐
Cloud Load Balancing
HTTPS Global LB con SSL gestionado + WAF básico
~$18/mes
API / Compute
🚀
Cloud Run
FastAPI containerizado · min=1 inst · max=20 · europe-west1
~$85/mes
🔐
Identity Platform
Auth multitenancy (B2B) · JWT · OIDC · hasta 10k MAU gratis
~$0/mes
🔑
Secret Manager
DB password, API keys, OAuth secrets versionados
~$3/mes
Datos / Storage
🐘
Cloud SQL (PostgreSQL)
db-custom-2-4096 · HA · automated backups · europa
~$125/mes
📨
Pub/Sub
Ingesta de eventos de leads en tiempo real · 10 topics
~$15/mes
📊
BigQuery
DW de analíticas · particionado por día · clustering por tenant
~$95/mes
Pipeline / DevOps
Dataflow
Apache Beam · streaming Pub/Sub → BigQuery · 2 workers
~$210/mes
🔨
Cloud Build
CI/CD desde GitHub · tests + build + deploy · 120 min/día free
~$8/mes
📦
Artifact Registry
Docker registry privado EU para imágenes Cloud Run
~$5/mes
Terraform HCL — main.tf (núcleo)
main.tf · leadflow-analytics HCL
# Provider GCP — europe-west1
provider "google" {
  project = var.project_id
  region  = "europe-west1"
}

# Cloud Run — FastAPI Backend
resource "google_cloud_run_v2_service" "api" {
  name     = "leadflow-api-prod"
  location = "europe-west1"

  template {
    containers {
      image = "europe-west1-docker.pkg.dev/${var.project_id}/leadflow/api:latest"
      resources { limits = { cpu = "1000m" memory = "512Mi" } }
      env {
        name = "DB_URL"
        value_source {
          secret_key_ref {
            secret  = google_secret_manager_secret.db_url.secret_id
            version = "latest"
          }
        }
      }
    }
    scaling {
      min_instance_count = 1
      max_instance_count = 20
    }
    service_account = google_service_account.cloudrun_sa.email
  }
}

# BigQuery Dataset — particionado por tenant
resource "google_bigquery_dataset" "analytics" {
  dataset_id = "leadflow_analytics"
  location   = "EU"
  labels     = { env = "prod" gdpr = "true" }
}

# Pub/Sub Topic — eventos de leads
resource "google_pubsub_topic" "lead_events" {
  name = "leadflow-lead-events-prod"
  message_storage_policy {
    allowed_persistence_regions = ["europe-west1"]
  }
}

# Cloud SQL — PostgreSQL HA
resource "google_sql_database_instance" "main" {
  name             = "leadflow-db-prod"
  database_version = "POSTGRES_15"
  region           = "europe-west1"
  settings {
    tier = "db-custom-2-4096"
    backup_configuration {
      enabled            = true
      binary_log_enabled = false
      start_time         = "02:00"
    }
    ip_configuration {
      ipv4_enabled    = false
      private_network = google_compute_network.vpc.id
    }
  }
}
Cloud Build — CI/CD Pipeline
🔀
GitHub Push
main branch
🧪
Tests
~2 min
🏗️
Docker Build
~4 min
📦
Push Registry
~1 min
🚀
Deploy Run
~2 min
Live
~9 min total
cloudbuild.yaml YAML
steps:
  # 1. Tests unitarios e integración
  - name: 'python:3.11-slim'
    entrypoint: bash
    args: ['-c', 'pip install -r requirements.txt && pytest tests/ -v']

  # 2. Build imagen Docker
  - name: 'gcr.io/cloud-builders/docker'
    args: ['build', '-t',
      'europe-west1-docker.pkg.dev/$PROJECT_ID/leadflow/api:$COMMIT_SHA', '.']

  # 3. Push a Artifact Registry
  - name: 'gcr.io/cloud-builders/docker'
    args: ['push',
      'europe-west1-docker.pkg.dev/$PROJECT_ID/leadflow/api:$COMMIT_SHA']

  # 4. Deploy a Cloud Run (zero-downtime)
  - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk'
    entrypoint: gcloud
    args:
      - 'run'
      - 'deploy'
      - 'leadflow-api-prod'
      - '--image=europe-west1-docker.pkg.dev/$PROJECT_ID/leadflow/api:$COMMIT_SHA'
      - '--region=europe-west1'
      - '--traffic=100'  # Canary available

options:
  logging: CLOUD_LOGGING_ONLY
  machineType: E2_HIGHCPU_8

timeout: '600s'
Entornos separados
DEV STAGING PROD
Entorno Cloud Run DB Coste
Development
min=0, max=3
db-f1-micro
~$28/mes
Staging
min=0, max=5
db-custom-1-2048
~$65/mes
Production
min=1, max=20
db-custom-2-4096 HA
~$847/mes
Desglose de Costes (Producción)
Servicio €/mes
⚡ Dataflow (streaming)
2 workers n1-standard-2 · 730h
$210
🐘 Cloud SQL PostgreSQL
db-custom-2-4096 · HA · 50GB storage
$125
📊 BigQuery
500GB storage · 5TB queries/mes
$95
🚀 Cloud Run
1 CPU · 512Mi · ~2M requests/mes
$85
🌐 Load Balancer
Global HTTPS · forwarding rules
$18
☁️ Cloud CDN
200GB egress/mes · PoPs europa
$12
📦 Otros (Pub/Sub, Build, Artifact, Secrets)
Servicios auxiliares
$31
TOTAL MENSUAL
Vs. presupuesto $980/mes
$847
Optimizaciones recomendadas
ALTA
Committed Use Discount 1 año para Dataflow workers
-$63
ALTA
CUD Cloud SQL (1 año) · reducir a db-custom-2-3072
-$45
MEDIA
BigQuery: pasar a flat-rate $400/slot-mes si queries >8TB
-$55
BAJA
Cloud Storage lifecycle: mover logs >90 días a Nearline
-$30
Ahorro total potencial -$193/mes → $654/mes
Checklist de Seguridad (GDPR)
  • IAM mínimo privilegio — Service Account dedicado por servicio
    Workload Identity para Cloud Run, roles predefinidos no básicos
  • Datos en Europa — todas las regiones forzadas a EU/europe-west1
    BigQuery dataset location=EU · Cloud SQL europe-west1 · Pub/Sub restrict
  • Credenciales en Secret Manager — cero secrets en env vars
    DB_URL, API_KEY, OAUTH_SECRET gestionados con versioning
  • VPC privada — Cloud SQL sin IP pública, Cloud Run en VPC connector
    Private Service Connect para acceso SQL desde Cloud Run
  • Cloud Audit Logs habilitados — Admin Activity + Data Access
    Retención 400 días en Cloud Logging · exportar a BigQuery
  • Cifrado CMEK con Cloud KMS para BigQuery y Cloud SQL
    Customer-managed encryption keys en keyring europe-west1
  • VPC Service Controls — recomendado para BigQuery GDPR
    Pendiente configurar: necesita org-level Access Context Manager
  • DPA (Data Processing Agreement) con Google Cloud firmado
    Obligatorio GDPR Art. 28 — gestionar en Google Cloud Console > IAM
Anti-Patrones Evitados
✗ VPC default en producción
Solucionado: VPC custom con subnets privadas
✗ Secrets en variables de entorno
Solucionado: Secret Manager + Workload Identity
✗ Cloud Run min=0 (cold starts)
Solucionado: min=1 en prod para SLA 99.9%
✗ BigQuery on-demand ilimitado
Solucionado: slot reservations cuando >8TB/mes
✗ Single-region para SaaS B2B
Solucionado: Global LB + Cloud CDN multi-PoP
✗ Cloud Functions para streaming
Solucionado: Dataflow para pipeline Pub/Sub→BQ
Scripts de Despliegue — gcloud CLI
deploy.sh — Initial Setup Bash
#!/bin/bash
# LeadFlow Analytics — GCP Initial Setup
# Ejecutar con: ./deploy.sh leadflow-prod-123456

PROJECT_ID="$1"
REGION="europe-west1"
APP_NAME="leadflow"

# Habilitar APIs necesarias
gcloud services enable \
  run.googleapis.com \
  sql-component.googleapis.com \
  sqladmin.googleapis.com \
  bigquery.googleapis.com \
  pubsub.googleapis.com \
  dataflow.googleapis.com \
  cloudbuild.googleapis.com \
  artifactregistry.googleapis.com \
  secretmanager.googleapis.com \
  identitytoolkit.googleapis.com \
  --project=$PROJECT_ID

# Crear Artifact Registry
gcloud artifacts repositories create $APP_NAME \
  --repository-format=docker \
  --location=$REGION \
  --description="LeadFlow container registry"

# Service Account para Cloud Run
gcloud iam service-accounts create $APP_NAME-cloudrun \
  --display-name="LeadFlow Cloud Run SA"

# Permisos mínimos (least privilege)
gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member="serviceAccount:${APP_NAME}-cloudrun@${PROJECT_ID}.iam.gserviceaccount.com" \
  --role="roles/cloudsql.client"

gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member="serviceAccount:${APP_NAME}-cloudrun@${PROJECT_ID}.iam.gserviceaccount.com" \
  --role="roles/bigquery.dataEditor"

gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member="serviceAccount:${APP_NAME}-cloudrun@${PROJECT_ID}.iam.gserviceaccount.com" \
  --role="roles/secretmanager.secretAccessor"

# Deploy Cloud Run API
gcloud run deploy $APP_NAME-api \
  --image=$REGION-docker.pkg.dev/$PROJECT_ID/$APP_NAME/api:latest \
  --region=$REGION \
  --platform=managed \
  --no-allow-unauthenticated \
  --memory=512Mi \
  --cpu=1 \
  --min-instances=1 \
  --max-instances=20 \
  --service-account=$APP_NAME-cloudrun@$PROJECT_ID.iam.gserviceaccount.com

echo "✅ LeadFlow desplegado en europe-west1"
dataflow_pipeline.py — Pub/Sub → BigQuery Python
"""
LeadFlow — Streaming Pipeline
Pub/Sub topic: leadflow-lead-events-prod
BigQuery table: leadflow_analytics.lead_events
"""
import apache_beam as beam
from apache_beam.options.pipeline_options import PipelineOptions
from apache_beam.io.gcp import bigquery

PROJECT = "leadflow-prod-123456"
TOPIC   = f"projects/{PROJECT}/topics/leadflow-lead-events-prod"
TABLE   = f"{PROJECT}:leadflow_analytics.lead_events"

SCHEMA = {
  'fields': [
    {'name': 'event_id',    'type': 'STRING',    'mode': 'REQUIRED'},
    {'name': 'tenant_id',   'type': 'STRING',    'mode': 'REQUIRED'},
    {'name': 'lead_id',     'type': 'STRING',    'mode': 'REQUIRED'},
    {'name': 'event_type',  'type': 'STRING',    'mode': 'REQUIRED'},
    {'name': 'score',       'type': 'FLOAT64',   'mode': 'NULLABLE'},
    {'name': 'metadata',    'type': 'JSON',      'mode': 'NULLABLE'},
    {'name': 'timestamp',   'type': 'TIMESTAMP', 'mode': 'REQUIRED'},
  ]
}

def parse_event(msg):
  import json
  data = json.loads(msg.decode('utf-8'))
  return {
    'event_id':   data['id'],
    'tenant_id':  data['tenant'],
    'lead_id':    data['lead'],
    'event_type': data['type'],
    'score':      data.get('score'),
    'metadata':   json.dumps(data.get('meta', {})),
    'timestamp':  data['ts'],
  }

opts = PipelineOptions(
  runner='DataflowRunner',
  project=PROJECT,
  region='europe-west1',
  num_workers=2,
  max_num_workers=8,
  streaming=True,
)

with beam.Pipeline(options=opts) as p:
  (p
   | 'ReadPubSub'  >> beam.io.ReadFromPubSub(topic=TOPIC)
   | 'ParseEvent'  >> beam.Map(parse_event)
   | 'WriteBQ'     >> beam.io.WriteToBigQuery(
       TABLE,
       schema=SCHEMA,
       write_disposition=bigquery.BigQueryDisposition.WRITE_APPEND,
       create_disposition=bigquery.BigQueryDisposition.CREATE_IF_NEEDED
     )
  )