Módulo 1: Why Cicd And Gitops

2. El problema del `apply` manual

Descripción

En terraform-and-iac-guide corriste terraform apply decenas de veces. Funcionó, cada vez. El proyecto andes-cargo-infra/ existe, correcto y probado. Pero hay tres preguntas que esa guía nunca te obligó a responder, porque no eran su tema: ¿quién corrió ese apply? ¿con qué credenciales, en qué máquina? ¿y qué pasa si esa persona, un día, no está? Esta lección responde esas tres preguntas con toda la honestidad posible, y después revisita —desde un ángulo nuevo— el caso de estudio más duro de la guía anterior: el terraform destroy que un agente de IA corrió contra producción real, con el humano aprobando el plan que ya había señalado el riesgo.

Conexión con el módulo

Esta es la lección que justifica el resto de la guía, igual que la lección 2 de terraform-and-iac-guide justificó esa guía completa. No vas a instalar nada todavía —eso empieza en la lección 6—, y no vas a definir todavía qué es "CI" o "CD" con precisión —eso es la lección 3—. Lo único que hace esta lección es nombrar el dolor real de tener un humano como el único paso entre el código y la infraestructura, con evidencia de tu propia experiencia y con el incidente más citado de esta guía hermana.


Analogía: el cheque en blanco

Imagina que, en tu trabajo, cada vez que hace falta pagar algo, alguien del equipo firma un cheque en blanco y confía en que la persona que lo complete después escriba el monto correcto. No hay una segunda firma. No hay un registro de quién decidió que ese pago era necesario, ni de quién revisó el monto antes de que el cheque saliera del banco. Si el monto está mal —por error, por apuro, o porque nadie miró con suficiente atención— el dinero ya salió antes de que alguien más pudiera decir "espera, revisa esto de nuevo".

Eso es, con precisión, lo que es un terraform apply corrido a mano, sin ningún proceso alrededor. No importa qué tan bueno seas leyendo un plan —y en terraform-and-iac-guide aprendiste a leerlo con atención—: mientras la única persona que revisa el cambio sea la misma persona que lo aplica, no hay ninguna segunda firma. El cheque se cobra en el instante en que se firma.


Tres preguntas que terraform-and-iac-guide nunca te obligó a responder

1. ¿Quién corrió el apply?

Piensa en el andes-cargo-infra/ que ya tienes. Cada apply que corriste dejó, sí, un rastro en el state —qué recursos existen, con qué configuración—, pero ningún rastro de quién decidió aplicarlo, cuándo, ni por qué. Si mañana un compañero de equipo te pregunta "¿quién aprobó el cambio que agregó esa política al bucket la semana pasada?", la única respuesta honesta con Terraform corrido a mano es: quien tenga acceso a la terminal donde corrió ese comando, si es que alguien se acuerda. No hay un registro estructurado, buscable, que una auditoría de seguridad —o simplemente un compañero curioso— pueda consultar.

2. ¿Con qué credenciales, en qué máquina?

En esta guía, contra LocalStack, tus credenciales son test/test — dummy, sin ningún riesgo real. Pero piensa en lo que ese mismo flujo significaría contra una cuenta de AWS real: para que terraform apply funcione desde tu laptop, tu laptop necesita credenciales de AWS con permiso para crear, modificar y borrar la infraestructura que declara andes-cargo-infra/ — típicamente una clave de acceso de larga vida (AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY), guardada en ~/.aws/credentials o exportada como variable de entorno. Esa credencial vive, entonces, en tu computadora personal: en tu disco, en tu historial de shell si alguna vez la exportaste a mano, potencialmente en un volcado de memoria si tu máquina se compromete. Es exactamente el antipatrón que la auditoría de mercado de este ecosistema marca como el hueco de seguridad más citado de la competencia —y la razón por la que el Módulo 4 completo de esta guía existe.

3. ¿Qué pasa si esa persona no está?

Esta es la pregunta más incómoda, y la más real. Si la única persona que sabe correr terraform apply sobre andes-cargo-infra/ —la única con las credenciales configuradas, la única familiarizada con el proyecto— está de vacaciones, renunció, o simplemente no responde el teléfono un sábado a la madrugada cuando algo se rompe, ¿quién aplica el cambio urgente? Con un apply manual, la respuesta depende enteramente de que el conocimiento y el acceso estén distribuidos correctamente entre el equipo — algo que, en la práctica, rara vez sucede sin un proceso que lo obligue.


Los cuatro problemas, ahora con un humano en el medio

terraform-and-iac-guide (lección 2) ya nombró cuatro problemas de la infraestructura imperativa — comandos sueltos, sin ningún artefacto declarativo. Esos problemas los resolvió Terraform: ahora tienes un archivo que describe qué debería existir. Pero declarar la infraestructura en HCL no resuelve, por sí solo, el problema de quién decide cuándo ese HCL se vuelve realidad:

   CUATRO PROBLEMAS QUE TERRAFORM SOLO, SIN UN PIPELINE, NO RESUELVE

   1. Sin revisión obligatoria
      Terraform te muestra el plan. Nada te obliga a que OTRA
      persona también lo lea antes de que apruebes tu propio apply.

   2. Sin registro de aprobación
      El state dice QUÉ existe. No dice QUIÉN decidió que debía
      existir, ni cuándo lo aprobó, ni con qué justificación.

   3. Sin control de quién puede aplicar
      Si la credencial vive en tu laptop, cualquiera con acceso a
      tu laptop puede correr apply — sin importar si debería o no.

   4. Sin punto único de bloqueo
      Nada impide que dos personas corran apply casi al mismo
      tiempo, cada una desde su propia terminal, con su propia
      copia del state — el mismo riesgo de lock que ya viste en
      terraform-and-iac-guide, ahora multiplicado por "cuántas
      laptops distintas pueden tocar main sin coordinarse".

Fíjate en algo importante: ninguno de estos cuatro problemas es un defecto de Terraform. Terraform hace exactamente lo que promete: calcula un plan, lo aplica si se lo pides. El problema vive fuera de Terraform, en el proceso —o la ausencia de proceso— que rodea a quien decide teclear apply.


El caso de estudio, revisitado desde un ángulo nuevo

terraform-and-iac-guide (Módulo 8) documentó, con evidencia verificable, el incidente de marzo de 2026 donde Claude Code corrió terraform destroy contra la infraestructura de producción de DataTalks.Club (Alexey Grigorev), después de que el propio agente reemplazara sin querer el state activo por uno viejo de un .zip archivado. El destroy borró VPC, clúster ECS, balanceadores, bastion host, la base RDS y sus snapshots automáticos — cerca de 1.943.200 filas y 2,5 años de historial de un curso, con aproximadamente 24 horas de recuperación vía soporte de AWS (Alexey Grigorev — How I Dropped Our Production Database · Hacker News #47278720 · incidentdatabase.ai — Incident 1424).

El detalle que hace a ese caso pedagógicamente valioso, no solo anecdótico, es este: el agente había señalado el riesgo antes de ejecutar, y el humano aprobó igual. terraform-and-iac-guide usó ese caso para instalar un hábito: ningún apply ni destroy corre sin leer el plan completo primero. Esta lección hace la pregunta que esa guía dejó abierta, a propósito, para esta: ¿un pipeline hubiera evitado ese incidente?

La respuesta honesta, sin adornarla, tiene dos partes:

No, un pipeline no evita la negligencia. Si el flujo hubiera pasado por un apply.yml con un Environment de producción que exige aprobación humana (Módulo 4), y la persona que aprobó ese Environment hubiera visto exactamente el mismo plan con la misma advertencia de riesgo — y aun así hubiera aprobado — el resultado habría sido idéntico. Un pipeline no reemplaza el juicio humano; automatiza el proceso alrededor de ese juicio, no el juicio en sí.

Sí, un pipeline deja un registro que en el incidente real no existía de forma explícita. Con un apply.yml gatillado por push a main, protegido por branch protection (Módulo 6) y un Environment con required reviewers (Módulo 4), quedaría un rastro estructurado, buscable, imposible de perder en el historial de una terminal: quién aprobó el PR que introdujo el cambio, quién aprobó el Environment antes de que el destroy corriera, cuándo, y sobre qué plan exacto —el mismo que se revisó, no uno recalculado después—. En el incidente real, la aprobación ocurrió, pero no dentro de un sistema que la registrara de esa forma. Esa diferencia —de "la aprobación existió, en algún lado, quizás" a "la aprobación existe, con fecha, autor y contenido exacto, consultable para siempre"— es exactamente lo que un pipeline agrega. No previene la mala decisión. Hace que la mala decisión sea auditable, y esa auditabilidad es, en la práctica, lo que cambia el comportamiento de los equipos: nadie aprueba con la misma ligereza cuando sabe que su nombre queda asociado, para siempre, a esa aprobación específica.

El Módulo 6 de esta guía vuelve a esta misma pregunta, con más profundidad, después de que hayas construido el guardrail real que sí hubiera detenido —no la negligencia, sino el efecto— de un destroy sobre la tabla Shipments.


Errores comunes

Creer que esta lección dice "un pipeline es infalible" (de expectativa, corregido explícitamente arriba). Qué pasa: alguien termina la sección del caso de estudio con la conclusión de que, si Andes Cargo tuviera un pipeline, ningún incidente similar podría volver a pasar. Por qué pasa: es tentador leer "deja un registro" como "previene el error". Cómo detectarlo: si tu resumen de esta lección es "con un pipeline, esto no habría pasado" en vez de "con un pipeline, sabríamos exactamente quién lo aprobó". Cómo corregirlo: vuelve al párrafo de la respuesta honesta, arriba — un pipeline automatiza el proceso, no el juicio. La sección "Errores comunes" del Módulo 6 (lección 5) vuelve sobre esto con el guardrail real ya construido.

Pensar que el problema de las credenciales solo aplica "si trabajas con AWS real" (de alcance). Qué pasa: alguien, trabajando contra LocalStack con test/test, concluye que la pregunta 2 de esta lección ("¿con qué credenciales?") no le aplica, porque sus credenciales dummy no tienen ningún riesgo. Por qué pasa: es cierto que en el laboratorio de esta guía no hay riesgo real —y eso es intencional, para mantener el compromiso de $0—. Cómo detectarlo: si crees que el Módulo 4 (secretos y OIDC) es "teoría sin aplicación práctica" para ti. Cómo corregirlo: el laboratorio usa test/test a propósito, para que puedas practicar el patrón completo sin arriesgar nada — pero el patrón que construyes (GitHub Secrets, OIDC nombrado) es exactamente el que usarías el día que andes-cargo-infra/ apunte a una cuenta real, sin cambiar la estructura del pipeline.

Confundir "revisar el plan yo mismo, con más calma" con "tener una segunda revisión" (conceptual). Qué pasa: alguien piensa que el problema #1 de esta lección (sin revisión obligatoria) se resuelve simplemente siendo más cuidadoso al leer el plan antes de aplicar. Por qué pasa: es un hábito real y valioso —de hecho, es el hábito que instaló terraform-and-iac-guide—, y se siente suficiente. Cómo detectarlo: si tu solución mental es "yo reviso mejor" en vez de "alguien más también revisa, antes de que yo pueda aplicar". Cómo corregirlo: leer con cuidado tu propio trabajo reduce errores, pero no elimina el sesgo de quien escribió el cambio siendo también quien lo aprueba — es la misma persona validando su propia decisión. Un pull request con revisión de otra persona, gate obligatorio antes de fusionar (Módulo 3 y Módulo 6), agrega un punto de vista genuinamente distinto, no solo una segunda lectura de la misma persona.


Ejercicios

Ejercicio 1 — Audita tu propio historial. Sin mirar ningún log, intenta responder: de los apply que corriste en terraform-and-iac-guide, ¿podrías decir hoy, con certeza, la fecha exacta y la razón de negocio de cada uno? Si no puedes, ¿dónde viviría esa información si el mismo trabajo se hubiera hecho a través de un pull request?

Ver solución

La mayoría de las personas no van a poder reconstruir fecha y razón exacta de cada apply sin revisar activamente su propio historial de shell (si es que lo conservaron) — y eso es, precisamente, el punto del ejercicio: esa información existió solo en el momento en que corriste el comando, no en ningún artefacto persistente y estructurado. Si el mismo trabajo se hiciera vía pull request, esa información viviría en el propio PR: el título, la descripción, los comentarios de revisión, y la fecha de fusión — todo buscable, para siempre, sin depender de la memoria de nadie.

Ejercicio 2 — Explica la diferencia entre "prevenir" y "auditar" a un colega escéptico. Un colega te dice: "si un pipeline no evita que alguien apruebe un destroy peligroso, entonces no sirve de nada — el resultado final es el mismo desastre". Respóndele en tres o cuatro frases, usando la distinción exacta de esta lección.

Ver solución

Una respuesta completa suena, más o menos, así: "Tienes razón en que el pipeline no cambia la decisión de la persona que aprueba — si alguien decide aplicar un cambio peligroso habiendo visto la advertencia, el pipeline no se lo va a impedir por arte de magia. Pero 'el resultado final es el mismo' es cierto solo para la infraestructura destruida, no para lo que pasa después: sin pipeline, nadie puede reconstruir con certeza quién aprobó qué y cuándo; con pipeline, ese registro existe, es inmutable, y cambia radicalmente qué tan rápido se puede diagnosticar la causa raíz y qué tan seriamente se toma la próxima aprobación cualquier persona del equipo. Prevenir el error humano es un problema de cultura y de juicio; dejar un registro auditable es un problema de ingeniería, y ese sí lo resuelve un pipeline."

Ejercicio 3 — Diseña la pregunta que un pipeline sí puede responder. Escribe tres preguntas concretas sobre un cambio de infraestructura que serían imposibles de responder con confianza si andes-cargo-infra/ solo se aplicara a mano, y que un pipeline con PR obligatorio, plan publicado y apply.yml encadenado sí puede responder con certeza.

Ver solución

Tres preguntas razonables: (1) "¿Quién aprobó, exactamente, el cambio que modificó la política del bucket andes-cargo-shipment-docs la semana pasada?" — con pipeline, la respuesta es el autor del PR y quien lo aprobó, con fecha, en el historial de GitHub. (2) "¿El apply que corrió en producción es exactamente el mismo plan que se revisó, o se recalculó algo distinto entre la revisión y la aplicación?" — con pipeline (Módulo 5, needs + artefactos), la respuesta es verificable: el mismo archivo de plan viaja de un job al siguiente. (3) "¿Hubo algún cambio directo, fuera de este proceso, que nadie revisó?" — con pipeline y detección de drift programada (Módulo 5), la respuesta es un plan periódico que compara el estado real contra lo declarado, en vez de "no hay forma de saberlo hasta que alguien lo note por accidente".


Resumen y siguiente paso

En esta lección nombraste, con precisión, el problema que sostiene el resto de esta guía: un terraform apply corrido a mano no deja registro de quién lo corrió, expone credenciales de larga vida en la máquina de una persona, y depende de que esa persona específica esté disponible cuando haga falta. También revisitaste el incidente del destroy de Claude Code de terraform-and-iac-guide desde un ángulo nuevo: un pipeline no habría evitado la negligencia —el humano aprobó habiendo visto el riesgo—, pero sí habría dejado un registro auditable de esa aprobación, que en el incidente real no existía de forma explícita.

Antes de avanzar deberías poder: nombrar las tres preguntas que un apply manual no puede responder con confianza; explicar la diferencia entre "prevenir" y "auditar" un cambio de infraestructura; y describir, en una frase, qué agrega un pipeline sobre el apply manual que ya dominas.

La lección 3 le pone nombre formal a la solución: qué es, exactamente, integración continua, frente a entrega continua, frente a despliegue continuo — tres cosas que comparten una sigla y que esta lección todavía no distinguió.

Recursos

  1. Hacker News — discusión del incidente #47278720 — el hilo original del incidente de destroy citado en esta lección.
  2. incidentdatabase.ai — Incident 1424 — el registro estructurado del incidente en la base de datos pública de incidentes de IA.
  3. terraform-and-iac-guide, Módulo 8, lección 5 — la fuente completa del caso de estudio del destroy, con el detalle técnico de cómo se reemplazó el state.
  4. AWS Well-Architected Framework — Operational Excellence — el pilar oficial de AWS que enmarca por qué la automatización de despliegues y la auditabilidad son un requisito de operación, no una preferencia estética.