Módulo 7: Gitops Beyond Terraform
6. CI/CD de código de aplicación vs. infraestructura
Descripción
Las lecciones 2 a 5 de este módulo compararon herramientas y mecanismos, siempre dentro del mundo de infraestructura que ya conoces. Esta lección traza la frontera más importante de todo el módulo, de forma corta y directa a propósito: qué cambia cuando el "código" que un pipeline de CI/CD procesa no es HCL declarativo, sino el código fuente de una aplicación —una API, un frontend, un script—. No es una lección larga porque no necesita serlo: la diferencia se resume en pocos conceptos concretos, y la lección 7 la hace tangible con un pipeline real, corrido con act.
Conexión con el módulo
Esta lección es la bisagra exacta del módulo: cierra la parte puramente conceptual (lecciones 2 a 5) y prepara el terreno para la única lección manos a la obra (7). Todo lo que leas aquí lo vas a ver correr, de verdad, en la próxima lección — un pipeline mínimo con exactamente los pasos característicos de CI/CD de aplicación que esta lección nombra: checkout, lint, test.
La tabla que resume todo el módulo
| CI/CD de infraestructura (esta guía, Módulos 2-6) | CI/CD de código de aplicación | |
|---|---|---|
| Qué procesa el pipeline | HCL declarativo (.tf) | Código fuente ejecutable (.py, .js, .go...) |
| Paso característico de "verificación" | terraform fmt, terraform validate | Linter (ruff, eslint), type checker |
| Paso característico de "prueba" | terraform plan (calcula qué cambiaría, no ejecuta lógica de negocio) | Tests unitarios/integración (pytest, jest) — ejecutan lógica de negocio real |
| ¿Existe un "artefacto" que compilar/empaquetar? | No — el HCL se aplica directamente, no se compila a un binario intermedio | Sí — un paquete, un binario, o típicamente una imagen de contenedor |
| Qué hace el paso de "despliegue" | terraform apply — mueve el estado de un recurso declarado al siguiente | Reemplazar réplicas de una aplicación corriendo, con una estrategia (Módulo 7, lección 5: rolling/blue-green/canary) |
| Qué credenciales necesita | Credenciales del proveedor de nube (AWS, vía OIDC — Módulo 4) | Credenciales de base de datos, APIs de terceros, y también del proveedor de nube si despliega ahí |
| ¿"Éxito" es reversible fácilmente? | Sí — git revert + el mismo pipeline (Módulo 6) | Depende de la estrategia de despliegue (Módulo 7, lección 5) |
Fíjate en la fila del "artefacto" — es, probablemente, la diferencia estructural más profunda de la tabla. andes-cargo-infra/ nunca produjo nada que se pudiera "guardar en un registro y versionar como una unidad" — el HCL se lee y se aplica directamente contra el proveedor de nube en cada corrida. Un pipeline de aplicación típico, en cambio, tiene un paso explícito de build (compilar, empaquetar, construir una imagen de contenedor) que no tiene equivalente en el pipeline de esta guía, precisamente porque Terraform no se "compila" en el mismo sentido.
Por qué el plan no es lo mismo que un test
Vale la pena ser preciso en un punto que se presta a confusión: terraform plan parece una prueba —corre antes de aplicar, y si algo está mal, lo muestra—, pero no cumple la misma función que un test unitario. plan calcula la diferencia entre el estado declarado y el estado real, y te la muestra para revisión humana — no ejecuta ninguna lógica de negocio ni verifica un comportamiento esperado contra un resultado esperado. Un test unitario de aplicación, en cambio, sí hace exactamente eso: ejecuta una función real con entradas conocidas y afirma (assert) que la salida es la que se espera. terraform validate (Módulo 3) es lo más parecido a un test que corriste en esta guía, y ni siquiera eso ejecuta lógica — solo confirma que la sintaxis y las referencias internas del HCL son válidas.
Esta distinción explica por qué el pipeline de esta guía nunca tuvo un paso llamado, literalmente, "test": no hay lógica de negocio propia que probar. Andes Cargo no escribió una función que calcule algo y necesite verificarse contra casos conocidos — declaró recursos, y la única "prueba" posible sobre una declaración es "¿el plan resultante es el que yo esperaba?", una pregunta que un humano responde leyendo el plan, no una que un assert automatizado pueda responder por sí solo sin duplicar el propio plan.
Errores comunes
Pensar que terraform validate es "el equivalente de Terraform" a un test unitario (conceptual, la confusión más común de esta lección). Qué pasa: alguien, viendo que ambos corren en CI antes de aplicar/desplegar, asume que cumplen el mismo rol. Por qué pasa: los dos aparecen en la misma posición del pipeline (verificación temprana, antes de la parte cara). Cómo detectarlo: si describes terraform validate como "los tests de esta guía". Cómo corregirlo: validate confirma sintaxis y referencias — nunca ejecuta lógica de negocio ni compara una salida contra un resultado esperado, porque el HCL declarativo no tiene "lógica de negocio" en el sentido en el que una función de aplicación sí la tiene.
Asumir que cualquier pipeline de aplicación necesita un paso de "build" (de generalización, corregido en la lección 7). Qué pasa: alguien espera que el pipeline mínimo de la lección 7 tenga un paso de compilación o empaquetado. Por qué pasa: la tabla de esta lección lo presenta como diferencia estructural típica. Cómo detectarlo: si te sorprende que el pipeline de la lección 7 no tenga un step de "build". Cómo corregirlo: la fila de la tabla dice "típicamente" — un script de Python interpretado, como el de la lección 7, no necesita compilarse a un binario antes de correr; el paso de build es característico de lenguajes compilados o de aplicaciones que se empaquetan como imagen de contenedor, no una regla universal de todo CI/CD de aplicación.
Ejercicios
Ejercicio 1 — Completa la tabla de memoria. Sin mirar esta lección, escribe las cuatro filas de la tabla (paso de verificación, paso de prueba, artefacto, despliegue) para ambos tipos de CI/CD.
Ver solución
Infraestructura: verificación = fmt/validate; prueba = plan (calcula diferencia, no ejecuta lógica); artefacto = ninguno, se aplica directo; despliegue = apply, mueve el estado de un recurso al siguiente. Aplicación: verificación = linter/type checker; prueba = tests unitarios/integración que ejecutan lógica real con assert; artefacto = paquete/binario/imagen de contenedor; despliegue = reemplazar réplicas corriendo, con una estrategia (rolling/blue-green/canary).
Ejercicio 2 — Explica por qué plan no es un test. En una o dos frases, explica a un colega por qué terraform plan, aunque corra antes de aplicar y muestre si algo está mal, no cumple la misma función que un test unitario de una aplicación.
Ver solución
plan calcula y muestra la diferencia entre el estado declarado y el real, para que un humano la revise — no ejecuta ninguna lógica propia ni compara un resultado calculado contra un resultado esperado con un assert. Un test unitario sí hace eso: ejecuta código real con entradas conocidas y afirma automáticamente que la salida es la correcta, sin necesitar revisión humana para saber si pasó o falló.
Ejercicio 3 — Ubica las dos guías de la frontera. ¿Qué dos guías del ecosistema cubren, en profundidad, el lado "aplicación" de la tabla de esta lección?
Ver solución
cicd-python-backend-guide (pipelines de CI/CD para una aplicación backend de Python: lint, tests, build, deploy de un artefacto real) y testing-in-cicd-guide (estrategias de testing automatizado — unitario, integración, end-to-end — integradas en un pipeline de CI). Esta guía nombra el contraste; esas dos lo construyen.
Resumen y siguiente paso
En esta lección sistematizaste, en una sola tabla, la frontera completa entre CI/CD de infraestructura (lo que construiste en los Módulos 2 a 6) y CI/CD de código de aplicación: qué se verifica, qué se prueba, si existe un artefacto, y qué significa "desplegar" en cada caso. Confirmaste, con precisión, por qué terraform plan/validate no son equivalentes a un test unitario de aplicación — la ausencia de lógica de negocio propia en HCL declarativo.
Antes de avanzar deberías poder: completar la tabla de contraste de memoria; explicar por qué esta guía nunca necesitó un paso de "test" en el sentido de aplicación; y nombrar las dos guías del ecosistema que cubren CI/CD de aplicación en profundidad.
La lección 7 hace tangible todo lo de esta lección: vas a correr, de verdad con act, un pipeline mínimo de tres pasos —checkout, lint, test— sobre un script Python trivial, y vas a ver con tus propios ojos la diferencia con ci.yml.
Recursos
- GitHub Docs — GitHub Actions — documentación oficial de la herramienta que corre ambos tipos de pipeline (infraestructura y aplicación), sin distinción técnica entre uno y otro.
terraform-and-iac-guide, Módulo 1, lección 3 — la definición de "declarativo" que explica por qué el HCL no tiene lógica de negocio propia que testear.cicd-python-backend-guide(NIEVA) — el lado "aplicación" completo de la tabla de esta lección, construido en profundidad.testing-in-cicd-guide(NIEVA) — estrategias de testing automatizado en CI, el paso de "prueba" de la tabla de esta lección, cubierto a fondo.