Pipeline de infraestructura¶
El proyecto terraform-modules tiene su propio .gitlab-ci.yml. A diferencia de los pipelines de aplicación, no consume el repositorio cicd-templates: define plantillas ocultas para OpenTofu y jobs concretos por capa. La selección de proveedor modifica el directorio de trabajo y las variables, manteniendo la misma secuencia.
Controles de entrada¶
| Variable | Predeterminado del snapshot | Comportamiento |
|---|---|---|
CLOUD_PROVIDER |
aws |
Se valida contra aws y gcp |
ENVIRONMENT |
pro |
Prefijo de estado y resource_group; el comentario enumera dev/pre/pro, pero el script no valida esos valores |
PIPELINE_ACTION |
destroy |
Se valida contra create y destroy |
STACK |
Lo fija cada job | network, kubernetes, database o platform |
TF_IN_AUTOMATION |
true |
Ejecución automatizada |
TF_INPUT |
false |
Sin preguntas interactivas |
Seleccionar explícitamente la operación
La configuración publicada selecciona planes de destrucción por defecto. Las aplicaciones de esos planes siguen siendo manuales. Para crear un entorno se debe indicar PIPELINE_ACTION=create, el proveedor y el entorno elegidos, tras revisar el aislamiento de recursos explicado en estados.
En un lanzamiento desde la interfaz de GitLab, la configuración de creación es:
| Campo | AWS | GCP |
|---|---|---|
| Rama de ejecución del código actual | main |
main |
PIPELINE_ACTION |
create |
create |
CLOUD_PROVIDER |
aws |
gcp |
ENVIRONMENT |
Nombre del entorno previamente preparado | Nombre del entorno previamente preparado |
No se ofrece un valor automático para el entorno: usar dev en una cuenta que ya tiene recursos con los nombres fijos de otro estado puede producir colisiones o una gestión incorrecta.
Preparación común del job¶
La plantilla .tofu_base utiliza la imagen OpenTofu 4.7.0-opentofu1.12.1-alpine, vacía su entrypoint e instala bash, curl, jq y aws-cli. Incluso los jobs GCP ejecutan esa instalación común.
Después valida selector/acción/directorio, calcula TF_ROOT y los nombres de estado, cambia a la raíz, exporta el backend HTTP y las referencias de estado, y mapea las variables de DB, Agent, región y proyecto. Para GCP escribe el JSON de la cuenta de servicio a un fichero dentro del workspace. Véase el contrato de variables.
Secuencia de creación¶
Cada capa completa validación, plan y aplicación antes de comenzar la siguiente:
| Capa | Jobs, en orden | Dependencia previa |
|---|---|---|
| Red | validate_network, plan_network, apply_network |
Ninguna capa previa |
| Kubernetes | validate_kubernetes, plan_kubernetes, apply_kubernetes |
apply_network |
| Base de datos | validate_database, plan_database, apply_database |
apply_kubernetes |
| Plataforma | validate_platform, plan_platform, apply_platform |
apply_database |
La validación ejecuta tofu init -reconfigure, tofu fmt -check -recursive y tofu validate. La opción -recursive se aplica después de entrar a una raíz concreta, por lo que no valida de golpe las ocho raíces del repositorio. La validación tampoco garantiza permisos cloud, cuotas, coste o viabilidad de todo el despliegue.
El plan ejecuta tofu plan -out=plan.cache y exporta JSON con tofu show -json. Copia los ficheros a la raíz del workspace como <stack>.plan.cache y <stack>.plan.json. El apply recupera el artefacto mediante needs, reinicializa el backend y aplica ese plan guardado, sin recalcularlo implícitamente.
Los applies son manuales, allow_failure: false y solo se incluyen si la rama es literalmente main. Esta separación deja una revisión explícita por capa. Una aprobación tardía debe comprobar que el plan sigue vigente y que sus artefactos no han expirado.
Secuencia de destrucción¶
Para cada capa existen plan_destroy_<stack> y apply_destroy_<stack>. El primero genera un plan con tofu plan -destroy; el segundo aplica el destroy.cache guardado, manualmente. El orden es plataforma → base de datos → Kubernetes → red.
Además existe force_unlock_gcp_database_private_service_access. A pesar del nombre, su script ejecuta tofu state rm sobre la conexión Private Service Access. No desbloquea un lock. Está restringido a GCP/destroy/main, usa un resource_group fijo dev-gcp-database y no marca el job manual como opcional con allow_failure: true. Por tanto, también debe revisarse su efecto sobre el estado global del pipeline; no se debe ejecutarlo solo para eliminar un estado de pipeline bloqueado. El procedimiento excepcional está explicado en teardown.
Artefactos y reportes¶
Los planes binarios y JSON se conservan una semana. Es una dependencia operativa del apply: si la espera de aprobación supera esa conservación, hay que regenerar y revisar el plan. No se incluyen controles explícitos artifacts:access en la configuración revisada.
El YAML declara artifacts:reports:terraform, pero el fichero enviado contiene la salida completa de tofu show -json. La integración documentada de GitLab espera un resumen de acciones create, update y delete. La presencia del tipo de artefacto en YAML no acredita que el widget de merge request funcione correctamente. La transformación al resumen y la restricción de acceso son mejoras recomendadas para el repositorio de infraestructura.
Ramas, merge requests y concurrencia¶
El código de creación incluye jobs de plan y validación en cualquier rama, mientras que los jobs de apply solo existen en main. Sin embargo, validate_kubernetes depende mediante needs de apply_network, y las capas siguientes hacen lo mismo. Por lectura estática, una creación en una rama distinta puede producir un grafo inválido al faltar el job requerido. Debe comprobarse con CI Lint antes de presentar este pipeline como validación de infraestructura apta para cualquier merge request.
Los resource_group limitan la concurrencia por entorno/proveedor/capa; el backend añade su bloqueo. No serializan el ciclo completo entre planificación y aprobación manual. Para evitar planes obsoletos, coordinar las ejecuciones por entorno y regenerar el plan tras cualquier cambio de estado.
Estas observaciones describen el snapshot y no modifican los pipelines de los repositorios originales. El pipeline de documentación entregado en este ZIP es independiente y no aprovisiona ni destruye infraestructura.
Evidencia histórica disponible¶
El pipeline público 2604650152, del 16 de junio de 2026, registra jobs satisfactorios de destrucción de las cuatro capas y el job de Private Service Access; aparecen dos ejecuciones de plan_destroy_database. Corresponde a un commit anterior al snapshot revisado. Es evidencia histórica de una ejecución de retirada, no una prueba de que haya clústeres activos hoy ni de que el HEAD actual se haya ejecutado satisfactoriamente.
Fuentes¶
- Pipeline completo, commit ae1502b0.
- Estados y credenciales, variables, retirada.
- GitLab: reportes de planes en merge requests.
- Memoria §7.2.7, páginas impresas 45–49 (PDF 51–55), figuras 8 y 10: ejecución de infraestructura y estados. Los defaults, las reglas de rama y el job de recuperación se obtienen del código.