SaaS B2B · Analytics en tiempo real · europe-west1 · Generado por CULTIVA IA — Arquitecto Nube GCP
┌─────────────────────────────────────────────────────────────────────────────────────────┐ │ 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
# 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 } } }
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'
| 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 |
| 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 |
#!/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"
""" 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 ) )