Alejandría

Busca en Alejandría

Herramientas

Terraform y OpenTofu

Infraestructura como código declarativa, versionada y revisable en pull requests.

01

En pocas palabras

Herramientas de IaC que describen recursos de nube en HCL, calculan un plan de cambios contra el estado real y lo aplican. OpenTofu es el fork open source de Terraform gestionado por la Linux Foundation.

Qué problema resuelve

Infraestructura creada a mano en consolas, irreproducible entre entornos, sin historial de cambios ni revisión.

Cuándo utilizarlo

Cualquier entorno de nube con más de unos pocos recursos. Ejemplo: replicar la configuración de Cloud Run, VPC y Cloud SQL de un país en otro.

02

De la idea a la práctica

Funcionamiento, ejemplos y decisiones para pasar al siguiente nivel.

Terraform u OpenTofu

En 2023 HashiCorp cambió la licencia de Terraform a BSL 1.1; la comunidad creó OpenTofu bajo MPL 2.0. Ambos comparten sintaxis HCL y la mayoría de proveedores. OpenTofu añade funciones como el cifrado del estado en el cliente. La elección depende de licencia, soporte comercial (HCP Terraform) y ecosistema de la organización.

Ciclo de trabajo

tofu init      # descarga proveedores y configura el backend
tofu plan      # calcula diferencias entre código y realidad
tofu apply     # aplica el plan revisado

En CI, el plan se publica como comentario en el pull request y el apply se ejecuta solo tras la aprobación y el merge.

Ejemplo: servicio de Cloud Run

terraform {
  backend "gcs" {
    bucket = "krediya-tfstate"
    prefix = "originacion/prod"
  }
}

resource "google_cloud_run_v2_service" "api" {
  name     = "api-solicitudes"
  location = "us-east1"

  template {
    service_account = google_service_account.api.email
    scaling {
      min_instance_count = 1
      max_instance_count = 20
    }
    containers {
      image = "us-east1-docker.pkg.dev/krediya/apps/api-solicitudes:${var.version}"
      resources {
        limits = { cpu = "1", memory = "512Mi" }
      }
      env {
        name = "DB_PASSWORD"
        value_source {
          secret_key_ref {
            secret  = google_secret_manager_secret.db.secret_id
            version = "latest"
          }
        }
      }
    }
  }
}

Estructura y estado

Práctica Por qué
Un estado por entorno y dominio Limita el radio de impacto de un apply
Módulos versionados Reutilizar patrones (servicio + SA + alertas) entre países
Backend remoto con bloqueo Evita aplicaciones concurrentes (GCS tiene bloqueo nativo)
Secretos fuera del código Usa Secret Manager; el estado puede contener valores sensibles
Detección de drift plan programado que alerta si alguien cambió algo a mano

Antipatrones frecuentes

  • Un único estado gigante para toda la organización: planes de 20 minutos y miedo a aplicar.
  • apply desde portátiles con credenciales personales.
  • terraform import masivo sin refactorizar: se replica el desorden de la consola en código.

Módulo reutilizable

# modules/servicio-cloud-run/variables.tf
variable "nombre"         { type = string }
variable "imagen"         { type = string }
variable "region"         { type = string }
variable "max_instancias" {
  type    = number
  default = 10
  validation {
    condition     = var.max_instancias <= 50
    error_message = "Más de 50 instancias requiere revisión de conexiones a la base de datos."
  }
}
# entornos/prod/originacion.tf
module "api_solicitudes" {
  source         = "git::https://github.com/krediya/terraform-modules.git//servicio-cloud-run?ref=v3.2.0"
  nombre         = "api-solicitudes"
  imagen         = var.imagen_api
  region         = "us-east1"
  max_instancias = 20
}

El módulo agrupa cuenta de servicio, servicio, alertas y permisos con las convenciones de la organización. Fijar ref a una versión evita que un cambio del módulo afecte a todos los entornos a la vez.

Pruebas de módulos

# tests/servicio.tftest.hcl
variables {
  nombre = "prueba"
  imagen = "us-docker.pkg.dev/cloudrun/container/hello"
  region = "us-east1"
}

run "valida_limite_instancias" {
  command = plan
  variables { max_instancias = 80 }
  expect_failures = [var.max_instancias]
}

run "usa_cuenta_de_servicio_dedicada" {
  command = plan
  assert {
    condition     = google_cloud_run_v2_service.this.template[0].service_account != ""
    error_message = "El servicio debe usar una cuenta de servicio dedicada."
  }
}

terraform test (o tofu test) ejecuta los run en orden; con command = plan no crea recursos.

Refactorizar sin destruir

moved {
  from = google_cloud_run_v2_service.api
  to   = module.api_solicitudes.google_cloud_run_v2_service.this
}

import {
  to = google_storage_bucket.documentos
  id = "krediya-documentos-prod"
}

removed {
  from = google_storage_bucket.temporal
  lifecycle { destroy = false }   # dejar de gestionarlo sin borrarlo
}

Estos bloques sustituyen a comandos manuales sobre el estado (state mv, import, state rm) y quedan revisados en el pull request.

Flujo en CI

Paso en el PR Herramienta
Formato y validación fmt -check, validate, tflint
Seguridad y políticas Trivy/Checkov, Conftest sobre el plan
Plan publicado como comentario GitHub Actions / GitLab CI, Atlantis, HCP Terraform, Spacelift
Apply tras merge Identidad de CI con OIDC, sin claves, con aprobación en producción

Versiona también .terraform.lock.hcl y declara versiones de proveedores en required_providers, para que todos usen las mismas.

Criterios de implementación

Empieza por los recursos nuevos y trae los existentes gradualmente con bloques import. Ejecuta análisis estático (tflint, Trivy o Checkov) en el pipeline como parte de continuous compliance. Compara con Crossplane si la organización gestiona ya todo desde Kubernetes.

Continúa en las fuentes

Documentación oficial para verificar detalles y explorar más.