Saltar al contenido

Terraform Plan Summarizer · IaC

Sumarizador de planes de Terraform — lee el plan antes de aplicarlo

Pega la salida de terraform plan —color ANSI y CRLF de un log de CI incluidos— o de terraform show -json tfplan. Los adds, changes, destroys y replacements se cuentan como cuatro cifras separadas, cada atributo forces replacement se nombra en el recurso al que pertenece, y todo lo destructivo que toque una base de datos, un NAT gateway o un control plane de clúster se sube arriba. Después los totales se comprueban contra la propia línea de resumen de Terraform — porque un lector de planes que se desvía en silencio es peor que ninguno.

Se ejecuta en tu navegador: nada de lo que pegas sale de esta página. Cómo lo demostramos

Funciona en tu navegador Cifras comprobadas Sin subidas ni registro Actualizado el 3 ago 2026

Playground del sumarizador de planes de Terraform

Examples

Both formats work and the format is detected for you: the human-readable terraform plan transcript (ANSI colour codes and CRLF from a CI log are fine) or terraform show -json tfplan. Up to 2 MiB — roughly a 50,000-line plan. It stays in this tab: there is no server here to send it to, which matters, because plan output is full of account IDs, ARNs, CIDRs and policy JSON.

Results update as you type — press Enter to run now.

Grouping

By action puts replacements and destroys first, because those are the ones that can take something down. By module follows the code instead, which is what you want when one module call is the thing under review.

Result

Paste a plan to see adds, changes, destroys and replacements counted separately, the replacement-forcing attributes named, and the totals cross-checked against Terraform’s own summary line.

El hueco

El -/+ que importa está en la línea 310.

Un plan real son miles de líneas de diff de atributos, y la parte que puede tirar producción mide tres caracteres. Revisar uno en un pull request es recorrer un log de CI plegado buscando un -/+ entre cientos de cambios de etiqueta ~, y luego seguir bajando para encontrar el comentario # forces replacement que dice qué atributo lo provocó. El resumen del final no ayuda: 2 to add se lee como dos cosas nuevas, cuando una de ellas es tu base de datos destruida y reconstruida.

Así que la gente pega el plan en un chatbot. Es la peor opción disponible, y por dos motivos. Primero, exfiltración: la salida de un plan lleva IDs de cuenta, ARNs, rangos de subred y CIDR, documentos de política IAM, reglas de security group y nombres DNS internos —un documento con la forma de tu red que nunca adjuntarías a un ticket, entregado a un tercero y, en los planes de consumo, a los datos de entrenamiento—. Segundo, exactitud: un modelo de lenguaje que lee un plan hace reconocimiento de patrones sobre texto. Atribuye un comentario forces replacement al recurso equivocado, se salta recursos en silencio cuando el pegado está cortado y suma con aplomo cifras que nunca contó.

Esta página es la versión con datos de verdad de esa misma pregunta, y es deliberada justamente en lo que una respuesta de IA no puede darte: una declaración de cuánto no sabe. La salida legible de Terraform no es una interfaz estable, así que la lista de recursos parseada se suma y se compara con la propia línea Plan: de Terraform cada vez. Cuando coinciden, lo dice. Cuando no —que es el aspecto de un pegado de CI cortado— nombra las dos cifras y te dice que la de Terraform es la buena. El sexto chip de ejemplo es exactamente ese caso: un log de GitHub Actions cuyo centro plegó el visor, donde la línea de Terraform reporta 4 to add, 3 to change y 2 to destroy y solo 2, 1 y 1 sobrevivieron a la copia.

¿Estás revisando la pipeline que ejecuta el plan y no el plan? El validador de GitHub Actions y el validador de GitLab CI revisan el workflow, y el comprobador de .env.example encuentra las variables que se le olvidó pasar.

La tubería

Cómo funciona.

Cinco pasos deterministas, todos dentro de tu pestaña — dos parsers detrás de un único punto de entrada que autodetecta, y una comprobación cruzada que convierte un formato de entrada inestable en una respuesta honesta.

  1. Detectar el formato, y decirlo cuando el fichero es otro.

    JSON o texto se decide por el primer carácter y por las claves presentes. Un volcado de estado, un resultado de terraform validate -json o un JSON cortado a mitad de array reciben cada uno su nombre, con el comando que produce un plan de verdad — nunca un «entrada no válida» a secas.

  2. Quitar ANSI, normalizar los finales de línea.

    Un plan copiado de GitHub Actions, GitLab o Jenkins llega envuelto en escapes de color y finales CRLF. Ambos se eliminan antes de parsear nada, así que un pegado de CI y uno de terminal dan una salida idéntica. La entrada está limitada a 2.097.152 caracteres: 2 MiB, más o menos un plan de 50.000 líneas.

  3. Leer los recursos, no el diff.

    Cada línea de cabecera «# <dirección> …» lleva la ruta de módulo y el índice, así que es la fuente de verdad para la dirección; la línea de símbolo de debajo aporta el orden de la sustitución. Dentro de cada bloque solo se buscan tres cosas: «# forces replacement», «(sensitive value)» y la razón «(because …)» que da Terraform, que se conserva literal.

  4. Ordenar por lo que se rompe, no por lo que cambia.

    Una tabla de 17 patrones de tipo de recurso en cuatro clases —almacén de datos, ruta de salida, control plane, clave de cifrado— marca solo acciones destructivas, con una frase que nombra qué desaparece concretamente: los datos, la IP pública de salida, los kubeconfig. Un tipo que no está en la tabla queda sin clasificar, y la página lo dice en lugar de insinuar que es seguro.

  5. Comprobar el total y negarse a equivocarse con seguridad.

    La lista parseada se suma a la manera de Terraform —cada sustitución cuenta una vez como add y una vez como destroy— y se compara con la línea «Plan:». La coincidencia se declara. La discrepancia es un aviso que nombra las dos cifras y dice que confíes en Terraform. Aquí nada adivina en silencio.

Referencia

Todos los símbolos que un plan puede imprimir.

Nueve glifos y anotaciones cargan con todo el significado de un plan. Seis son acciones, tres son notas sobre un valor — y dos de las seis solo se diferencian en el orden de dos operaciones, que es la diferencia entre un cambio progresivo y una caída.

Símbolo Qué significa
+ create Un objeto nuevo. Todavía no existe nada, así que la mayoría de sus atributos leen (known after apply).
~ update in-place El objeto existente se modifica. El id sobrevive, y también todo lo guardado en él.
- destroy El objeto se borra y no se recrea. Busca la línea (because …): ahí está el motivo.
-/+ destroy then create Una sustitución, primero el objeto viejo. Hay una ventana en la que no hay nada — el caso por defecto, y el que hay que leer con cuidado.
+/- create then destroy Una sustitución con create_before_destroy = true. El objeto nuevo existe antes de que el viejo se vaya.
<= read during apply Una data source que no se puede resolver en tiempo de plan. Nunca forma parte de add, change ni destroy.
# forces replacement anotación de atributo Este atributo no puede cambiar en el sitio, así que se sustituye el objeto entero. El único comentario que merece un grep.
(known after apply) anotación de valor El proveedor lo asigna al crear, así que de verdad todavía no existe. No es un error.
(sensitive value) anotación de valor Marcado como sensible, y el plan lo oculta. Ojo: en el fichero de estado sigue estando en claro.

Por qué una sustitución se cuenta dos veces

Terraform cuenta operaciones. Esta página cuenta recursos, e imprime las cifras de Terraform al lado para que ninguna se confunda con la otra.

replace-math.txt
Plan: 2 to add, 0 to change, 1 to destroy.

  what Terraform counted            what actually happens
  ────────────────────────          ─────────────────────
  + aws_iam_role.app                one NEW role
  -/+ aws_db_instance.primary       one database replaced
        counted as +1 add
        counted as +1 destroy

  this page shows them apart:
    + add      1   created outright
    ~ change   0   updated in place
    − destroy  0   destroyed outright
    ± replace  1   destroyed and recreated

Conseguir el fichero correcto

show -json contra un plan guardado es la entrada fiable; la transcripción de texto es la que ya tienes. Dos casi-aciertos se reconocen y se nombran.

get-a-plan.sh
# The reliable path: save the plan, then read the machine format
terraform plan -out=tfplan
terraform show -json tfplan > plan.json     # paste plan.json above

# The path you already have: the text a pipeline printed
terraform plan -no-color                    # -no-color if you can; ANSI is fine either way

# What NOT to paste — both are told apart from a plan and named
terraform show -json                        # this is STATE, it has no resource_changes
terraform validate -json                    # this is a config check, not a plan

Siguiente paso

El plan está bien. Ahora revisa la pipeline que lo ejecuta.

Un plan solo es tan fiable como el workflow que lo produjo: el validador de GitHub Actions y el validador de GitLab CI atrapan los errores de pipeline que hacen que un plan corra contra el estado o las credenciales equivocadas, y el comprobador de .env.example encuentra la variable que tu job nunca pasó. Todos, como esta página, se ejecutan por completo en tu navegador.

plan-summary.txt
+ add 1   ~ change 1   − destroy 0   ± replace 1

read this first — 1 high blast radius
  module.data.aws_db_instance.primary      data store
    forces replacement: engine_version
    destroy then create — the database does not exist in between

cross-check: reconciles
  Terraform printed: Plan: 2 to add, 1 to change, 1 to destroy.
  (the replacement is one of those adds AND the destroy)

FAQ

Tus preguntas, respondidas.

Toca una pregunta para desplegar la respuesta.

Los dos, y detecta cuál has pegado. El primero es la transcripción legible que imprime Terraform —la de +, ~, - y -/+ en el margen izquierdo— incluidos los códigos de color ANSI y los finales de línea CRLF que salen al copiar un log de CI. El segundo es terraform show -json tfplan, el formato de máquina, que lleva resource_changes, replace_paths, action_reason y output_changes y es una interfaz documentada y versionada. El JSON es más fiable y es lo que conviene usar si puedes guardar un fichero de plan; el texto es lo que de verdad tienes cuando la pipeline ya se ha ejecutado. Lo que NO acepta es terraform show -json de tu estado, ni la salida de terraform validate -json: son confusiones habituales, y en ambos casos se te dice qué son y qué comando produce lo correcto.

El orden de las dos operaciones, y eso decide si hay caída de servicio. -/+ significa destruir y luego crear: el objeto viejo desaparece antes de que exista el nuevo, así que todo lo que dependa de él queda roto durante ese hueco —segundos para una regla de security group, veinte minutos para una instancia RDS—. +/- significa crear y luego destruir, que es exactamente lo que compra lifecycle { create_before_destroy = true }: el reemplazo se construye y solo después se elimina el objeto antiguo. Terraform elige destruir-primero por defecto, así que +/- solo aparece donde alguien lo ha pedido. Esta página escribe los dos órdenes con palabras en cada fila de sustitución, en lugar de hacerte descifrar un glifo de tres caracteres.

Marca el atributo concreto cuyo cambio no se puede aplicar en el sitio, de modo que el proveedor tiene que borrar el objeto y construir uno nuevo. Es por atributo, y ahí está lo útil: engine_version en un aws_db_instance es una actualización real que querías hacer, mientras que availability_zone o name cambiando por accidente —por una variable renombrada, una etiqueta reformateada, un valor por defecto del proveedor que se movió— es la sustitución sorpresa clásica. Esta página extrae cada uno de esos nombres de atributo del bloque al que pertenece y los muestra como chips en la fila de ese recurso, para que nunca tengas que recorrer un diff de 400 líneas buscando el comentario.

Porque Terraform cuenta operaciones, no recursos, y una sustitución son dos operaciones. Así que un plan con un create simple y una sustitución imprime «Plan: 2 to add, 0 to change, 1 to destroy»: la sustitución contribuye a las dos cifras. Es correcto, y es también la línea peor leída de toda la salida de Terraform, porque «2 to add» suena a dos cosas nuevas. Esta página muestra en cambio cuatro tarjetas disjuntas: add es creado directamente, replace es destruido y recreado, y nada se cuenta dos veces. La contabilidad propia de Terraform se imprime debajo, literal, para poder comparar las dos en lugar de confundirlas.

Sí, y por eso esta página existe con esta forma. No hay servidor detrás: el parser es JavaScript que se carga en tu pestaña y se ejecuta ahí, así que el plan nunca sale de tu máquina —puedes comprobarlo en la pestaña de red del navegador, o cargando la página y desconectándote después—. Eso importa más con la salida de un plan que con casi cualquier otra cosa que pegarías en una herramienta web: un plan está lleno de IDs de cuenta, ARNs, rangos de subred y CIDR, documentos de política IAM, reglas de security group y nombres DNS internos. Pegar uno en un chatbot entrega todo eso a un tercero y, en los planes de consumo de la mayoría de asistentes, a los datos de entrenamiento.

Significa que los recursos que esta página ha podido leer no suman los totales de la propia línea de resumen de Terraform, y nueve de cada diez veces el pegado está incompleto: un visor de logs de CI plegó el centro, un búfer de scrollback lo cortó, o la copia empezó a mitad. El aviso nombra los dos conjuntos de cifras y te dice que confíes en Terraform. La razón de que exista es que la salida legible de Terraform no es explícitamente una interfaz estable, así que un parser de texto acabará desviándose con algún cambio de formato —y un sumarizador que se desvía en silencio imprimiría un total erróneo con seguridad, lo cual es peor que no imprimir nada—. Esa comprobación cruzada es lo que hace defendible parsear un formato inestable.

Significa que el valor todavía no existe. Atributos como un ARN, un id, un nombre DNS generado o una dirección IP los asigna el proveedor al crear el objeto, así que en tiempo de plan Terraform de verdad no los conoce y se niega a adivinarlos. No es un error ni un aviso: un plan de algo nuevo está lleno de ellos. Sí tiene una consecuencia práctica: un recurso cuya entrada depende de un valor desconocido tampoco puede evaluarse por completo, y por eso a veces ves una data source marcada como «read during apply» en lugar de resuelta, y por eso un apply puede acabar haciendo más de lo que mostraba el plan.

Sí. OpenTofu se bifurcó de Terraform 1.5.x y conservó los dos formatos de salida: la transcripción de texto usa los mismos símbolos y la misma línea «Plan: N to add, N to change, N to destroy», y tofu show -json emite la misma familia de format_version con la misma forma de resource_changes. Todo lo de esta página se aplica sin cambios, y la línea de versión se lee según el producto que la imprimió. Lo mismo vale para los envoltorios que pasan la salida de Terraform tal cual —Terragrunt, Atlantis, Spacelift— siempre que el texto del plan esté intacto.

La ruta JSON está escrita contra format_version 0.1 a 1.x, que abarca de Terraform 0.12 a 1.9 y el OpenTofu actual; un documento con una versión major desconocida se acepta pero lleva un aviso, porque un campo renombrado produciría ceros en silencio. La ruta de texto está probada contra las formas de 1.5 en adelante, que es donde «N to import» se sumó a la línea de resumen y donde aparecen los bloques moved e import; la salida más antigua se parsea en su mayoría, y lo que no, lo atrapa la comprobación cruzada de cifras en lugar de reportarse como un hecho. Lo único que esta página nunca hará es estimar costes: los precios se quedan obsoletos, y una cifra obsoleta impresa con seguridad es justo el tipo de respuesta que este sitio existe para reemplazar.

More free, private DevOps tools.

El sumarizador de planes de Terraform es una de las herramientas de OpsCanopy — una copa creciente de validadores, convertidores y testers basados en el navegador que nunca tocan un servidor.

39 herramientas gratuitas, todas pueden funcionar sin conexión — opscanopy.com funciona sin registro y sin subir nada.

Herramientas de infraestructura relacionadas: el convertidor de docker run a Compose, el comprobador de .env.example para las variables que un despliegue olvidó, y los validadores de GitHub Actions y GitLab CI para la pipeline que ejecuta tu plan — o explora el directorio completo de herramientas.

Se ofrece tal cual, por comodidad. Sin afiliación con HashiCorp. Esta página resume lo que dice un plan; no estima costes y no lo hará — los precios se quedan obsoletos, y una cifra obsoleta impresa con seguridad es la única respuesta que una herramienta de datos de verdad no puede dar. Un tipo de recurso ausente de la tabla de radio de impacto está sin clasificar, no demostrado como seguro. OpsCanopy es libre y gratuito.