Golden Pipeline — Template CI/CD Centralizado
Flujo del Golden Pipeline
Sección titulada «Flujo del Golden Pipeline»1. Arquitectura del repositorio de templates
Sección titulada «1. Arquitectura del repositorio de templates»El template vive en un repositorio centralizado gestionado por el equipo de plataforma:
grupo-herdez/platform/pipelines/gitlab-ci/├── base/│ ├── stages.yml ← 6 etapas estándar + post-deploy│ ├── rules.yml ← Reglas comunes de ejecución│ └── init-manifest.yml ← Lee product-manifest + service-manifest├── validate/│ ├── schema-validation.yml ← Valida manifiestos contra JSON Schema│ └── schemas/│ ├── product-manifest.schema.json│ └── service-manifest.schema.json├── stacks/│ ├── nodejs.yml│ ├── dotnet.yml│ ├── python.yml│ ├── php.yml│ └── java.yml├── security/│ ├── sonarqube.yml ← SAST (default: ON)│ ├── docker-scout.yml ← SCA (default: ON)│ ├── trufflehog.yml ← Secrets (siempre ON, sin flag)│ ├── veracode.yml ← Solo CDE (default: OFF)│ └── zap-dast.yml ← DAST post-deploy en QA├── deploy/│ ├── helm-gke.yml ← Deploy + generación de values│ └── keda-config.yml ← ScaledObject para DEV/QA├── observability/│ ├── version-check.yml ← Warning si template desactualizado│ └── pipeline-metrics.yml ← Reporta al Pipeline Observatory├── CHANGELOG.md└── README.mdEl equipo de plataforma es el único que modifica este repositorio. Los equipos de desarrollo lo consumen, no lo modifican.
2. Versionado y rollback
Sección titulada «2. Versionado y rollback»Tags semánticos
Sección titulada «Tags semánticos»Cada release es un tag que sigue SemVer:
| Tipo | Cuándo | Ejemplo |
|---|---|---|
| Major (breaking) | Nueva etapa, cambio de schema de manifiesto | v3.0.0 |
| Minor (feature) | Nueva herramienta, nuevo stack soportado | v2.1.0 |
| Patch (fix) | Corrección de bug en un job existente | v2.1.1 |
Tag stable para rollback centralizado
Sección titulada «Tag stable para rollback centralizado»Además de los tags numéricos, existe un tag stable que el equipo de plataforma controla:
| Tag | Apunta a | Quién lo mueve | Uso |
|---|---|---|---|
stable | Última versión validada | Solo plataforma | Default para el 90% de proyectos |
latest | Última versión publicada | Automático con cada release | Solo pilotos |
vX.Y.Z | Versión específica | Inmutable | Proyectos que necesitan pin |
Configuración en cada proyecto GitLab
Sección titulada «Configuración en cada proyecto GitLab»En Settings → CI/CD → CI/CD configuration file, se configura la URL del template con el tag deseado:
<URL_GITLAB>/<GRUPO>/templates/gitlab-ci/-/raw/stable/.gitlab-ci.ymlDonde <URL_GITLAB> es la URL de la instancia GitLab corporativa y <GRUPO> es el grupo raíz de HERA.
Flujo de rollback
Sección titulada «Flujo de rollback»Si una versión nueva tiene un bug:
- Plataforma detecta el problema en la versión v2.2.0
- Mueve el tag
stablea la versión anterior: v2.1.0 - Los proyectos que apuntan a
stablevuelven a la versión funcional automáticamente en su siguiente ejecución - Los pilotos en
v2.2.0explícito no se afectan — pueden decidir si regresan o esperan el fix
3. Manifiestos como fuente de verdad
Sección titulada «3. Manifiestos como fuente de verdad»HERA define dos manifiestos YAML que el pipeline consume como contrato declarativo: uno por producto (product-manifest.yml) y uno por servicio (service-manifest.yml). El portal documenta su schema como contrato; el YAML canónico (con valores de ejemplo) vive en los templates oficiales.
product-manifest.yml — en _shared/ del producto
Sección titulada «product-manifest.yml — en _shared/ del producto»Define la identidad, clasificación y configuración que aplica a todos los servicios del producto.
Ubicación en el repo: grupo-herdez/products/<dominio>/<producto>/_shared/product-manifest.yml
Schema del product-manifest.yml
Sección titulada «Schema del product-manifest.yml»| Campo | Tipo / Formato | Obligatorio | Descripción |
|---|---|---|---|
product.name | kebab-case, lowercase | ✅ | Nombre canónico del producto (p. ej. tienda-herdez) |
product.domain | enum de dominios de negocio | ✅ | ecommerce, marketing, supply-chain, sitios, integracion, cms, datos, apps, shared-services |
product.brand | enum de marcas | ✅ | grupo-herdez, barcel, donamaria, corporativo, interno |
product.owner.tech_lead | email corporativo | ✅ | Responsable técnico del producto |
product.owner.product_owner | email corporativo | ✅ | Product Owner del negocio |
classification.criticality | enum | ✅ | Criticidad (ver Valores permitidos) |
classification.data_classification | enum | ✅ | Sensibilidad de datos (ver Valores permitidos) |
active_version | string | ✅ | Versión activa en PRD (determina qué subcarpeta de servicios se despliega) |
partner | string | ❌ | Partner externo responsable (si aplica) |
state | enum | ✅ | candidate, active-dev, active-qa, active-prd, legacy, retired |
infrastructure.namespace | kebab-case | ✅ | Namespace Kubernetes único por producto |
infrastructure.gcp_project.{dev,qa,prd} | string (ID GCP) | ✅ | Project GCP por ambiente, siguiendo Estándares de Naming |
infrastructure.cluster.{dev,qa,prd} | string | ✅ | Cluster GKE por ambiente |
keda.schedule.timezone | IANA timezone | ❌ | Zona horaria del cron (p. ej. America/Mexico_City) |
keda.schedule.active_start | cron expression | ❌ | Inicio del horario activo (scale-up) |
keda.schedule.active_end | cron expression | ❌ | Fin del horario activo (scale-down) |
homologation | enum | ✅ | Nivel de homologación (gold, silver, bronze) |
service-manifest.yml — en cada repo de servicio
Sección titulada «service-manifest.yml — en cada repo de servicio»Define la configuración específica del servicio: stack tecnológico, recursos, seguridad y probes.
Ubicación en el repo: grupo-herdez/products/<dominio>/<producto>/<version>/<servicio>/service-manifest.yml
Schema del service-manifest.yml
Sección titulada «Schema del service-manifest.yml»| Campo | Tipo / Formato | Obligatorio | Descripción |
|---|---|---|---|
service.name | kebab-case, lowercase | ✅ | Nombre del repo de servicio |
service.category | enum cerrado de 13 valores | ✅ | Ver Valores permitidos — determina el pipeline y SLOs |
service.layer | enum | ✅ | experience, domain, integration, platform |
service.tech_stack | enum | ✅ | nodejs, dotnet, python, php, java, go — determina el pipeline base |
service.talla | enum | ✅ | micro, estandar, intensivo — tier de consumo de recursos |
resources.requests.{cpu,memory} | K8s resource string | ✅ | Valor generado por la Calculadora de Recursos (herramienta del ecosistema HERA) |
resources.limits.{cpu,memory} | K8s resource string | ✅ | Valor generado por la Calculadora |
scaling.hpa.min_replicas | integer ≥ 2 | ✅ | En PRD el mínimo corporativo es 2 (HA multi-zona) |
scaling.hpa.max_replicas | integer | ✅ | Tope superior del HPA |
scaling.hpa.target_cpu | integer (porcentaje) | ✅ | Umbral de CPU que dispara scale-up |
scaling.keda.scaler | enum | ✅ | cron, pubsub, prometheus, none — habilita KEDA scale-to-zero en DEV/QA |
security.pci_cde | boolean | ✅ | true si el servicio forma parte del entorno PCI-CDE (escaneos adicionales) |
security.enable_veracode | boolean | ❌ | Habilita Veracode SAST (servicios con requisitos regulatorios) |
security.workload_identity.gsa | Google SA name | ✅ | Google Service Account vinculada al KSA vía Workload Identity |
probes.liveness.path | HTTP path | ✅ | Endpoint de liveness probe |
probes.liveness.initial_delay | integer (segundos) | ✅ | Retardo inicial antes del primer probe |
probes.readiness.path | HTTP path | ✅ | Endpoint de readiness probe |
probes.readiness.initial_delay | integer (segundos) | ✅ | Retardo inicial antes del primer probe |
4. Validación con JSON Schema
Sección titulada «4. Validación con JSON Schema»El pipeline valida que los valores del service-manifest.yml pertenezcan al catálogo cerrado de HERA antes de ejecutar cualquier job. Esto evita errores como talla: grande o category: api que pasarían silenciosamente.
Valores permitidos (catálogo cerrado)
Sección titulada «Valores permitidos (catálogo cerrado)»| Campo | Valores válidos |
|---|---|
service.category | frontend, bff, experience, backend, data, cms, integration, event, worker, platform, edge, infra, docs |
service.layer | experience, domain, integration, platform |
service.tech_stack | nodejs, dotnet, python, php, java, go |
service.talla | micro, estandar, intensivo |
scaling.keda.scaler | cron, pubsub, prometheus, none |
classification.criticality | low, medium, high, critical |
classification.data_classification | public, internal, confidential, restricted |
Ejemplo de error
Sección titulada «Ejemplo de error»Si un desarrollador configura un valor inválido:
❌ service-manifest.yml inválido: 'grande' is not one of ['micro', 'estandar', 'intensivo'] Campo: service.talla Valores permitidos: ['micro', 'estandar', 'intensivo']El pipeline se detiene en la etapa Validate — no llega a build ni a deploy.
5. Feature flags para herramientas de seguridad
Sección titulada «5. Feature flags para herramientas de seguridad»| Herramienta | Control | Default | Cuándo cambia |
|---|---|---|---|
| SonarQube (SAST) | Variable de grupo | ON | Solo plataforma puede desactivar (repos de IaC/docs) |
| Docker Scout (SCA) | Variable de grupo | ON | Solo plataforma puede desactivar |
| TruffleHog (Secrets) | Sin flag | Siempre ON | Nunca desactivable — un secreto filtrado es una brecha inmediata |
| Veracode | security.enable_veracode en service-manifest | OFF | Tech Lead activa para servicios del CDE (PCI-DSS) |
| OWASP ZAP (DAST) | Variable de grupo | ON solo en QA | Solo post-deploy en ambiente QA |
6. Generación automática de Helm values
Sección titulada «6. Generación automática de Helm values»El pipeline genera un values.yaml completo con todos los estándares HERA leyendo los manifiestos. El desarrollador nunca configura labels ni resources manualmente — el pipeline lo hace:
# Generado automáticamente por el pipelinepodLabels: # Estándares K8s app.kubernetes.io/name: "backend-checkout-service" app.kubernetes.io/version: "3.0.1" app.kubernetes.io/component: "domain" app.kubernetes.io/part-of: "tienda-herdez" app.kubernetes.io/managed-by: "hera-pipeline" # Labels de negocio HERA hera.grupoherdez.com/domain: "ecommerce" hera.grupoherdez.com/product: "tienda-herdez" hera.grupoherdez.com/brand: "grupo-herdez" hera.grupoherdez.com/criticality: "critical" hera.grupoherdez.com/data-classification: "restricted" hera.grupoherdez.com/partner: "partner-beta" hera.grupoherdez.com/lifecycle: "active"
resources: requests: cpu: "200m" memory: "256Mi" limits: cpu: "400m" memory: "512Mi"
serviceAccount: name: "backend-checkout-service-ksa" annotations: iam.gke.io/gcp-service-account: "gsa-tienda-herdez-checkout@ghdz-grupo-ext-sites-prd.iam.gserviceaccount.com"Si el repo tiene un auto-deploy-values.yaml con configuraciones adicionales (probes, ports), el pipeline hace merge — las configuraciones del repo se suman, pero nunca sobreescriben labels ni resources.
7. KEDA post-deploy (DEV/QA)
Sección titulada «7. KEDA post-deploy (DEV/QA)»Después del deploy exitoso en DEV o QA, el pipeline genera automáticamente un ScaledObject de KEDA leyendo el schedule del product-manifest.yml:
# Generado automáticamente — el desarrollador no escribe estoapiVersion: keda.sh/v1alpha1kind: ScaledObjectmetadata: name: backend-checkout-service-schedule namespace: tienda-herdezspec: scaleTargetRef: name: backend-checkout-service minReplicaCount: 0 maxReplicaCount: 6 triggers: - type: cron metadata: timezone: "America/Mexico_City" start: "0 8 * * 1-5" end: "0 20 * * 1-5" desiredReplicas: "3"En producción, el pipeline NO crea ScaledObject de Cron. Solo genera el HPA estándar con minReplicas mayor o igual a 2.
8. Jerarquía de variables GitLab
Sección titulada «8. Jerarquía de variables GitLab»GitLab hereda variables del grupo padre al hijo. Esto evita configurar los mismos valores 800 veces:
| Nivel | Qué se configura | Ejemplo |
|---|---|---|
Root group (grupo-herdez/) | Herramientas globales, tokens de plataforma | SONAR_HOST_URL, DOCKER_REGISTRY, HERA_READ_TOKEN |
Product subgroup (tienda-herdez/) | Proyectos GCP del producto | GCP_PROJECT_DEV, GCP_PROJECT_QA, GCP_PROJECT_PRD |
| Project | Secretos de build-time del servicio, por ambiente | K8S_SECRET_API_URL (scoped a qa), ADDITIONAL_HOSTS (scoped a prd) |
| GCP Secret Manager | Secretos de runtime | DB passwords, API keys, tokens OAuth — nunca en GitLab CI |
9. Pipeline Observatory
Sección titulada «9. Pipeline Observatory»Con 800 servicios, el equipo de plataforma necesita visibilidad agregada. El Pipeline Observatory es un job scheduled semanal que consume la API de GitLab y reporta:
| Métrica | Qué responde |
|---|---|
| Distribución de versiones | ¿Cuántos proyectos están en stable vs. versiones antiguas? |
| Tasa de fallos por herramienta | ¿SonarQube falla más que Docker Scout? ¿Hay un patrón? |
| Cobertura de manifiestos | ¿Cuántos proyectos aún no tienen service-manifest.yml? |
| Servicios sin KEDA en DEV/QA | ¿Cuántos servicios corren 24/7 sin scale-to-zero? |
| Templates desactualizados | ¿Quién está a 2+ minor versions de atraso? |
Alertas automáticas
Sección titulada «Alertas automáticas»| Condición | Severidad | Canal |
|---|---|---|
| Proyecto crítico con pipeline rojo mayor a 24h | Alta | Google Chat #hera-security-alerts |
| Mas del 20% de proyectos en versión desactualizada | Media | Google Chat #hera-platform-alerts |
| Mas de 50 servicios DEV/QA sin KEDA | Baja | Reporte FinOps mensual |
10. Documentos relacionados
Sección titulada «10. Documentos relacionados»| Documento | Relación |
|---|---|
| Estructura de Repositorios | Define la jerarquía de grupos GitLab y el product-manifest.yml |
| Estándares de Etiquetado | Los labels que el pipeline inyecta automáticamente |
| Workload Identity | El serviceAccount que el pipeline configura en cada deploy |
| Gestión de Secretos | Separación de secretos build-time (GitLab) vs. runtime (Secret Manager) |
| Clasificación de Servicios | Las 13 categorías válidas para service.category |