Ir al contenido

Storage y Datos

La estrategia de almacenamiento y datos de HERA se basa en un conjunto de servicios de GCP altamente escalables, duraderos y seguros. Utilizamos Cloud Storage para el almacenamiento de objetos, BigQuery como nuestro data warehouse, Memorystore para caché en memoria y Pub/Sub para la mensajería asíncrona, formando un ecosistema de datos robusto y versátil.


Cloud Storage (GCS): Almacenamiento Unificado

Sección titulada «Cloud Storage (GCS): Almacenamiento Unificado»

Cloud Storage es nuestro servicio para almacenar “objetos” (archivos) no estructurados. Su versatilidad lo hace fundamental para múltiples casos de uso.

Clases de Almacenamiento y Políticas de Ciclo de Vida

Sección titulada «Clases de Almacenamiento y Políticas de Ciclo de Vida»

No todo el almacenamiento es igual. Clasificamos nuestros datos y aplicamos políticas de ciclo de vida para moverlos automáticamente a clases de almacenamiento más económicas a medida que envejecen, optimizando así los costos.

ClaseCosto almacénCosto accesoUso típico en HERAPolítica de ciclo de vida (ej: logs)
StandardAltoBajoAssets públicos (con CDN), uploads de usuarios, datos “calientes”.0-30 días
NearlineMedioMedioLogs recientes, backups de corto plazo.30-90 días
ColdlineBajoAltoBackups de DR, datos de acceso poco frecuente.90-365 días
ArchiveMuy BajoMuy AltoArchivado a largo plazo por cumplimiento normativo.> 365 días

Tenemos una nomenclatura estandarizada para nuestros buckets que refleja su propósito y ambiente.

BucketClase por DefectoAccesoPropósito
herdez-assets-prdStandardPúblico (a través de CDN)Imágenes, CSS, JS de nuestros sitios web.
herdez-uploads-prdStandardPrivadoArchivos subidos por los usuarios.
herdez-logs-prdStandardPrivadoLogs de auditoría y de aplicaciones.
herdez-backups-prdNearlinePrivadoBackups de bases de datos y VMs.
herdez-archive-prdArchivePrivadoDatos retenidos por cumplimiento legal (ej. 7 años).

BigQuery es la pieza central de nuestra estrategia de datos analíticos. Es un data warehouse totalmente gestionado y serverless que nos permite ejecutar consultas SQL sobre terabytes de datos en segundos.

BigQuery Data Warehouse — Flujo de Datos
Fuentes de Datos
Cloud SQL (CDC)
GCS (Logs/Files)
Pub/Sub (Events)
Ingesta
Stream Dataflow
Batch Dataflow
Stream Dataflow
BigQuery
raw_data
Datos sin transformar
ETL / ELT con SQL ↓
analytics
Datos procesados
Consumo
Looker Studio
Modelos ML
APIs de Datos
Mensaje clave Los datos fluyen de Cloud SQL/Storage a BigQuery vía pipelines automatizados para analytics.
  • Ingesta: Los datos llegan a BigQuery desde múltiples fuentes, ya sea en tiempo real (streaming) desde Pub/Sub o en lotes (batch) desde Cloud Storage.
  • Capa Cruda (raw_data): Almacenamos los datos tal como llegan, sin transformar.
  • Capa Analítica (analytics): Ejecutamos consultas SQL programadas para limpiar, transformar y agregar los datos crudos en tablas optimizadas para el análisis.
  • Consumo: Los datos limpios se utilizan para crear dashboards en Looker Studio, entrenar modelos de Machine Learning o alimentar APIs.

Memorystore (Redis): Caché de Alta Velocidad

Sección titulada «Memorystore (Redis): Caché de Alta Velocidad»

Memorystore nos proporciona una instancia de Redis totalmente gestionada. Lo utilizamos para acelerar las respuestas de nuestras aplicaciones y reducir la carga sobre las bases de datos.

Caso de UsoDescripciónTTL Típico
Caché de SesionesAlmacenar los datos de sesión de los usuarios autenticados.24 horas
Caché de DatosGuardar resultados de consultas de base de datos frecuentes o costosas.1 hora
Rate LimitingImplementar límites de velocidad para proteger nuestras APIs del abuso.1 minuto
ContadoresContadores en tiempo real para métricas de negocio.Variable

Acceso desde workloads — IAM a nivel de bucket

Sección titulada «Acceso desde workloads — IAM a nivel de bucket»

La seguridad en Cloud Storage ha evolucionado. En HERA, gestionamos el acceso a los datos utilizando IAM a nivel de bucket en combinación con Workload Identity, eliminando las ACLs (Access Control Lists) heredadas y previniendo la exposición accidental de datos.

Todo bucket de Cloud Storage creado en HERA debe cumplir con las siguientes configuraciones de seguridad (enforced vía Terraform):

  • Uniform Bucket-Level Access (UBLA): Habilitado. Desactiva las ACLs individuales de objetos y centraliza todo el control de acceso en las políticas IAM del bucket.
  • Public Access Prevention (PAP): Enforced. Bloquea cualquier intento (accidental o malicioso) de hacer público el bucket o sus objetos. Únicamente los buckets designados explícitamente para assets públicos (ej. CDN) tienen excepciones.
  • Cifrado CMEK (Customer-Managed Encryption Keys): Los buckets que almacenan datos clasificados como Confidencial o Restringido deben usar claves de Cloud KMS gestionadas por HERA, no las claves por defecto de Google.
  • Object Versioning y Retention Policies: Para datos críticos (ej. auditoría, financieros), se habilita el versionado para proteger contra sobreescrituras y políticas de retención (WORM) para prevenir borrados antes de tiempo.
ParámetroValor estándarAplicación
uniform_bucket_level_accesstrueTodos los buckets — elimina ACLs legacy
public_access_preventionenforcedTodos los buckets salvo los explícitamente públicos (CDN)
versioningenabledBuckets con datos críticos (auditoría, financieros, pedidos)
Cifrado CMEK (Cloud KMS)ObligatorioDatos clasificados como Confidencial o Restringido
Retention policy (WORM)≥ 30 díasBuckets de auditoría, evidencia de compliance, datos financieros
NamingPrefijo ghdz-Todos — ver Estándares de Nombramiento GCP

Lifecycle por defecto (optimización de costos)

Sección titulada «Lifecycle por defecto (optimización de costos)»

Los buckets no-críticos aplican transiciones automáticas de clase de storage para reducir costo sin intervención manual:

Edad del objetoClase de destinoCosto relativo
0 – 90 díasStandard
90 – 365 díasColdline~0.4×
> 365 díasArchive~0.1×

Los buckets de audit/compliance pueden omitir estas transiciones si la retention policy exige acceso inmediato durante todo el periodo.

El acceso de las aplicaciones a los buckets se otorga asignando roles de IAM al Google Service Account (GSA) de la aplicación, utilizando Workload Identity.

Rol IAMUso CorrectoAntipatrón Bloqueado
roles/storage.objectViewerServicios que solo necesitan leer archivos (ej. procesamiento de reportes).Asignar a toda la GSA si solo necesita leer un bucket.
roles/storage.objectCreatorServicios que solo suben archivos pero no necesitan leerlos ni borrarlos (ej. ingesta de logs).
roles/storage.objectUserServicios que necesitan leer y escribir (ej. procesamiento de imágenes).Asignar roles/storage.admin. Las aplicaciones nunca deben poder borrar el bucket ni cambiar sus políticas IAM.

Cuando una aplicación necesita que un usuario externo (un cliente web, un partner) suba o descargue un archivo directamente a Cloud Storage sin pasar por el backend (para ahorrar ancho de banda), utilizamos Signed URLs.

Una Signed URL otorga acceso temporal (ej. 15 minutos) para realizar una acción específica sobre un objeto específico.

Para que un microservicio en GKE pueda generar una Signed URL, su GSA necesita el permiso para firmar tokens en nombre propio:

Ventana de terminal
# Otorgar permiso al GSA para firmar URLs (impersonación de sí mismo)
gcloud iam service-accounts add-iam-policy-binding \
mi-app-gsa@mi-proyecto.iam.gserviceaccount.com \
--role=roles/iam.serviceAccountTokenCreator \
--member="serviceAccount:mi-app-gsa@mi-proyecto.iam.gserviceaccount.com"

Ejemplo de generación en Node.js:

const { Storage } = require('@google-cloud/storage');
// ADC resuelve la identidad automáticamente gracias a Workload Identity
// # simplificado para ilustración - En producción, instanciar globalmente y manejar errores
const storage = new Storage();
async function generateV4UploadSignedUrl(bucketName, fileName) {
try {
const options = {
version: 'v4',
action: 'write',
expires: Date.now() + 15 * 60 * 1000, // 15 minutos
contentType: 'application/octet-stream',
};
const [url] = await storage
.bucket(bucketName)
.file(fileName)
.getSignedUrl(options);
return url;
} catch (error) {
console.error('Error al generar Signed URL:', error);
throw error;
}
}

Ejemplo de generación en Python:

from google.cloud import storage
from datetime import timedelta
# ADC resuelve la identidad automáticamente gracias a Workload Identity
client = storage.Client()
def generate_upload_signed_url(bucket_name: str, blob_name: str) -> str:
bucket = client.bucket(bucket_name)
blob = bucket.blob(blob_name)
url = blob.generate_signed_url(
version="v4",
expiration=timedelta(minutes=15),
method="PUT",
content_type="application/octet-stream",
)
return url

Antes de aprovisionar un nuevo bucket, valida:

  • UBLA está habilitado (uniform_bucket_level_access = true).
  • Public Access Prevention está enforced (a menos que sea asset público explícito).
  • La clase de almacenamiento por defecto coincide con el patrón de uso.
  • Lifecycle policy configurada para transicionar datos antiguos a Coldline/Archive.
  • CMEK configurado si el bucket almacena datos clasificados como Confidencial o Restringido.
  • Roles IAM asignados son objectViewer, objectCreator o objectUser — nunca storage.admin.
  • Los accesos son a través de Workload Identity (GSA), no cuentas de usuario directas.
  • Si el bucket usa Signed URLs, la GSA tiene roles/iam.serviceAccountTokenCreator sobre sí misma.

Pub/Sub es un servicio de mensajería global que nos permite desacoplar nuestros servicios y construir arquitecturas robustas y escalables basadas en eventos.

En lugar de que los servicios se llamen directamente entre sí (acoplamiento fuerte), un servicio publica un evento (un mensaje) en un topic. Otros servicios, sin que el publicador lo sepa, se suscriben a ese topic y reaccionan al evento.

Ejemplo: Creación de un Pedido

  1. El servicio de eCommerce recibe un nuevo pedido.
  2. Publica un mensaje en el topic pedidos-creados con los detalles del pedido.
  3. Tres servicios diferentes reaccionan a este único evento:
    • El servicio de Inventario se suscribe, recibe el mensaje y descuenta el stock.
    • El servicio de Notificaciones se suscribe y envía un email de confirmación al cliente.
    • El pipeline de Analytics se suscribe y envía el evento a BigQuery.
Pub/Sub — Ejemplo: Creación de un Pedido
eCommerce App
Recibe nuevo pedido
Publica
Topic
pedidos-creados
Inventario
Descuenta stock
Notificaciones
Envía email
Analytics
Envía a BigQuery
Resiliencia: Si un servicio falla, los otros siguen procesando
Escalabilidad: Añade suscriptores sin tocar el publisher
Mensaje clave Pub/Sub desacopla productores y consumidores. Los mensajes persisten hasta ser procesados.