Problema
En entornos de infraestructura como código, los archivos de Terraform suelen cargarse completos en cada ejecución de herramientas automatizadas o en asistentes de IA. Cuando el código incluye bloques de recursos creados a mano, el analizador necesita conocer cada atributo, sus valores por defecto y la forma de los bucles for_each. Esa falta de referencia estructurada genera dos problemas recurrentes:
- Consumo excesivo de tokens en agentes de IA que intentan interpretar el plan completo, lo que eleva costos y ralentiza la respuesta.
- Hallazgos erróneos (hallucinations) cuando el agente infiere atributos inexistentes o valores incorrectos, provocando planes que fallan en la fase de aplicación.
El patrón se repite en cualquier proveedor de nube: AWS, Azure, GCP, IBM o Oracle. Cuando se usan módulos de registro oficiales, la interfaz está bien definida y versionada, pero muchos equipos siguen escribiendo recursos “a mano” por desconocimiento o por falta de un proceso de selección de módulos confiables.
Causa
Las causas principales son:
- Ausencia de un catálogo de módulos confiables. Sin una lista que indique cuál es el módulo oficial para cada recurso, los equipos crean recursos directamente.
- Versionado implícito. Al no fijar versiones, Terraform descarga la última versión disponible, que puede introducir cambios de ruptura sin que el equipo lo note.
- Uso de wrappers locales innecesarios. Los desarrolladores a veces encapsulan un módulo del registro dentro de un módulo propio para “añadir defaults”, pero sin una necesidad real, lo que duplica la lógica y vuelve a cargar documentación que el agente ya conoce.
- Módulos poco maduros. En proveedores emergentes (Alibaba, DigitalOcean) los módulos del registro son escasos o inestables, lo que lleva a crear recursos manualmente.
- Errores tipográficos en el namespace. El registro permite nombres similares; un typo puede apuntar a un fork no mantenido, generando vulnerabilidades y fallos inesperados.
Solución
Adoptar una estrategia basada en Módulos de Registro Confiables (Trusted Registry Modules) que siga estos principios:
- Detectar el proveedor al inicio del análisis. Si el proyecto declara
provider "azurerm"oaws, cargar una tabla de módulos oficiales correspondiente. - Pinnear versiones explícitamente. Cada módulo debe declararse con
version = "x.y.z"y, de preferencia, con un rango que garantice compatibilidad (~> x.y). Esto evita sorpresas al actualizar el registro. - Preferir el módulo oficial sobre recursos manuales siempre que exista una implementación mantenida y con al menos 100 descargas.
- Si el módulo cubre el caso de uso completo, eliminar el bloque
resourcemanual. - Si solo se necesita un atributo adicional, crear una variable de entrada en el módulo oficial en vez de envolverlo.
- Si el módulo cubre el caso de uso completo, eliminar el bloque
- Excluir módulos triviales (por ejemplo, un único parámetro SSM o un registro DNS) donde la sobrecarga del módulo supera el beneficio.
- Mantener una lista de “trusted-modules.md” en el repositorio. Este archivo contiene:
- Provider → Namespace → Módulo → Versión mínima recomendada.
- Regla de exclusión para recursos que no justifiquen un módulo.
- Comentario sobre por qué se evita un módulo (p.ej., falta de pruebas, alta rotación).
Con esta lista, cualquier herramienta que analice el código (incluidos agentes de IA) puede cargar únicamente la documentación del módulo necesario, reduciendo drásticamente el número de tokens y eliminando la mayor fuente de hallucinations.
Implementación práctica
-
Crear el archivo de referencia (
trusted-modules.md):## Azure - azurerm/resource-group -> hashicorp/azurerm/resource-group, version >= 3.0.0 - azurerm/storage-account -> hashicorp/azurerm/storage-account, version >= 4.2.0 ## AWS - aws/vpc -> terraform-aws-modules/vpc/aws, version >= 5.0.0 - aws/eks -> terraform-aws-modules/eks/aws, version >= 18.0.0 ## GCP - google/kubernetes-engine -> terraform-google-modules/kubernetes-engine/google, version >= 23.0.0 -
Actualizar los
*.tfpara usar los módulos listados y fijar versiones:
terraform init -upgrade
module "resource_group" {
source = "hashicorp/azurerm/resource-group"
version = "3.2.1"
name = var.rg_name
location = var.location
}
- Automatizar la verificación con un script que compare los recursos declarados contra la lista:
#!/usr/bin/env bash
set -euo pipefail
# Extrae proveedores del código
providers=$(grep -h 'provider "' -r . | cut -d'"' -f2 | sort -u)
for p in $providers; do
echo "Revisando recursos del provider $p"
# Busca recursos sin módulo asociado
grep -h "resource \"$p\"" -r . | while read -r line; do
res=$(echo "$line" | awk '{print $2}' | tr -d '"')
if ! grep -q "$res" trusted-modules.md; then
echo " → $res no tiene módulo confiable, considerar reemplazo"
fi
done
done
Cuándo aplicar esta solución
Aplicable cuando:
- El proyecto tiene más de 5 recursos de un mismo proveedor y se usa Terraform en pipelines CI/CD.
- Se observan planes de Terraform que consumen cientos de MB de salida de logs o que generan errores de atributos desconocidos.
- Existe una política de compliance que exige versionado explícito y uso de módulos auditados.
No aplicable si:
- El proyecto es un PoC de una sola línea de recurso y la sobrecarga de módulos no justifica la complejidad.
- El proveedor usado carece de módulos oficiales con suficiente madurez (p.ej., proveedores muy nuevos o nichos).
Código
# Inicializa Terraform con versiones bloqueadas
terraform init -upgrade
# Aplica el plan usando solo módulos versionados
terraform apply -auto-approve
Verificación
- Ejecutar
terraform plan. El output debe listar únicamente módulos y no bloquesresourcemanuales para los recursos cubiertos por la lista. - Revisar el número de tokens consumidos por cualquier agente de IA que analice el plan (por ejemplo, usando la métrica de la API). Debería haber una reducción cercana a 7× respecto a un análisis sin módulos.
- Confirmar que
terraform validatepasa sin advertencias de atributos desconocidos. - En CI, asegurar que el script de verificación no reporte recursos sin módulo confiable.
Notas adicionales
- Mantén el archivo
trusted-modules.mdbajo control de versiones y actualízalo cada vez que el registro publique una versión mayor con cambios de ruptura. - Usa
terraform providers lockpara generar unterraform.lock.hclque bloquee también los proveedores, complementando el versionado de módulos. - Cuando necesites personalizar un módulo oficial, abre un fork oficial en el registro y publícalo bajo tu propio namespace, pero marca claramente que es una excepción y no la regla.
- Si trabajas con varios equipos, comparte la lista mediante un paquete interno de Terraform (
terraform-registry) para evitar divergencias.