Desplegar Base de Datos PRIVADA en GCP con Terraform: Cloud SQL PostgreSQL + VPC Peering
Diseña una arquitectura de Cloud SQL PostgreSQL sin exposición a Internet, automatizada con Terraform y conectada mediante Private Service Access. La clave no es simplemente activar Private IP: es construir correctamente la relación entre VPC, rango reservado, Service Networking y Cloud SQL para obtener una plataforma reproducible, segura y operable.
Lo que aprenderás
La arquitectura: una base de datos que no necesita Internet
El objetivo es eliminar la IP pública de Cloud SQL y hacer que las aplicaciones que viven en la VPC consuman PostgreSQL mediante una dirección IP privada. Google Cloud recomienda Private IP cuando los clientes están dentro de una VPC o tienen conectividad privada hacia ella.
En este diseño, Private Service Access establece una conexión privada
mediante VPC Network Peering entre nuestra VPC y la red administrada por Google que
proporciona el servicio. El rango de direcciones reservado con propósito
VPC_PEERING permite que Google asigne las direcciones internas utilizadas
por Cloud SQL.
La consecuencia arquitectónica importante es que la base de datos deja de ser un recurso que debemos proteger desde Internet mediante listas de IP públicas y pasa a formar parte del plano de red privado de nuestra arquitectura.
Matriz de decisión: ¿Public IP, Private IP o PSC?
| Patrón | Exposición | Conectividad | Seguridad | Complejidad | Cuándo utilizarlo |
|---|---|---|---|---|---|
| Public IP | Internet | Endpoint IPv4 público | Depende de authorized networks / TLS / conectores | Baja | Clientes externos que no tienen conectividad privada. |
| Private IP + PSA | Sin endpoint público | VPC + Service Networking | Excelente para workloads internos | Media | Patrón recomendado para aplicaciones dentro de GCP. |
| Private Service Connect | Sin exposición pública | Endpoint PSC | Segmentación y control avanzado | Alta | Escenarios donde se necesita publicar/consumir servicios mediante endpoints PSC. |
| VPN / Interconnect + Private IP | Sin Internet pública para DB | Red híbrida privada | Alta | Alta | Datacenters, oficinas o VPC externas con conectividad híbrida. |
Para Cloud SQL PostgreSQL, Private Service Access requiere una conexión privada
previamente establecida sobre la VPC. La documentación de Google muestra Terraform
mediante google_compute_global_address,
google_service_networking_connection y
google_sql_database_instance.
Private Service Access no es simplemente "activar Private IP"
Este es uno de los puntos donde aparecen más errores en implementaciones Terraform. Cloud SQL no puede utilizar una VPC arbitraria con Private IP si antes no existe la infraestructura de Private Service Access.
El flujo lógico es:
VPC
Crear la red que alojará los consumidores de la base de datos.
Rango reservado
Reservar un bloque CIDR con propósito VPC_PEERING para servicios gestionados.
Service Networking
Crear google_service_networking_connection contra servicenetworking.googleapis.com.
Cloud SQL
Asociar PostgreSQL a la VPC y deshabilitar la dirección IPv4 pública.
Operación
Utilizar Cloud SQL Studio, IAM y autenticación de base de datos para administrar los datos.
⚠️ Antipatrón crítico: creer que "Private IP" significa aislamiento automático
Tener una dirección privada no significa que cualquier componente de la arquitectura esté correctamente segmentado. El aislamiento depende de quién tiene rutas hacia la VPC, qué rangos están anunciados, qué identidades pueden autenticarse y qué reglas de red permiten el tráfico.
Otro error frecuente consiste en crear el google_sql_database_instance
antes de que exista la conexión de Service Networking. En Terraform esto puede producir
carreras de provisión o errores de operación.
Solución: modela explícitamente la dependencia mediante
depends_on, reserva un rango suficientemente dimensionado y evita diseñar
el rango de PSA solapado con las subredes que utilizarán tus workloads.
Además, no habilites una IP pública "solo para probar" en producción: la configuración de red debería ser reproducible desde Terraform y el acceso operativo debería resolverse con los mecanismos de autenticación y administración previstos.
Implementación de producción con Terraform
El siguiente ejemplo crea una VPC custom, una subred para workloads, un rango reservado para Private Service Access, la conexión de Service Networking y finalmente una instancia PostgreSQL de Cloud SQL sin IP pública.
terraform {
required_version = ">= 1.6.0"
required_providers {
google = {
source = "hashicorp/google"
version = ">= 6.0"
}
}
}
provider "google" {
project = var.project_id
region = var.region
}
variable "project_id" {
type = string
}
variable "region" {
type = string
default = "europe-west1"
}
resource "google_compute_network" "private_vpc" {
name = "data-private-vpc"
auto_create_subnetworks = false
}
resource "google_compute_subnetwork" "apps" {
name = "data-apps-subnet"
ip_cidr_range = "10.20.0.0/24"
region = var.region
network = google_compute_network.private_vpc.id
private_ip_google_access = true
}
# Rango reservado exclusivamente para
# Private Service Access / VPC Peering.
resource "google_compute_global_address" "private_services" {
name = "google-managed-services-data"
purpose = "VPC_PEERING"
address_type = "INTERNAL"
prefix_length = 16
network = google_compute_network.private_vpc.id
}
# Conexión privada entre nuestra VPC y
# la red de servicios administrados de Google.
resource "google_service_networking_connection" "private_vpc_connection" {
network = google_compute_network.private_vpc.id
service = "servicenetworking.googleapis.com"
reserved_peering_ranges = [
google_compute_global_address.private_services.name
]
}
resource "google_sql_database_instance" "postgres" {
name = "private-postgres"
region = var.region
database_version = "POSTGRES_17"
# La dependencia evita intentar crear Cloud SQL
# antes de disponer de Private Service Access.
depends_on = [
google_service_networking_connection.private_vpc_connection
]
settings {
tier = "db-custom-2-8192"
availability_type = "REGIONAL"
backup_configuration {
enabled = true
point_in_time_recovery_enabled = true
}
ip_configuration {
# Sin dirección IPv4 pública.
ipv4_enabled = false
# Cloud SQL utilizará la VPC privada.
private_network = google_compute_network.private_vpc.id
# Evita que una configuración de red posterior
# introduzca accidentalmente rangos públicos.
enable_private_path_for_google_cloud_services = true
}
maintenance_window {
day = 7
hour = 3
update_track = "stable"
}
}
deletion_protection = true
}
resource "google_sql_database" "application" {
name = "application"
instance = google_sql_database_instance.postgres.name
}
output "vpc_name" {
value = google_compute_network.private_vpc.name
}
output "postgres_private_ip" {
value = google_sql_database_instance.postgres.private_ip_address
sensitive = true
}
output "postgres_connection_name" {
value = google_sql_database_instance.postgres.connection_name
}
La propiedad fundamental es ipv4_enabled = false. La instancia queda
configurada para conectividad privada y utiliza private_network para
asociarse a la VPC.
En producción también conviene mantener deletion_protection = true y
definir explícitamente backups, recuperación point-in-time, ventana de mantenimiento,
disponibilidad y sizing según los SLO reales de la aplicación.
Un detalle importante: las rutas de VPC Peering
En arquitecturas donde se utilizan rutas personalizadas o escenarios de networking más complejos, puede ser necesario gestionar explícitamente las rutas importadas y exportadas de la conexión de peering.
El patrón de Terraform utilizado por Google para determinados escenarios de Cloud SQL
Private IP contempla google_compute_network_peering_routes_config.
resource "google_compute_network_peering_routes_config" "private_services_routes" {
peering = google_service_networking_connection.private_vpc_connection.peering
network = google_compute_network.private_vpc.name
import_custom_routes = true
export_custom_routes = true
}
No debes añadir este recurso mecánicamente a todas las arquitecturas. La decisión depende de si necesitas intercambiar rutas personalizadas a través del peering. El principio correcto es habilitar únicamente la propagación de rutas necesaria para el diseño.
¿Qué ocurre realmente con el tráfico?
Desde una VM, GKE u otro workload con acceso a la VPC, el cliente resuelve la dirección privada de Cloud SQL y el tráfico permanece dentro de la infraestructura privada de Google Cloud.
Esto reduce la superficie de exposición. No necesitas publicar un endpoint PostgreSQL en Internet únicamente porque una aplicación necesite acceder a la base de datos.
Para conectividad híbrida, el patrón puede extenderse mediante VPN o Cloud Interconnect, siempre que exista conectividad hacia la VPC donde está establecido Private Service Access.
Cloud SQL Studio: administración sin abrir PostgreSQL a Internet
Una pregunta habitual después de eliminar la IP pública es: ¿cómo administro entonces la base de datos?
Cloud SQL Studio permite interactuar con Cloud SQL directamente desde la consola de Google Cloud. Para PostgreSQL, proporciona Explorer, editor SQL y resultados de consultas, permitiendo ejecutar DDL, DML y DQL.
El acceso no implica convertir la instancia en pública. Cloud SQL Studio utiliza el
plano de administración de Google Cloud y exige los permisos IAM correspondientes.
El rol específico de usuario de Cloud SQL Studio es
roles/cloudsql.studioUser.
# Ejemplo conceptual de IAM para un operador:
resource "google_project_iam_member" "cloud_sql_studio_user" {
project = var.project_id
role = "roles/cloudsql.studioUser"
member = "user:operador@example.com"
}
Después de desplegar la instancia, el flujo operativo es: seleccionar la instancia en Cloud SQL, abrir Cloud SQL Studio, seleccionar la base de datos y autenticarse mediante IAM Database Authentication o mediante las credenciales del usuario PostgreSQL.
Para consultas de producción pesadas, Cloud SQL Studio no debería sustituir a un cliente especializado: la herramienta está orientada a consultas ligeras y tiene limitaciones operativas, entre ellas un límite de cinco minutos para las solicitudes y truncamiento de respuestas superiores a 10 MB.
Patrones de diseño y mejores prácticas
1. Separar la red de aplicaciones del rango de PSA
No utilices el mismo rango CIDR para las subredes de aplicaciones y para el espacio reservado a Google-managed services. El rango de PSA debe tratarse como un bloque dedicado de infraestructura.
2. Diseñar el CIDR pensando en expansión
Cloud SQL puede necesitar espacio para diferentes instancias y regiones. Dimensionar demasiado agresivamente el rango reservado puede convertirse en un problema de capacidad años después del primer despliegue.
3. Evitar la IP pública como mecanismo de administración
El acceso administrativo debe diseñarse alrededor de IAM, Cloud SQL Studio, conectividad privada, Cloud SQL Auth Proxy o mecanismos de acceso controlado según el caso de uso.
4. Terraform debe controlar el grafo de dependencias
VPC → rango reservado → Service Networking → Cloud SQL es una dependencia arquitectónica,
no un detalle cosmético. Expresarla correctamente reduce fallos durante
terraform apply.
5. Mantener la región alineada
Mantener los consumidores y Cloud SQL en regiones coherentes reduce latencia y evita costes innecesarios de transferencia interregional. La decisión final debe basarse en requisitos de disponibilidad, residencia de datos y disaster recovery.
6. Gobernar los permisos por identidad
El aislamiento de red no sustituye IAM. Un operador con acceso excesivo puede seguir siendo un riesgo aunque PostgreSQL no tenga una IP pública. Aplica mínimo privilegio tanto en Google Cloud como dentro de PostgreSQL.
Checklist de implementación empresarial
Definir el modelo de red
Determina VPC, subredes, regiones, CIDRs, conectividad híbrida y consumidores autorizados.
Reservar CIDR para PSA
Crea un rango interno dedicado con propósito VPC_PEERING.
Crear Service Networking
Establece google_service_networking_connection con servicenetworking.googleapis.com.
Desplegar Cloud SQL
Configura private_network y ipv4_enabled = false.
Proteger el ciclo de vida
Activa backups, PITR, deletion protection, mantenimiento controlado y monitorización.
Configurar IAM
Define quién puede administrar la instancia, ejecutar SQL y modificar infraestructura.
Validar conectividad
Comprueba DNS, rutas, IP privada, conectividad desde los workloads y ausencia de IP pública.
Validar Cloud SQL Studio
Accede desde la consola, autentica el usuario y ejecuta una consulta de validación.
Automatizar con CI/CD
Ejecuta Terraform mediante pipelines con revisión, plan, aprobación y estado remoto protegido.
FinOps: dónde se puede encarecer esta arquitectura
Private IP no significa que la red sea gratuita. El coste global depende principalmente del tamaño y configuración de Cloud SQL, almacenamiento, backups, alta disponibilidad, transferencia de datos y otros servicios asociados.
Una de las optimizaciones más importantes es evitar tráfico innecesariamente interregional. Si una aplicación está en una región y PostgreSQL en otra, la decisión puede aumentar tanto la latencia como los costes de transferencia.
Desde una perspectiva FinOps, el diseño correcto consiste en colocar juntos los componentes que generan tráfico intenso, seleccionar el tamaño de Cloud SQL a partir de métricas reales y revisar periódicamente CPU, memoria, conexiones, almacenamiento, IOPS y patrones de transferencia.
FAQ: Cloud SQL PostgreSQL privado con Terraform
¿Qué diferencia hay entre Private Service Access y una VPC Peering tradicional?
Private Service Access utiliza VPC Network Peering como mecanismo subyacente para
conectar la VPC del consumidor con la red de servicios administrados. En Terraform,
el patrón se implementa reservando un rango con propósito VPC_PEERING
y creando un google_service_networking_connection. No debe confundirse
con crear manualmente un peering arbitrario entre dos VPC de aplicaciones.
¿Cómo puedo evitar que Cloud SQL PostgreSQL tenga una IP pública?
Configura ipv4_enabled = false dentro de
ip_configuration y proporciona
private_network con la VPC que tiene Private Service Access.
La conexión de Service Networking debe existir antes de crear la instancia.
¿Puedo utilizar Cloud SQL Studio con una instancia PostgreSQL privada?
Sí. Cloud SQL Studio permite consultar y administrar Cloud SQL desde la consola
de Google Cloud. Requiere permisos IAM adecuados, incluyendo
roles/cloudsql.studioUser, además de autenticación de base de datos.
La instancia no necesita exponerse mediante una IP pública únicamente para utilizar
Cloud SQL Studio.
