Módulo 8: Capstone The Andes Cargo Pipeline
8. Proyecto final: el pipeline de Andes Cargo como entregable
Descripción
Este es el proyecto que cierra la guía completa. No hay ninguna pieza técnica nueva que construir —las lecciones 3 y 4 ya probaron, con salida literal de act, que el pipeline entero funciona bajo presión— y las lecciones 5, 6 y 7 ya trazaron cada frontera de honestidad con precisión. Lo que este proyecto hace es lo que ningún módulo anterior tuvo espacio para hacer completo: presentar el repositorio entero como una pieza de portfolio, con un README.md de pipeline que documenta el flujo de punta a punta, una auditoría dirigida de la estructura completa, y el criterio exacto que un entrevistador técnico —o tú mismo, explicando este trabajo dentro de seis meses— usaría para juzgar si es real o decorativo.
Conexión con el módulo
Cada proyecto de cierre de esta guía, desde el Módulo 1, terminó con una confirmación dirigida del trabajo de ese módulo. Este es el mismo ejercicio, aplicado por última vez a los ocho módulos completos: tres workflows de producción, un guardrail real, y un recorrido probado dos veces bajo presión. Con esto, cicd-and-gitops-on-aws-guide queda completa.
Paso 1 — Auditoría de la estructura: la capa de pipeline completa
cd andes-cargo-infra
find . -maxdepth 3 -not -path '*/.terraform*' -not -path './.git/*' -not -path './.git' | sort
Qué esperar (literal, ejecutado para escribir esta lección):
.
./.actrc
./.github
./.github/act-events
./.github/act-events/pr-event-52.json
./.github/act-events/pr-event-revert.json
./.github/act-events/pr-event.json
./.github/guardrail-fixtures
./.github/guardrail-fixtures/shipments-already-applied.state.json
./.github/workflows
./.github/workflows/apply.yml
./.github/workflows/ci.yml
./.github/workflows/drift.yml
./.github/workflows/guardrail-demo.yml
./.gitignore
./.secrets
./dynamodb.tf
./iam.tf
./lambda
./lambda.tf
./lambda/function.zip
./lambda/handler.py
./locals.tf
./modules
./modules/iam-role
./modules/s3-bucket
./outputs.tf
./providers.tf
./s3.tf
./terraform.tfvars
./variables.tf
./versions.tf
Divide esta lista en dos capas, y confirma que puedes explicar cada una sin dudar: la capa de negocio —versions.tf a lambda.tf, más modules/— es, línea por línea, el mismo proyecto que terraform-and-iac-guide dejó terminado en su capstone; esta guía no reescribió una sola línea de HCL de negocio, salvo la excepción documentada del guardrail. La capa de pipeline —todo dentro de .github/, más .actrc y .secrets— es lo genuinamente nuevo de esta guía, construido módulo por módulo, desde el .actrc de una sola línea del Módulo 1 hasta el guardrail de ci.yml del Módulo 6.
Confirma que el proyecto de negocio sigue siendo válido, sin ninguna huella del trabajo de esta guía:
terraform fmt -check -recursive
terraform validate
Qué esperar (literal):
Success! The configuration is valid.
Paso 2 — El README.md de pipeline: el entregable de portfolio
Crea este archivo en la raíz de andes-cargo-infra/ — el documento que cualquier persona que abra este repositorio leería primero:
# andes-cargo-infra — pipeline de CI/CD
Infraestructura de Andes Cargo (bucket de manifiestos, tabla de envíos, roles IAM, función
de procesamiento) declarada en Terraform, con un pipeline de GitHub Actions que automatiza
su revisión y aplicación. Corrido de punta a punta con `act` (v0.2.89) contra LocalStack —
$0, reproducible, sin necesitar una cuenta de AWS ni de GitHub para desarrollarlo.
## El pipeline
| Workflow | Disparador | Qué hace |
|---|---|---|
| `ci.yml` | `pull_request` contra `main` | `fmt` → `validate` → `plan` → guardrail → resumen → sube el plan como artefacto |
| `apply.yml` | `push` a `main` | Descarga el plan exacto que se revisó, lo aplica con `-auto-approve` |
| `drift.yml` | `schedule` (diario, 06:00 UTC) o `workflow_dispatch` | `plan -detailed-exitcode` de solo lectura, reporta si algo cambió por fuera de Terraform |
## El guardrail
`ci.yml` incluye un step que falla el job si el `plan` intenta destruir la tabla
`Shipments` — un `grep` sobre `terraform show -json`, agregado en el Módulo 6 de la guía
que construyó este pipeline. `guardrail-demo.yml` prueba ese mismo guardrail contra un
*fixture* de `state` sembrado, sin necesitar infraestructura real aplicada.
## Cómo correrlo localmente
\`\`\`bash
brew install act
docker run --rm -d --name localstack_main -p 127.0.0.1:4566:4566 \
-e LOCALSTACK_AUTH_TOKEN=${LOCALSTACK_AUTH_TOKEN:?} localstack/localstack
act pull_request -e .github/act-events/pr-event.json -j terraform-checks --secret-file .secrets
act push -W .github/workflows/apply.yml
act workflow_dispatch -j check-drift -W .github/workflows/drift.yml
\`\`\`
## Qué NO construye este pipeline (a propósito)
- **OIDC federado real** contra una cuenta AWS — mostrado en YAML completo, sin ejecutar
(`act` no emite tokens OIDC). Credenciales dummy `test`/`test` vía `.secrets`, aceptable
únicamente porque el destino es LocalStack.
- **Aprobación humana de *Environments*** y **branch protection** — configuración de
`github.com` real, sin ningún YAML asociado que `act` pueda ejecutar.
- **SAST/DAST, SBOM, firma de imágenes, políticas como sistema** (`conftest`/OPA/Sentinel a
escala) — fuera del alcance de este proyecto de aprendizaje.
Documentación completa del diseño y la honestidad de ejecución de cada pieza:
`cicd-and-gitops-on-aws-guide` (NIEVA).
Commitea el documento:
git add README.md
git commit -m "Add README.md: pipeline documentation for andes-cargo-infra"
Paso 3 — Cómo defender este proyecto en una entrevista
Un entrevistador técnico que revise este repositorio —o tú mismo, explicándolo seis meses después— no necesita que recites YAML de memoria. Necesita que puedas responder, sin dudar, cuatro tipos de pregunta, cada uno con su evidencia específica dentro de esta guía:
-
"¿Por qué dos workflows separados,
ci.ymlyapply.yml, en vez de uno solo con una condición?" — la respuesta vive en el Módulo 3, lección 2: separarplan(en cada PR) deapply(solo enpushamain) es el patrón estándar citado del tutorial oficial de HashiCorp, y evita la familia de vulnerabilidades donde unpull_requestde una rama no confiable termina, por error de configuración, con permisos de escritura. -
"¿Cómo garantizas que lo que se aplica es exactamente lo que se revisó, no un recálculo?" — la respuesta vive en el Módulo 5, lección 3, y la confirmaste tres veces con tus propios ojos en este módulo:
upload-artifact/download-artifactmueven el mismo archivo binario entre jobs, verificado por SHA256 idéntico en cada punto —el mismo hash apareció enci.ymlal subir, y dos veces enapply.ymlal descargar, en la lección 3 de este módulo—. -
"¿Qué pasa si alguien intenta un cambio peligroso, por error o a propósito?" — la respuesta vive en el Módulo 6 y se demostró bajo presión en la lección 4 de este módulo: un
grepreal sobre elplanen JSON detiene el job antes de que exista cualquier artefacto queapply.ymlpudiera aplicar.Plan: 10 to add, 1 to destroy→Job failed, sin ambigüedad. -
"¿Qué le falta a este pipeline para producción real?" — la respuesta completa vive en las lecciones 5, 6 y 7 de este módulo: comentarios de PR y aprobación humana reales (requieren
github.com), OIDC de punta a punta y SAST/DAST/SBOM (cloud-security-and-guardrails-guide), y el resto del ciclo operacional —EKS con GitOps pull-based, SRE, FinOps— cada uno con su guía dedicada, no una admisión vaga de que "falta trabajo".
Si puedes responder las cuatro con la evidencia específica de esta guía —no una afirmación genérica sobre buenas prácticas de CI/CD—, este proyecto está listo para defenderse.
Paso 4 — Confirmación final: el pipeline completo, listado
act -l
Qué esperar (literal, ejecutado para escribir esta lección):
Stage Job ID Job name Workflow name Workflow file Events
0 fetch-reviewed-plan fetch-reviewed-plan apply apply.yml push
0 terraform-checks terraform-checks ci ci.yml pull_request
0 check-drift check-drift drift-detection drift.yml schedule,workflow_dispatch
0 destroy-shipments-check destroy-shipments-check guardrail-demo guardrail-demo.yml workflow_dispatch
1 terraform-apply terraform-apply apply apply.yml push
git log --oneline | wc -l
git log --oneline | head -5
Qué esperar (representativo en los hashes y en el conteo exacto —depende de cuántas veces corriste cada proyecto de módulo a lo largo de esta guía—, literal en la estructura de los mensajes más recientes):
<N>
<hash> Add README.md: pipeline documentation for andes-cargo-infra
<hash> Add CostCenter tag to the shipment-docs bucket
<hash> Add doc/adr/0001-choosing-cicd-tooling.md: ADR for GitHub Actions over Jenkins/GitLab CI
<hash> ci.yml: add a guardrail step that blocks any plan destroying the Shipments table; add guardrail-demo.yml to test it against a seeded fixture
<hash> Add pr-event-revert.json to simulate the revert PR with act
Cinco jobs listados, el mismo historial acumulativo desde el Módulo 1 — ningún workflow se perdió, ningún commit se reescribió. Esta es la confirmación final de que el repositorio está exactamente en el estado que las ocho lecciones de este módulo, y los siete anteriores, construyeron con evidencia real.
Errores comunes
Considerar el proyecto "terminado" sin escribir el README.md del Paso 2 (de alcance). Qué pasa: alguien completa las lecciones 3 y 4, ve el pipeline funcionando, y asume que eso es suficiente evidencia de portfolio. Cómo corregirlo: un repositorio sin ningún documento que explique el flujo completo exige que cualquier persona que lo revise reconstruya la lógica leyendo YAML sin contexto — el README.md es lo que convierte "un montón de archivos que funcionan" en "un proyecto que se explica solo". Es la misma disciplina que el Módulo 4 ya aplicó con SECRETS-AND-ENVIRONMENTS.md.
Presentar este proyecto sin mencionar sus límites explícitos (de honestidad, revisita las lecciones 5-7). Qué pasa: alguien, al mostrar este trabajo en una entrevista, lo presenta como "listo para producción" sin nombrar ninguna de las piezas de las lecciones 5, 6 y 7. Cómo corregirlo: un entrevistador experimentado valora más a alguien que conoce los límites exactos de su propio trabajo que a alguien que presenta un proyecto de aprendizaje como si fuera un sistema de producción completo — las lecciones 5-7 de este módulo son, literalmente, el guion de esa parte de la conversación.
Borrar .secrets o .gitignore al preparar el repositorio para mostrarlo (de seguridad). Qué pasa: alguien, preparando este proyecto para compartirlo, borra archivos que le parecen "de configuración interna" sin revisar cuáles importan. Cómo corregirlo: .gitignore demuestra que entiendes qué nunca debe versionarse; .secrets, gitignorado desde el Módulo 2, nunca debería estar en el historial de Git en primer lugar —confírmalo con git log --all --full-history -- .secrets, que debería devolver vacío, exactamente como confirmó el Módulo 4—. Si vas a compartir este repositorio públicamente, verifica ese comando antes de publicarlo, no después.
Ejercicios
Ejercicio 1 — Responde las cuatro preguntas de entrevista del Paso 3 sin mirar la lección. De memoria, escribe una respuesta completa a cada una de las cuatro preguntas de entrevista de esta lección, citando la evidencia específica de qué módulo/lección la respalda.
Ver solución
La estructura completa de las cuatro respuestas está en el Paso 3 — el objetivo de este ejercicio es haber podido reconstruirlas sin mirar, citando de memoria la evidencia específica: el patrón HashiCorp del Módulo 3 (pregunta 1), la verificación de SHA256 del Módulo 5 y de la lección 3 de este módulo (pregunta 2), el Plan: 10 to add, 1 to destroy → Job failed de la lección 4 de este módulo (pregunta 3), y las tres piezas de frontera de las lecciones 5-7 (pregunta 4). Si citaste evidencia específica —números, nombres de archivo, nombres de lección— en vez de afirmaciones genéricas, tienes la defensa completa internalizada.
Ejercicio 2 — Explica la tesis completa de esta guía en menos de treinta segundos hablados. Un entrevistador te da treinta segundos para explicar qué construiste en esta guía y por qué importa. Escribe esa respuesta.
Ver solución
Una respuesta completa, ajustada a treinta segundos hablados, suena, más o menos, así: "Tomé infraestructura de AWS ya declarada en Terraform y construí el pipeline de CI/CD que la gobierna: cada Pull Request calcula un plan que alguien revisa, cada fusión a main lo aplica automáticamente con el mismo archivo exacto que se revisó —verificado por SHA256—, un chequeo programado detecta cambios hechos por fuera del pipeline, y un guardrail bloquea, de forma automática, cualquier intento de destruir el recurso más crítico del proyecto. Probé el pipeline completo dos veces: con un cambio real que pasa de punta a punta sin que yo tocara terraform apply, y con un intento de destrucción que el pipeline detiene antes de aplicar. El punto no es que un pipeline sea más rápido que aplicar a mano — es que deja un registro auditable de quién aprobó qué, y hace algunas decisiones peligrosas técnicamente imposibles, sin depender del juicio de nadie en el momento."
Ejercicio 3 — Aplica la metáfora del mapa del Módulo 7 a esta guía completa. Cierra el círculo abierto en el Módulo 7, lección 1, ejercicio 3: compara la frase que escribiste entonces sobre el borde de tu propio mapa con lo que sabes ahora, al cerrar el Módulo 8.
Ver solución
No hay una única respuesta correcta — es la misma autoevaluación honesta que ya practicaste, ahora con el mapa completo de esta guía disponible. Una versión actualizada razonable: "Sé construir y probar, de punta a punta, un pipeline de CI/CD de infraestructura completo —revisión automática, aplicación automática solo tras revisión, un guardrail real que protege un recurso crítico, verificado bajo presión con un cambio aceptado y uno rechazado—. Sé nombrar con precisión qué le falta para producción real: OIDC de punta a punta, SAST/DAST, aprobación humana real, y el resto del ciclo operacional —Kubernetes, SRE, FinOps—, cada uno con su guía dedicada que sabría dónde empezar." Si tu versión combina algo que construiste con algo que puedes nombrar con precisión pero no construiste todavía, tienes exactamente la habilidad que esta guía completa practicó de principio a fin.
Resumen y siguiente paso
En este proyecto final auditaste la estructura completa de andes-cargo-infra/ —doce archivos y directorios de la capa de pipeline, sin tocar una sola línea de la capa de negocio heredada—, escribiste el README.md que documenta el flujo completo como pieza de portfolio, y preparaste la defensa de cuatro preguntas de entrevista con evidencia específica de esta guía. Confirmaste, con act -l y git log, que el repositorio completo sigue exactamente donde las ocho lecciones de este módulo, y los siete módulos anteriores, lo dejaron.
Antes de cerrar esta guía deberías poder: responder las cuatro preguntas de entrevista del Paso 3 con evidencia específica, no genérica; explicar la tesis completa de la guía en menos de treinta segundos hablados; y nombrar, sin dudar, tanto lo que construiste como lo que sabes que existe pero todavía no construiste.
Con esto, cicd-and-gitops-on-aws-guide queda completa: ocho módulos, un pipeline de CI/CD de infraestructura real —probado, no solo descrito—, un guardrail que protege el recurso más crítico de Andes Cargo, y la honestidad completa de dónde termina este trabajo. El camino sigue, según lo que tu propio proyecto necesite, en cualquiera de las guías hermanas que las lecciones 5, 6 y 7 de este módulo trazaron: cloud-security-and-guardrails-guide, kubernetes-and-eks-in-production-guide, sre-and-incident-response-guide, o finops-and-cost-guardrails-guide.
Recursos
- nektosact.com — User Guide — referencia completa de
act, la herramienta que sostuvo la ejecución real de cada lección de esta guía. - GitHub Docs — GitHub Actions — documentación oficial del motor completo detrás de los tres workflows de producción de Andes Cargo.
- HashiCorp Developer — Automate Terraform with GitHub Actions — el patrón central que esta guía entera implementó y probó de punta a punta.
terraform-and-iac-guide(NIEVA) — el proyectoandes-cargo-infra/original, automatizado por esta guía sin reescribir una sola línea de negocio, salvo el guardrail del Módulo 6.