Terraform para laboratorios reproducibles

Artículo 1 de 7

14%

completado

Cloud e infraestructuraLab note8 min de lectura

Terraform y OpenTofu para laboratorios reproducibles

Base práctica para Terraform y OpenTofu en labs cloud: providers, state, plan, módulos, costos y teardown seguro.

Un laboratorio cloud tiene dos enemigos silenciosos: la configuración manual y el recurso olvidado.

Terraform y OpenTofu atacan ambos, siempre que los usemos con disciplina. No son “el botón mágico de infraestructura”. Son una forma de declarar intención, revisar cambios y repetir un entorno sin rezarle a la memoria.

Terraform define el state como el vínculo entre la configuración y los objetos remotos; OpenTofu conserva el mismo ciclo de escribir, planear y aplicar como contrato operativo.

Piensa en Bash como la capa que valida y orquesta; Terraform/OpenTofu describe y aplica infraestructura. La guía de scripting complementaria permanece en revisión y no es requisito para comenzar esta serie.

Objetivo

Diseñar un flujo mínimo para labs de infraestructura que puedas planificar, aplicar, verificar y destruir sin depender de pasos manuales invisibles. El resultado esperado no es “usar Terraform porque sí”, sino tener un ciclo auditable para crear recursos pequeños y cerrarlos a tiempo.

Prerrequisitos

  • Terraform u OpenTofu instalado localmente.
  • Credenciales cloud explícitas y acotadas al lab.
  • Backend de state decidido: local para pruebas personales, remoto para trabajo colaborativo.
  • Un presupuesto o límite de gasto definido antes de aplicar.
  • Capacidad útil, pero no obligatoria: leer y adaptar un script Bash pequeño.

Puente al lab reproducible

La lectura desemboca en el Terraform lab network. La primera iteración no usa credenciales ni ejecuta apply: valida una allowlist de recursos, ausencia de ingress público, techo de costo y teardown declarado. Esa frontera es intencional. Primero se demuestra que el plan es revisable; después se conecta un provider real.

La evidencia mínima del lab es el JSON de guardrails. Si una futura variante crea recursos, debe sumar plan guardado, costo estimado, outputs verificables y salida de destroy.

Terraform, OpenTofu y la idea central

La idea es simple:

Modelo mental: código declarativo + estado + provider = infraestructura reproducible.

Ciclo mínimo

La evidencia de un lab IaC

El teardown es parte del experimento, no una nota al pie.
  1. Escribirintención y límites en HCL
  2. Validarformato, tipos y providers
  3. Planearpropuesta revisable
  4. Aplicarsolo el plan aprobado
  5. Verificaroutputs y smoke checks
  6. Destruirevidencia de cleanup

Un bloque resource describe una pieza de infraestructura. El provider sabe cómo hablar con AWS, Cloudflare, GitHub u otro sistema. El state recuerda qué existe y cómo se relaciona con el código.

hcl
resource "aws_s3_bucket" "lab" {
  bucket = "trautslab-lab-${var.suffix}"
}

La referencia del bloque resource define el contrato declarativo que el provider interpreta; no es solo sintaxis de ejemplo.

Parece pequeño, pero ahí empieza la diferencia: el bucket ya no vive como memoria tribal; vive como artefacto revisable.

El state es el contrato, no un archivo cualquiera

El terraform.tfstate u homólogo en OpenTofu no es basura generada. Es el mapa entre tu código y la realidad.

Regla de oro:

  • local state para laboratorios personales y efímeros;
  • remote state para trabajo colaborativo;
  • nunca commitear state con secretos o identificadores sensibles;
  • nunca editar state a mano salvo cirugía explícita.

En un lab local:

gitignore
.terraform/
*.tfstate
*.tfstate.backup

Ojo: en una configuración raíz, incluida la de un laboratorio, .terraform.lock.hcl se versiona para revisar la selección y los checksums de providers. No pertenece al mismo grupo que el state ni contiene la infraestructura observada. Una biblioteca de módulos reutilizables puede dejar la selección final al root consumidor, pero este lab es una configuración ejecutable y conserva su lockfile.

Flujo mínimo de laboratorio

Bash
terraform init
terraform fmt -check
terraform validate
terraform plan -out tfplan
terraform apply tfplan
terraform destroy

El plan es el momento donde el humano sigue mandando. Si no entiendes el plan, no apliques. Así de poco glamoroso, así de sano.

Estructura recomendada

Texto
labs/
  terraform/
    s3-minimal/
      main.tf
      variables.tf
      outputs.tf
      versions.tf
      README.md

versions.tf:

hcl
terraform {
  required_version = ">= 1.6.0"
 
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
}

variables.tf:

hcl
variable "region" {
  description = "AWS region for the lab."
  type        = string
  default     = "us-east-1"
}
 
variable "suffix" {
  description = "Unique suffix to avoid bucket name collisions."
  type        = string
}

main.tf:

hcl
provider "aws" {
  region = var.region
}
 
resource "aws_s3_bucket" "lab" {
  bucket = "trautslab-${var.suffix}"
 
  tags = {
    Project = "TrautsLab"
    Lab     = "s3-minimal"
  }
}

outputs.tf:

hcl
output "bucket_name" {
  value = aws_s3_bucket.lab.bucket
}

El wrapper Bash sigue siendo útil

Terraform no reemplaza el preflight. Antes de correr plan, valida contexto.

Bash
#!/usr/bin/env bash
set -Eeuo pipefail
 
LAB_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../labs/terraform/s3-minimal" && pwd)"
 
command -v terraform >/dev/null || {
  echo "Falta terraform u opentofu en PATH"
  exit 1
}
 
[[ -n "${AWS_PROFILE:-}" ]] || {
  echo "Define AWS_PROFILE antes de ejecutar el lab"
  exit 1
}
 
cd "${LAB_DIR}"
terraform init
terraform fmt -check
terraform validate
terraform plan -out tfplan

El wrapper no decide infraestructura. Solo prepara una pista limpia.

Módulos: no empieces por ahí

Los módulos son útiles cuando ya repetiste un patrón dos o tres veces. Antes de eso, pueden esconder malas decisiones detrás de una interfaz bonita.

Empieza plano:

Texto
main.tf
variables.tf
outputs.tf

Luego extrae:

Texto
modules/
  s3-lab-bucket/

Un buen módulo tiene pocas variables, outputs claros y nombres aburridos.

Cost guardrails

Todo lab debe responder:

  • ¿qué crea?;
  • ¿cuánto podría costar?;
  • ¿cómo se destruye?;
  • ¿qué pasa si falla a mitad?;
  • ¿qué nombres/tags deja para encontrar recursos?

Tags mínimos:

hcl
locals {
  common_tags = {
    Project = "TrautsLab"
    Owner   = "lab"
    TTL     = "24h"
  }
}

No todos los servicios respetan tags igual, pero etiquetar es el inicio de una salida digna.

Terraform vs OpenTofu

Para TrautsLab, la regla será práctica:

  • escribir HCL portable cuando sea razonable;
  • no depender de features raras sin explicar por qué;
  • nombrar el runtime usado en cada lab;
  • validar comandos con el binario real (terraform u tofu).

En los posts podemos mostrar Terraform como lenguaje común y mencionar OpenTofu cuando el flujo aplica igual. Si una diferencia importa, se documenta ahí mismo. Nada de “es lo mismo” con la mano en el aire.

Cuándo no usarlo

No uses Terraform/OpenTofu para:

  • scripts de una sola ejecución sin estado;
  • cambios que requieren lógica imperativa compleja;
  • datos transaccionales;
  • operaciones que debes ejecutar muchas veces por minuto;
  • esconder una arquitectura que todavía no entiendes.

Para eso existen Bash, SDKs, pipelines o aplicaciones. Cada herramienta con su sombrero; si no, terminamos con una navaja suiza intentando hacer café.

Validar el lab

Antes de publicar o compartir un lab IaC, valida cuatro señales:

Bash
terraform fmt -check
terraform validate
terraform plan -out tfplan
terraform show -no-color tfplan

Criterios de aceptación:

  • el plan no crea recursos fuera del alcance declarado;
  • los nombres incluyen prefijo/sufijo de lab para evitar colisiones;
  • los outputs permiten ejecutar un smoke test;
  • el README explica cómo correr destroy;
  • el costo esperado está escrito, aunque sea aproximado.

Fuentes útiles

Conexiones dentro de la serie

  • Después: State, backends y locking.
  • Ruta completa: continúa con módulos, providers, testing, CI/CD y recuperación operacional antes de convertir estos fundamentos en automatización de producción.

Cierre

Terraform/OpenTofu no nos interesa por “automatizar clicks”. Nos interesa porque convierte laboratorios en artefactos revisables: código, plan, estado, teardown y evidencia.

El estándar TrautsLab será ese: si un lab crea algo, también debe explicar cómo lo valida y cómo lo borra. La nube perdona poco; la factura, menos.

Referencias

Bibliografía académica

Formato IEEENumerado para ingeniería, sistemas y protocolos.
  1. [1]

    HashiCorp, "State," Terraform Language Documentation.

    official docsID: TF-STATE🔗 Abrir fuente

    Propósito y protección del state.

  2. [2]

    OpenTofu, "Working with OpenTofu."

    official docsID: TOFU-WORKFLOW🔗 Abrir fuente

    Write–Plan–Apply para individuos y equipos.

  3. [3]

    HashiCorp, "Resource block reference," Terraform Language Documentation.

    official docsID: TF-RESOURCE🔗 Abrir fuente

    Semántica de recursos declarados.

  4. [4]

    HashiCorp, "Dependency Lock File," Terraform Language Documentation.

    official docsID: TF-LOCKFILE🔗 Abrir fuente

    Selección y checksums de providers revisables en el root module.

Fuentes primarias, papers seminales y especificaciones técnicas citadas en esta investigación.

Rutas vecinas

Si este tema te abrió hambre, sigue por aquí.

Series y labs que comparten área o dependen de esta ruta. Pocas opciones, para no convertir la curiosidad en menú infinito.

Sigue leyendo

Ideas conectadas con este artículo

Una ruta corta para continuar sin abrir veinte pestañas y perder el hilo.