Infraestructura como Código - Terraform
Este documento describe los procesos de despliegue y gestión de infraestructura de GCP mediante Terraform. Se enfoca en cómo desplegar y operar la infraestructura, no en la arquitectura de los componentes.
Overview
La infraestructura de GCP se gestiona mediante Terraform utilizando módulos reutilizables. Repositorio: solventomx/data/gcp.
Estructura del Repositorio
terraform-gcp-infrastructure/
├── provider.tf # Configuración de providers
├── versions.tf # Versiones de providers
├── variables.tf # Variables comunes
├── variables_dev.tf # Variables de desarrollo
├── variables_prod.tf # Variables de producción
├── terraform.tfvars # Valores de variables
├── tags.tf # Tags comunes
├── dataflow.tf # Recursos de Dataflow
├── pub_sub.tf # Recursos de Pub/Sub
├── cloud_run.tf # Recursos de Cloud Run
├── buckets.tf # Recursos de Cloud Storage
├── cloud_tasks.tf # Recursos de Cloud Tasks
├── notification.tf # Notificaciones de GCS
├── vpc.tf # Recursos de VPC
└── modules/ # Módulos reutilizables
├── dataflow/ # Módulo de Dataflow
├── pubsub/ # Módulo de Pub/Sub
├── cloud_run/ # Módulo de Cloud Run
├── buckets/ # Módulo de buckets
├── cloud_tasks/ # Módulo de Cloud Tasks
├── notification/ # Módulo de notificaciones
└── vpc/ # Módulo de VPC
Proyectos GCP
La infraestructura se despliega en dos proyectos:
solvento-data-dev: Ambiente de desarrollosolvento-data-prod: Ambiente de producción
Módulos Principales
Módulo de Dataflow
Gestiona jobs de Dataflow desde templates desplegados.
Ubicación: modules/dataflow/
Variables:
- job_name: Nombre del job de Dataflow
- template_gcs_path: Ruta GCS del template
- temp_gcs_location: Ubicación GCS para archivos temporales
- region: Región donde se ejecuta el job
- project_id: ID del proyecto GCP
- service_account_email: Service account (opcional)
- network: Red (default: "default")
- subnetwork: Subred (opcional)
- machine_type: Tipo de máquina (default: "n1-standard-2")
- max_num_workers: Número máximo de workers (default: 10)
- enable_streaming_engine: Habilitar streaming engine (default: false)
Ejemplo de uso:
module "dataflow_prod" {
source = "./modules/dataflow"
for_each = var.dataflow_templates_prod
job_name = each.value.job_name
template_gcs_path = each.value.template_gcs_path
temp_gcs_location = each.value.temp_gcs_location
region = var.region_prod
project_id = var.project_id_prod
service_account_email = try(each.value.service_account_email, null)
machine_type = try(each.value.machine_type, null)
max_num_workers = try(each.value.max_num_workers, null)
enable_streaming_engine = try(each.value.enable_streaming_engine, null)
}
Configuración en variables_prod.tf:
dataflow_templates_prod = {
invoices-webhook-prod = {
job_name = "invoices-webhook-prod-20251203-154624"
template_gcs_path = "gs://artifacts-bucket-solvento-data-prod/syntage/dataflow_templates/invoices-webhook-prod"
temp_gcs_location = "gs://syntage-ingestion/tmp/"
service_account_email = "dataflow-sa@solvento-data-prod.iam.gserviceaccount.com"
machine_type = "n1-standard-4"
max_num_workers = 10
enable_streaming_engine = true
}
}
Módulo de Pub/Sub
Gestiona topics y subscriptions de Pub/Sub.
Ubicación: modules/pubsub/
Variables:
- topic_name: Nombre del topic
- project_id: ID del proyecto
- subscriptions: Map de subscriptions con configuración
- tags: Tags para recursos
Ejemplo de uso:
module "pubsub_prod" {
for_each = var.pubsub_module_prod
source = "./modules/pubsub"
topic_name = each.value.topic_name
project_id = var.project_id_prod
subscriptions = each.value.subscriptions
tags = merge(local.tags_prod, try(each.value.tags, {}))
}
Configuración:
pubsub_module_prod = {
invoices-webhook-prod = {
topic_name = "invoices-webhook-prod"
subscriptions = {
invoices-webhook-subscription = {
subscription_name = "invoices-webhook-subscription"
ack_deadline_seconds = 60
}
}
tags = {
project = "data"
component = "ingestion"
}
}
}
Módulo de Cloud Run
Gestiona servicios de Cloud Run.
Ubicación: modules/cloud_run/
Variables principales:
- name: Nombre del servicio
- location: Región
- image: Imagen Docker
- port: Puerto (default: 8080)
- memory: Memoria (default: "512Mi")
- cpu: CPU (default: "1000m")
- max_instances: Máximo de instancias
- min_instances: Mínimo de instancias
- service_account_email: Service account
- environment_variables: Variables de entorno
- secrets: Secretos
Módulo de Buckets
Gestiona buckets de Cloud Storage.
Ubicación: modules/buckets/
Características: - Configuración de lifecycle rules - Versionado - IAM bindings - Storage classes
Módulo de Cloud Tasks
Gestiona colas de Cloud Tasks.
Ubicación: modules/cloud_tasks/
Variables:
- name: Nombre de la cola
- location: Región
- max_concurrent_dispatches: Máximo de despachos concurrentes
- max_dispatches_per_second: Máximo de despachos por segundo
- max_attempts: Máximo de intentos
Flujo de Despliegue
1. Desarrollo Local
# Inicializar Terraform
terraform init
# Planificar cambios
terraform plan
# Aplicar cambios (solo en desarrollo)
terraform apply
2. CI/CD Pipeline
- Crear branch: Crear una rama para los cambios
- Configurar variables: Actualizar
terraform.tfvars - Push a branch:
git push origin feature/tu-rama - Merge Request: Crear MR hacia
main - Merge a main: Al hacer merge, se lanza el pipeline CI/CD
- Deploy manual: Ejecutar manualmente la etapa de deploy en el pipeline
3. Despliegue de Templates
- Desplegar template: Usar
deploy_templates.shpara desplegar template a GCS - Actualizar Terraform: Actualizar
variables_prod.tfcon nueva ruta del template - Aplicar Terraform: Ejecutar
terraform applypara crear/actualizar el job
Integración Templates ↔ Terraform
Flujo Completo
-
Desarrollo del Template:
-
Desplegar Template:
-
Actualizar Terraform:
-
Aplicar Terraform:
Mejores Prácticas
Versionado
- Templates: Versionado automático con timestamp en GCS
- Terraform: Usar versiones específicas de providers
- Jobs: Nombres de jobs incluyen timestamp para trazabilidad
Separación de Ambientes
- Variables separadas:
variables_dev.tfyvariables_prod.tf - Providers separados:
google.devygoogle.prod - Tags diferenciados: Tags específicos por ambiente
Gestión de Secretos
- Usar Secret Manager para credenciales
- No hardcodear secretos en código
- Referenciar secretos en Cloud Run mediante variables
Tags y Labels
- Tags consistentes para todos los recursos
- Tags por proyecto, componente, ambiente
- Facilita gestión de costos y organización