Toda la configuración de Better Stack — páginas de estado, monitores, heartbeats, labels
de logs, dashboards y alertas — se declara como código bajo
infra/betterstack/. La UI nunca es la fuente de verdad; Terraform lo es.Por qué infraestructura como código
Configurar docenas de monitores, secciones y alertas a mano no escala y deriva silenciosamente entre entornos. Terraform nos da:Cómo piensa Terraform
Terraform reconcilia continuamente tres imágenes del mundo. Entender esto es la clave para todo lo demás en esta página:- Config declarada — lo que los archivos
.tfy los manifiestos de adopción dicen que debería existir. - Estado rastreado (
terraform.tfstate) — el inventario de Terraform de lo que ya gestiona, incluyendo el id de Better Stack de cada recurso. - Mundo real — lo que la API de Better Stack devuelve en este momento.
plan vs apply — la distinción central
Este es el concepto que cada operador debe internalizar. La analogía más simple:
plan es el diff, apply es el commit.
terraform plan — dry run, solo lectura
Refresca el estado desde la API de Better Stack, lo compara con la config
declarada, e imprime las acciones que tomaría:
+ create, ~ update,
- destroy. No cambia nada. Un plan que muestra
0 to add, 0 to change, 0 to destroy prueba que no hay drift.terraform apply — ejecuta el cambio
Toma ese mismo diff y ejecuta las llamadas reales a la API (POST / PATCH / DELETE),
luego escribe los ids resultantes de vuelta en el tfstate. Esta es la única
operación que muta la infraestructura.
Nunca haces
apply sin leer primero el plan. En CI el plan se imprime
en el log del job y apply requiere adicionalmente escribir APPLY — consulta
CI/CD para el monitoreo.Un tercer verbo: import (adopción)
Cuando un recurso ya existe en Better Stack (creado a mano antes de que Terraform
lo gestionara), import lo adjunta al estado sin recrearlo. Así
es como se adoptaron los monitores existentes: el primer apply en development
importó 68 recursos, y el plan de seguimiento reportó 0 cambios.
Idempotencia — por qué reejecutar es seguro
Terraform es declarativo: aplicar la misma config dos veces no duplica nada, siempre que el estado se preserve.Layout del repositorio
Providers
Manifiestos de adopción
Cada entorno converge al mismo catálogo — 31 monitores (12 API, incluyendo el journey transversal Digital Contract, + 9 integraciones + 10 plataformas), 4 secciones y 3 heartbeats — cada uno apuntando a sus propios hosts. El manifiestoadopted/<env>.json es el estado
deseado; después de la adopción lo editas vía PR. El generador sintetiza entradas
que aún no existen (con monitor_id = null) para que Terraform las cree en el
apply en lugar de importarlas.
Regenera solo para auditar el drift, y revisa siempre el diff antes de hacer commit:
Estado por entorno (workspaces)
El estado se aísla por entorno usando workspaces de Terraform: el nombre del workspace es igual al nombre del entorno, así que development, certification y production mantienen cada uno un estado independiente bajo el prefijoenv:/ del backend.
TF_BACKEND_OVERRIDE para que el
workflow lo escriba antes de terraform init.
Ejecutarlo localmente
terraform-apply.sh envuelve init + selección de workspace + plan/apply, y
carga los tokens automáticamente desde backend/horizon-api/.env.<env> (mapeando
BETTERSTACK_UPTIME_API_TOKEN al BETTERUPTIME_API_TOKEN del provider).
destroy está deliberadamente protegido: requiere CONFIRM_DESTROY=<env> para que
nunca pueda ejecutarse por accidente.Outputs
Después delapply, Terraform expone:
status_page_resources_json— el mapa scope de componente → id de recurso de la página de estado usado para llenarBETTERSTACK_STATUS_PAGE_RESOURCES.uptime_heartbeat_ids— los tres ids de heartbeat de cron.
Código relacionado
- Análisis profundo de IaC:
docs/initiatives/betterstack/06-terraform-iac.md - README del módulo:
infra/betterstack/README.md - Script del runner:
scripts/status-monitoring/terraform-apply.sh