Ir al contenido

Golden Pipeline — Template CI/CD Centralizado


Golden Pipeline HERA — Flujo End-to-End
1
Init
Lee manifiestos
product-manifest.yml service-manifest.yml
2
Validate
JSON Schema
Gate
3
Build
Por tech_stack
Docker image
4
Security
Feature flags
SAST SCA Secrets
5
Deploy
Helm + values
Labels HERA Resources WI
6
Post-Deploy
KEDA + Observatory
ScaledObject Metrics

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.md

El equipo de plataforma es el único que modifica este repositorio. Los equipos de desarrollo lo consumen, no lo modifican.


Cada release es un tag que sigue SemVer:

TipoCuándoEjemplo
Major (breaking)Nueva etapa, cambio de schema de manifiestov3.0.0
Minor (feature)Nueva herramienta, nuevo stack soportadov2.1.0
Patch (fix)Corrección de bug en un job existentev2.1.1

Además de los tags numéricos, existe un tag stable que el equipo de plataforma controla:

TagApunta aQuién lo mueveUso
stableÚltima versión validadaSolo plataformaDefault para el 90% de proyectos
latestÚltima versión publicadaAutomático con cada releaseSolo pilotos
vX.Y.ZVersión específicaInmutableProyectos que necesitan pin

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.yml

Donde <URL_GITLAB> es la URL de la instancia GitLab corporativa y <GRUPO> es el grupo raíz de HERA.

Si una versión nueva tiene un bug:

  1. Plataforma detecta el problema en la versión v2.2.0
  2. Mueve el tag stable a la versión anterior: v2.1.0
  3. Los proyectos que apuntan a stable vuelven a la versión funcional automáticamente en su siguiente ejecución
  4. Los pilotos en v2.2.0 explícito no se afectan — pueden decidir si regresan o esperan el fix

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

CampoTipo / FormatoObligatorioDescripción
product.namekebab-case, lowercaseNombre canónico del producto (p. ej. tienda-herdez)
product.domainenum de dominios de negocioecommerce, marketing, supply-chain, sitios, integracion, cms, datos, apps, shared-services
product.brandenum de marcasgrupo-herdez, barcel, donamaria, corporativo, interno
product.owner.tech_leademail corporativoResponsable técnico del producto
product.owner.product_owneremail corporativoProduct Owner del negocio
classification.criticalityenumCriticidad (ver Valores permitidos)
classification.data_classificationenumSensibilidad de datos (ver Valores permitidos)
active_versionstringVersión activa en PRD (determina qué subcarpeta de servicios se despliega)
partnerstringPartner externo responsable (si aplica)
stateenumcandidate, active-dev, active-qa, active-prd, legacy, retired
infrastructure.namespacekebab-caseNamespace 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}stringCluster GKE por ambiente
keda.schedule.timezoneIANA timezoneZona horaria del cron (p. ej. America/Mexico_City)
keda.schedule.active_startcron expressionInicio del horario activo (scale-up)
keda.schedule.active_endcron expressionFin del horario activo (scale-down)
homologationenumNivel 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

CampoTipo / FormatoObligatorioDescripción
service.namekebab-case, lowercaseNombre del repo de servicio
service.categoryenum cerrado de 13 valoresVer Valores permitidos — determina el pipeline y SLOs
service.layerenumexperience, domain, integration, platform
service.tech_stackenumnodejs, dotnet, python, php, java, go — determina el pipeline base
service.tallaenummicro, estandar, intensivo — tier de consumo de recursos
resources.requests.{cpu,memory}K8s resource stringValor generado por la Calculadora de Recursos (herramienta del ecosistema HERA)
resources.limits.{cpu,memory}K8s resource stringValor generado por la Calculadora
scaling.hpa.min_replicasinteger ≥ 2En PRD el mínimo corporativo es 2 (HA multi-zona)
scaling.hpa.max_replicasintegerTope superior del HPA
scaling.hpa.target_cpuinteger (porcentaje)Umbral de CPU que dispara scale-up
scaling.keda.scalerenumcron, pubsub, prometheus, none — habilita KEDA scale-to-zero en DEV/QA
security.pci_cdebooleantrue si el servicio forma parte del entorno PCI-CDE (escaneos adicionales)
security.enable_veracodebooleanHabilita Veracode SAST (servicios con requisitos regulatorios)
security.workload_identity.gsaGoogle SA nameGoogle Service Account vinculada al KSA vía Workload Identity
probes.liveness.pathHTTP pathEndpoint de liveness probe
probes.liveness.initial_delayinteger (segundos)Retardo inicial antes del primer probe
probes.readiness.pathHTTP pathEndpoint de readiness probe
probes.readiness.initial_delayinteger (segundos)Retardo inicial antes del primer probe

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.

CampoValores válidos
service.categoryfrontend, bff, experience, backend, data, cms, integration, event, worker, platform, edge, infra, docs
service.layerexperience, domain, integration, platform
service.tech_stacknodejs, dotnet, python, php, java, go
service.tallamicro, estandar, intensivo
scaling.keda.scalercron, pubsub, prometheus, none
classification.criticalitylow, medium, high, critical
classification.data_classificationpublic, internal, confidential, restricted

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»
HerramientaControlDefaultCuándo cambia
SonarQube (SAST)Variable de grupoONSolo plataforma puede desactivar (repos de IaC/docs)
Docker Scout (SCA)Variable de grupoONSolo plataforma puede desactivar
TruffleHog (Secrets)Sin flagSiempre ONNunca desactivable — un secreto filtrado es una brecha inmediata
Veracodesecurity.enable_veracode en service-manifestOFFTech Lead activa para servicios del CDE (PCI-DSS)
OWASP ZAP (DAST)Variable de grupoON solo en QASolo post-deploy en ambiente QA

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 pipeline
podLabels:
# 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.


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 esto
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: backend-checkout-service-schedule
namespace: tienda-herdez
spec:
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.


GitLab hereda variables del grupo padre al hijo. Esto evita configurar los mismos valores 800 veces:

NivelQué se configuraEjemplo
Root group (grupo-herdez/)Herramientas globales, tokens de plataformaSONAR_HOST_URL, DOCKER_REGISTRY, HERA_READ_TOKEN
Product subgroup (tienda-herdez/)Proyectos GCP del productoGCP_PROJECT_DEV, GCP_PROJECT_QA, GCP_PROJECT_PRD
ProjectSecretos de build-time del servicio, por ambienteK8S_SECRET_API_URL (scoped a qa), ADDITIONAL_HOSTS (scoped a prd)
GCP Secret ManagerSecretos de runtimeDB passwords, API keys, tokens OAuth — nunca en GitLab CI

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étricaQué 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?
CondiciónSeveridadCanal
Proyecto crítico con pipeline rojo mayor a 24hAltaGoogle Chat #hera-security-alerts
Mas del 20% de proyectos en versión desactualizadaMediaGoogle Chat #hera-platform-alerts
Mas de 50 servicios DEV/QA sin KEDABajaReporte FinOps mensual

DocumentoRelación
Estructura de RepositoriosDefine la jerarquía de grupos GitLab y el product-manifest.yml
Estándares de EtiquetadoLos labels que el pipeline inyecta automáticamente
Workload IdentityEl serviceAccount que el pipeline configura en cada deploy
Gestión de SecretosSeparación de secretos build-time (GitLab) vs. runtime (Secret Manager)
Clasificación de ServiciosLas 13 categorías válidas para service.category