← Todo el material
Curso Avanzado 23 de agosto de 2026

Deploy de Agentes — Módulo 10: Terraform desde cero — infraestructura como código

Décimo módulo del Curso de Deploy de Agentes: dejar de clickear en la consola de la nube y describir la infra en archivos versionados. Qué es IaC, el lenguaje HCL, provider, resource, variables, outputs y el state; el ciclo init → plan → apply → destroy y un ejemplo mínimo real en AWS para entender el flujo antes de tocar GCP.

☰ Índice del contenido

Décimo módulo del Curso de Deploy de Agentes. En el Módulo 9 cerramos la puerta de entrada: checks obligatorios, revisiones y las brechas que un pipeline de equipo tiene que tapar antes de dejar pasar código. Tu agente ya está probado, empaquetado en una imagen y con CI verde. Falta lo grande: la infraestructura donde va a correr — el registro de imágenes, el servicio que la ejecuta, los secretos, los permisos. La pregunta de este módulo es cómo creas todo eso. Y la respuesta profesional no es “entrando a la consola de la nube y clickeando”.

La tesis del módulo

Clickear en la consola crea infraestructura que nadie puede revisar, repetir ni recordar. Infraestructura como código es describir esa infra en archivos versionados: se revisa en un Pull Request como cualquier código, se recrea idéntica en un comando y queda documentada por el solo hecho de existir.

El problema del clickeo

Cuando creas un servicio entrando a la consola web de AWS o GCP y apretando botones, pasa algo invisible pero grave: ese conocimiento vive en tu cabeza y en ningún otro lado. Nadie sabe qué configuraste, ni por qué, ni cómo reproducirlo. Si el ambiente se cae, lo rearmas de memoria. Si entra otra persona, le dictas los clicks. Si necesitas un ambiente de staging idéntico al de producción, rezas por acordarte de cada casilla.

IaC (Infrastructure as Code, infraestructura como código) resuelve esto de raíz: en vez de clickear, escribes en archivos qué infraestructura quieres, y una herramienta la crea por ti. Esos archivos van a Git. Se revisan en PR. Se versionan. Un cambio de infra pasa por el mismo pipeline que un cambio de código.

Consola (clickear)IaC (Terraform)
Quién sabe qué existeTu memoriaEl repositorio
RevisiónNingunaPull Request, línea por línea
Reproducir un ambienteA mano, propenso a errorUn comando, idéntico
Historia de cambiosNo hayEl log de Git
DeshacerAdivinar qué tocastegit revert + apply

Terraform, pieza por pieza

Terraform (de HashiCorp) es la herramienta de IaC más usada. Trabajas con estas piezas, y conviene glosarlas una por una porque son el vocabulario del resto del bloque:

  • HCL (HashiCorp Configuration Language): el lenguaje en el que escribes. No es un lenguaje de programación normal — es declarativo: describes el estado final que quieres (“quiero un bucket llamado así”), no los pasos para llegar. Terraform calcula los pasos.
  • provider (proveedor): el plugin que sabe hablar con una nube concreta. Hay un provider aws, uno google, uno azurerm. Le declaras cuál usas y él traduce tu HCL a llamadas a la API de esa nube.
  • resource (recurso): cada pieza de infraestructura que quieres que exista — un bucket, una base de datos, un servicio. Es el bloque central de todo Terraform.
  • variables: los valores que parametrizas para no hardcodear (la región, el nombre del proyecto). Te dejan reutilizar el mismo código en distintos ambientes.
  • outputs (salidas): los datos que Terraform te devuelve después de crear algo — la URL del servicio, el nombre del bucket. Sirven para conectar piezas o mostrarte el resultado.
  • state (estado): el archivo donde Terraform anota qué existe de verdad. Es la pieza más incomprendida y la más delicada; le dedicamos su propia sección.

El state: lo que Terraform recuerda

Terraform necesita saber qué creó antes para decidir qué cambiar ahora. Eso lo guarda en el state, un archivo (por defecto terraform.tfstate) que es su fuente de verdad: mapea cada resource de tu HCL con el recurso real que existe en la nube.

Cuando corres Terraform, compara tres cosas: lo que dice tu HCL (lo que quieres), lo que dice el state (lo que creíste crear) y lo que existe de verdad en la nube. Si la realidad se desvió del state — alguien clickeó en la consola y cambió algo a mano — eso se llama drift (deriva): la infra real dejó de coincidir con lo que Terraform cree. El plan te lo muestra y quiere corregirlo.

Ojo, esto es lo más importante del módulo: el state jamás va a Git. Contiene, en texto plano, datos sensibles: contraseñas, IPs, a veces secretos. Y si dos personas tienen copias distintas del state, se pisan y corrompen la infra. La solución profesional es un backend remoto (remote backend): guardar el state en un almacenamiento compartido y cifrado — un bucket de S3 o GCS — con un candado (lock) que impide que dos corran apply al mismo tiempo.

El ciclo de vida: init, plan, apply, destroy

Todo Terraform gira sobre cuatro comandos. Este es el ciclo completo, con el state al medio como memoria:

 escribes .tf (HCL)
        │
        ▼
 terraform init      descarga el provider
        │
        ▼
 ┌──────────────────────────────────┐
 │ terraform plan                   │      ┌──────────┐
 │  compara HCL vs state vs nube    │◄─────┤  state   │
 │  y te muestra el diff            │      │ (remoto) │
 └────────────────┬─────────────────┘      └──────────┘
                  ▼                           ▲
 ┌──────────────────────────────────┐         │ escribe
 │ terraform apply                  │         │
 │  ejecuta el plan, crea/cambia    ├─────────┘
 │  la infra real                   │
 └────────────────┬─────────────────┘
                  ▼
              INFRA REAL
  • terraform init — arranca el directorio: descarga el provider que declaraste y configura el backend. Se corre una vez (y de nuevo si cambias providers).
  • terraform plan — el paso de oro: te muestra exactamente qué va a pasar antes de que pase. Qué se crea (+), qué se modifica (~), qué se destruye (-). Nunca cambia nada; solo te enseña el diff. Es el equivalente a revisar un PR de infraestructura.
  • terraform apply — ejecuta el plan. Ahora sí crea, modifica o borra recursos reales, y actualiza el state.
  • terraform destroy — borra todo lo que este código creó. Peligrosísimo y utilísimo: para ambientes efímeros, apagar un demo, o limpiar antes de irte a dormir sin dejar la factura corriendo.
ComandoQué hace¿Toca la nube?
terraform initDescarga provider, configura backendNo
terraform validateRevisa que el HCL sea válidoNo
terraform fmtFormatea el HCL (indentación)No
terraform planMuestra el diff de lo que haríaNo (solo lee)
terraform applyAplica los cambiosSí (crea/modifica/borra)
terraform destroyBorra la infra de este códigoSí (borra)

Un ejemplo mínimo real (AWS)

Para entender el flujo sin la complejidad de GCP todavía, nada mejor que el “hola mundo” de Terraform: crear un bucket de almacenamiento en AWS. Es el recurso más simple que existe y muestra las tres piezas — provider, variable, resource — en su forma pura.

# main.tf
# Declaras qué provider usas y de qué versión. Terraform lo descarga en init.
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
}

# Configuras el provider: en qué región va a operar.
provider "aws" {
  region = var.region
}

# Una variable: la región, parametrizada en vez de hardcodeada.
variable "region" {
  type    = string
  default = "us-east-1"
}

# El resource: un bucket de S3. El primer string es el TIPO de recurso
# (aws_s3_bucket), el segundo es el NOMBRE interno con el que lo referencias.
resource "aws_s3_bucket" "datos_agente" {
  bucket = "brisef-agente-datos-2026"  # nombre global, debe ser único
}

# Un output: te devuelve el nombre del bucket tras crearlo.
output "nombre_bucket" {
  value = aws_s3_bucket.datos_agente.bucket
}

El flujo con estos archivos es literalmente el ciclo de arriba:

terraform init      # descarga el provider aws
terraform plan      # te muestra: + aws_s3_bucket.datos_agente
terraform apply     # crea el bucket de verdad, escribe el state
# ... trabajas ...
terraform destroy   # borra el bucket cuando ya no lo necesitas

Fíjate en el patrón aws_s3_bucket.datos_agente.bucket del output: así se referencia un recurso desde otro. tipo.nombre.atributo. Ese encadenamiento es lo que en el próximo módulo va a conectar el registro de imágenes con el servicio y con los secretos en GCP.

Ojo con el backend: el ejemplo de arriba guarda el state local (en tu carpeta) para que puedas correrlo sin infraestructura previa. En un equipo real, lo primero es agregar un bloque backend "s3" (o backend "gcs") para que el state viva remoto, cifrado y con lock. State local + equipo = corrupción garantizada.

Errores comunes

  • Commitear el state. El error que no perdona: terraform.tfstate en Git filtra secretos y garantiza pisotones entre compañeros. Va al backend remoto y al .gitignore. Siempre.
  • Meter credenciales en el .tf. Las llaves de la nube van en variables de entorno o en el gestor de secretos, nunca escritas en el HCL que subes al repo. Es exactamente el mismo pecado que hardcodear una API key.
  • Correr apply sin leer el plan. El plan existe para que veas el diff antes. Aplicar a ciegas es cómo se borran bases de datos de producción por accidente.
  • Editar la infra a mano en la consola. Genera drift: la realidad se aleja del state y el próximo plan querrá “corregir” tu cambio manual, a veces destruyéndolo. Si usas IaC, usa solo IaC.
  • Confundir declarativo con imperativo. HCL no ejecuta pasos en orden; describe el estado final. No pienses “primero esto, luego esto”; piensa “quiero que exista esto”.

La frase para llevarse

“Con IaC, tu infraestructura deja de ser un recuerdo en la cabeza de alguien y pasa a ser un archivo que se revisa, se versiona y se recrea con un comando.”

Qué viene

Módulo 11, el módulo estrella: el deploy end-to-end en GCP con Terraform y GitHub Actions. Tomamos todo lo de aquí — provider, resources, state, el ciclo plan/apply — y lo aplicamos de verdad: subir la imagen de tu agente a Artifact Registry, correrla en Cloud Run leyendo secretos de Secret Manager, y automatizar todo el despliegue desde un push a main, sin una sola llave JSON de por medio.

Material relacionado

DeployTerraformIaCHCLAWSInfraestructura

Preguntas sobre este curso

Regístrate gratis para hacer preguntas y guardar tu progreso.

✉ Entérate de lo nuevo

Recibe un aviso cuando publique nuevos cursos, workshops o investigaciones. Sin spam.