---
title: CD (Entrega Continua) — Parte 4: Deploy a Staging y Performance Smoke Tests
url: https://jarroba.com/cd-entrega-continua-parte-4-deploy-a-staging-y-performance-smoke-tests/
author: Ramón Invarato
date: 2026-04-20
modified: 2026-10-21
language: es
license: CC BY-NC-SA 3.0 (https://creativecommons.org/licenses/by-nc-sa/3.0/) — attribution: "CD (Entrega Continua) — Parte 4: Deploy a Staging y Performance Smoke Tests", Ramón Invarato, jarroba.com
categories: Ingeniería del Software, Inteligencia Artificial
tags: ci-cd, cypress, devops, e2e, k6, performance, staging
series: CI/CD y la IA: De la teoría a la práctica (part 9 of 11)
---

# CD (Entrega Continua) — Parte 4: Deploy a Staging y Performance Smoke Tests

> Despliegue en preproducción con paridad a producción, validación E2E y de rendimiento ligero, y aprobación manual antes de producción.

> Esta parte cubre el despliegue en el entorno de preproducción (staging), la validación E2E y de rendimiento ligero, y la aprobación manual antes de promover a producción.

  

## Deploy a Staging

 

Promueve el artefacto ya verificado (misma imagen firmada y SBOM) a un entorno de preproducción que replica la configuración de producción con mayor fidelidad. **Staging** es el último entorno para validar integraciones, performance a escala reducida, pruebas de regresión y validaciones de compliance antes del despliegue a producción.

 

[![](https://jarroba.com/wp-content/uploads/2026/04/1-CD-Entrega-Continua-—-Parte-4-Deploy-a-Staging-y-Performance-Smoke-Tests-Deploy-a-Staging-www.jarroba.com_-1024x978.png)](https://jarroba.com/wp-content/uploads/2026/04/1-CD-Entrega-Continua-—-Parte-4-Deploy-a-Staging-y-Performance-Smoke-Tests-Deploy-a-Staging-www.jarroba.com_.png)

 

### Lo que incluye esta etapa

 
- **Selección del artefacto:** promover la **misma imagen firmada** que pasó Dev y los scans.
- **Provisionamiento de entorno:** aplicar IaC para crear/actualizar recursos (namespaces, ingress, secrets, configmaps) con valores de staging.
- **Configuración de datos:** usar datos sintéticos o copias anonimizadas; preparar fixtures y migraciones necesarias.
- **Despliegue con estrategia realista:** [Helm](https://helm.sh/)/[Kustomize](https://kustomize.io/) con valores de staging; aplicar recursos de red, límites y tolerancias equivalentes a producción.
- **Activación de observabilidad completa:** métricas, trazas distribuidas y logging centralizado con retención adecuada.
- **Ejecución de suites completas:** E2E, performance smoke, tests de seguridad adicionales y validaciones de compliance.
- **Gates y aprobaciones:** gates automáticos y, si procede, **aprobación manual** antes de promover a producción.
- **Registro y trazabilidad:** anotar release con commit SHA, tag de imagen, SBOM y firma; almacenar artefactos y reportes.

 

### Pasos

 
1. Obtener imagen firmada del registry.
2. Verificar firma ([cosign](https://docs.sigstore.dev/cosign/system_config/specifications/)) y SBOM asociado.
3. Aplicar IaC ([Terraform](https://developer.hashicorp.com/terraform) para infra, Helm/Kustomize para manifiestos).
4. Configurar secrets desde [Vault](https://developer.hashicorp.com/vault)/[Secret Manager](https://cloud.google.com/security/products/secret-manager?hl=es); no exponer valores.
5. Desplegar con wait y probes (`helm upgrade --install --wait --timeout`).
6. Ejecutar validaciones automáticas: E2E, contract tests, smoke de performance.
7. Evaluar resultados y ejecutar gates: si OK → marcar listo para producción; si KO → rollback y crear ticket.
8. Aprobación humana opcional para producción (manual approval step).

 

### Buenas prácticas

 
- **Promover el mismo artefacto firmado** entre entornos para garantizar reproducibilidad.
- **Paridad de configuración** con producción en límites, recursos y sidecars; diferencias solo en datos y endpoints externos.
- **Entorno inmutable**: evitar cambios ad-hoc en staging; todo por IaC.
- **Datos anonimizados** o synthetic data para pruebas realistas sin exponer PII.
- **Gates claros**: definir qué fallos bloquean y cuáles generan tickets.
- **Aprobaciones para producción**: integrar un paso de aprobación humana con contexto (logs, métricas, reportes).
- **Rollback automático y plan de mitigación** si las validaciones fallan.
- **Observabilidad y trazabilidad**: anotar release con metadatos y conservar reportes (E2E, perf, security).

 

### Ventajas

 
- Alta confianza antes de producción por la similitud con el entorno real.
- Permite pruebas de integración y compliance en condiciones realistas.
- Reduce riesgos de regresiones y errores de configuración.

 

### Desventajas / riesgos

 
- Coste en recursos y tiempo; pipelines más largos.
- Si no se mantiene paridad, staging puede dar falsos positivos/negativos.
- Gestión de datos sensibles exige controles estrictos.

 

### Ejemplo: job simple GitLab CI para Deploy a Staging

 

```yaml
deploy_to_staging:
  stage: deploy
  image: alpine/helm:3.12.0
  variables:
    NAMESPACE: staging
  before_script:
    - echo "$KUBE_CONFIG_BASE64" | base64 -d > /tmp/kubeconfig
    - export KUBECONFIG=/tmp/kubeconfig
  script:
    - echo "Verifying image signature"
    - cosign verify --key "$COSIGN_PUBKEY" $REGISTRY/$IMAGE_NAME:${IMAGE_TAG}
    - echo "Deploying to staging"
    - helm upgrade --install myapp ./chart \
        --namespace $NAMESPACE \
        --create-namespace \
        --set image.repository=$REGISTRY/$IMAGE_NAME \
        --set image.tag=${IMAGE_TAG} \
        --wait --timeout 10m
    - echo "Annotate release metadata"
    - kubectl -n $NAMESPACE annotate deployment myapp "ci.commit=${CI_COMMIT_SHA}" --overwrite || true
  rules:
    - if: $CI_COMMIT_BRANCH =~ /^release\/.*$/ || $CI_COMMIT_BRANCH == "develop"
```

 

### Ejemplo completo: Deploy a Staging con E2E, Performance y Aprobación manual

 

Este ejemplo ejecuta en staging la batería completa de pruebas de aceptación (E2E) y pruebas de rendimiento a escala reducida, automatiza la evaluación de resultados y expone un **paso de aprobación manual** antes de promover a producción.

 

[![](https://jarroba.com/wp-content/uploads/2026/04/2-CD-Entrega-Continua-—-Parte-4-Deploy-a-Staging-y-Performance-Smoke-Tests-Ejemplo-Deploy-a-Staging-Performance-y-Manual-Approval-www.jarroba.com_-802x1024.png)](https://jarroba.com/wp-content/uploads/2026/04/2-CD-Entrega-Continua-—-Parte-4-Deploy-a-Staging-y-Performance-Smoke-Tests-Ejemplo-Deploy-a-Staging-Performance-y-Manual-Approval-www.jarroba.com_.png)

 

El siguiente pipeline hace lo siguiente:

 
- **Obtiene la imagen firmada** del registry y verifica firma y SBOM.
- **Despliega en staging** con IaC y Helm/Kustomize usando valores de staging.
- **Ejecuta E2E** ([Cypress](https://docs.cypress.io/app/end-to-end-testing/writing-your-first-end-to-end-test) o [Newman](https://blog.postman.com/how-postman-uses-postman-e2e-testing-collaboration/)) contra el entorno staging y publica reportes [JUnit/HTML](https://www.baeldung.com/java-gradle-junit-generate-html-report).
- **Ejecuta pruebas de rendimiento** con [k6](https://k6.io/) para medir latencia y throughput en escenarios críticos.
- **Evalúa gates automáticos**: fallos E2E o umbrales de performance (p. ej. p95 > X ms, error rate > Y%) bloquean la promoción.
- **Publica artefactos y reportes** para auditoría y trazabilidad.
- **Si todo OK** crea un paso de aprobación manual para promover a producción.
- **Si KO** realiza rollback y crea ticket de remediación con evidencia.

 

```yaml
stages:
  - staging-deploy
  - staging-validate
  - approval

variables:
  REGISTRY: registry.example.com
  IMAGE_NAME: myapp
  IMAGE_TAG: ${IMAGE_TAG}
  NAMESPACE: staging
  HELM_CHART_PATH: ./chart
  K6_SCRIPT: tests/k6/staging-scenario.js
  CYPRESS_CONFIG: cypress.json

deploy_to_staging:
  stage: staging-deploy
  image: alpine/helm:3.12.0
  before_script:
    - echo "$KUBE_CONFIG_BASE64" | base64 -d > /tmp/kubeconfig
    - export KUBECONFIG=/tmp/kubeconfig
  script:
    - echo "Verify image signature"
    - cosign verify --key "$COSIGN_PUBKEY" $REGISTRY/$IMAGE_NAME:$IMAGE_TAG
    - echo "Deploying to staging"
    - helm upgrade --install myapp $HELM_CHART_PATH \
        --namespace $NAMESPACE \
        --create-namespace \
        --set image.repository=$REGISTRY/$IMAGE_NAME \
        --set image.tag=$IMAGE_TAG \
        --wait --timeout 10m
    - kubectl -n $NAMESPACE annotate deployment myapp "ci.commit=${CI_COMMIT_SHA}" --overwrite || true
  rules:
    - if: $CI_COMMIT_BRANCH =~ /^release\/.*$/ || $CI_COMMIT_BRANCH == "develop"

e2e_and_performance:
  stage: staging-validate
  image: node:20-alpine
  needs:
    - job: deploy_to_staging
      artifacts: false
  before_script:
    - apk add --no-cache curl bash jq
    - npm ci
    - echo "$KUBE_CONFIG_BASE64" | base64 -d > /tmp/kubeconfig
    - export KUBECONFIG=/tmp/kubeconfig
  script:
    - echo "Discover service endpoint"
    - SERVICE_HOST=$(kubectl -n $NAMESPACE get svc myapp -o jsonpath='{.status.loadBalancer.ingress[0].hostname}' || kubectl -n $NAMESPACE get svc myapp -o jsonpath='{.spec.clusterIP}')
    - echo "Service host: $SERVICE_HOST"
    # Run E2E with Cypress headless and export JUnit
    - npx cypress run --config-file $CYPRESS_CONFIG --env baseUrl="http://$SERVICE_HOST" --reporter junit --reporter-options "mochaFile=reports/cypress-junit-[hash].xml"
    - |
      if [ $? -ne 0 ]; then
        echo "E2E tests failed" >&2
        exit 10
      fi
    # Run k6 performance scenario
    - apk add --no-cache curl
    - wget -q -O /usr/local/bin/k6 https://github.com/grafana/k6/releases/download/v0.45.0/k6-v0.45.0-linux64 && chmod +x /usr/local/bin/k6
    - k6 run --out json=reports/k6-results.json $K6_SCRIPT || true
    - |
      ERR_RATE=$(jq '[.metrics.iterations.rate] | add' reports/k6-results.json || echo 0)
      P95=$(jq '.metrics["http_req_duration"].p[95]' reports/k6-results.json || echo 0)
      echo "k6 p95: $P95 ms, err_rate: $ERR_RATE"
      if (( $(echo "$P95 > 500" | bc -l) )); then
        echo "Performance threshold exceeded: p95 > 500ms" >&2
        exit 11
      fi
  artifacts:
    when: always
    paths:
      - reports/
    reports:
      junit: reports/cypress-junit-*.xml
  rules:
    - if: $CI_COMMIT_BRANCH =~ /^release\/.*$/ || $CI_COMMIT_BRANCH == "develop"

staging_to_prod_approval:
  stage: approval
  image: alpine:3.18
  when: manual
  allow_failure: false
  script:
    - echo "Manual approval to promote to production. Review reports and metrics before approving."
  rules:
    - if: $CI_COMMIT_BRANCH =~ /^release\/.*$/ || $CI_COMMIT_BRANCH == "develop"
```

 

**Notas:**

 
- **E2E** usa Cypress en modo headless y exporta JUnit para integración con [GitLab Test Reports](https://docs.gitlab.com/ci/testing/unit_test_reports/).
- **Performance** usa k6 y guarda resultados JSON; el job evalúa umbrales básicos y falla si se exceden. Ajusta métricas y umbrales a tu SLA.
- **Artifacts**: todos los reportes se guardan para auditoría.
- **Approval**: el job `staging_to_prod_approval` es manual; al aprobarlo se puede disparar el job de promoción a producción que use el mismo artefacto firmado.
- **Exit codes** diferenciados para distinguir fallos E2E y performance.

 

### IA

 
- **Mejora**: optimiza valores de recursos, sugiere configuraciones de tolerancia, genera tests E2E y scripts de carga, prioriza findings de seguridad y performance.
- **Automatización**: puede rellenar plantillas de issue con evidencia, proponer parches y generar PRs de remediación.
- **Limitación**: no sustituye la ejecución real ni la aprobación humana en decisiones de riesgo; no puede firmar artefactos ni ejecutar despliegues por sí sola sin integración.

  

## Performance Smoke Tests

 

Ejecuta pruebas de rendimiento ligeras y deterministas tras un despliegue para validar que los endpoints críticos cumplen requisitos básicos de latencia y estabilidad antes de avanzar a pruebas de carga completas o a producción. Buscan detectar degradaciones evidentes (p95/p99, error rate) que indicarían que el despliegue no es apto para promoción.

 

[![](https://jarroba.com/wp-content/uploads/2026/04/3-CD-Entrega-Continua-—-Parte-4-Deploy-a-Staging-y-Performance-Smoke-Tests-Performance-Smoke-Tests-www.jarroba.com_-563x1024.png)](https://jarroba.com/wp-content/uploads/2026/04/3-CD-Entrega-Continua-—-Parte-4-Deploy-a-Staging-y-Performance-Smoke-Tests-Performance-Smoke-Tests-www.jarroba.com_.png)

 

### Pasos

 
- **Selección de escenarios críticos:** elegir 2–6 rutas o flujos representativos (login, búsqueda, checkout, endpoints de lectura intensiva).
- **Definición de métricas y umbrales:** p50/p95/p99, latencia máxima aceptable, tasa de errores máxima, throughput mínimo.
- **Ejecución rápida y controlada:** usar herramientas como **k6** para escenarios cortos (30s–2min) con carga reducida.
- **Medición y evaluación automática:** calcular percentiles y error rate; comparar con umbrales y decidir pasar/fallar.
- **Salida estructurada:** exportar resultados en JSON/CSV para ingestión en el pipeline y para adjuntar a reportes.
- **Acciones según resultado:** si se exceden umbrales críticos → bloquear promoción, crear ticket y/o rollback; si están dentro de límites → continuar.

 

### Buenas prácticas

 
- **Mantener tests cortos y deterministas**: objetivo < 2–5 minutos para no alargar pipelines.
- **Elegir escenarios de alto impacto** en lugar de cubrir todo el API.
- **Ejecutar en staging con paridad de recursos** para obtener mediciones representativas.
- **Correlacionar con trazas y métricas** para identificar la causa raíz (CPU, GC, latencia de DB).
- **Aislar ruido**: ejecutar en ventanas controladas y limpiar datos entre runs.
- **Definir umbrales basados en SLAs** y revisarlos periódicamente.
- **Automatizar decisiones**: pasar/fallar pipeline según reglas claras; generar reportes y tickets con evidencia.

 

### Ventajas

 
- **Detección temprana de degradaciones** antes de pruebas de carga completas.
- **Bajo coste temporal** comparado con pruebas de stress.
- **Automatización fácil** en CI/CD para gates rápidos.

 

### Desventajas

 
- **Cobertura limitada**: no sustituye pruebas de carga o stress.
- **Resultados sensibles al entorno**: si staging no replica producción, las métricas pueden engañar.
- **Posible flakiness** si no se controlan variables externas.

 

### Herramientas

 
- **[k6](https://k6.io/)**: ideal para scripts JS ligeros y export JSON.
- **[Gatling](https://gatling.io/) / [Locust](https://locust.io/)**: alternativas para escenarios más complejos.
- **[Grafana Tempo](https://grafana.com/docs/tempo/latest/) / [Prometheus](https://prometheus.io/)**: para correlacionar métricas y trazas.

 

### Ejemplos

 

**Ejemplo k6 minimal** (`tests/k6/perf-smoke.js`):

 

```javascript
import http from 'k6/http';
import { check } from 'k6';
export let options = { vus: 10, duration: '1m' };
export default function () {
  let res = http.get(`${__ENV.BASE_URL}/api/v1/critical`);
  check(res, { 'status 200': (r) => r.status === 200 });
}
```

 

**Evaluación simple** (bash):

 

```bash
k6 run --out json=perf.json tests/k6/perf-smoke.js
P95=$(jq '.metrics.http_req_duration.p[95]' perf.json)
if (( $(echo "$P95 > 500" | bc -l) )); then exit 1; fi
```

 

**GitLab CI job:**

 

```yaml
performance_smoke:
  stage: validate
  image: loadimpact/k6:latest
  variables:
    BASE_URL: "http://myapp-staging.example.com"
    K6_SCRIPT: tests/k6/perf-smoke.js
  script:
    - k6 run --out json=perf.json $K6_SCRIPT
    - P95=$(jq '.metrics.http_req_duration.p[95]' perf.json)
    - ERR_RATE=$(jq '.metrics.http_req_failed.rate' perf.json)
    - echo "p95=$P95 ms err_rate=$ERR_RATE"
    - |
      if (( $(echo "$P95 > 500" | bc -l) )) || (( $(echo "$ERR_RATE > 0.01" | bc -l) )); then
        echo "Performance smoke failed: p95 or error rate exceeded" >&2
        exit 1
      fi
  artifacts:
    when: always
    paths:
      - perf.json
  rules:
    - if: $CI_COMMIT_BRANCH =~ /^release\/.*$/ || $CI_COMMIT_BRANCH == "develop"
```

 

### IA

 
- **Mejora**: la IA puede **sugerir escenarios críticos** a partir de logs y telemetría histórica, proponer umbrales realistas y generar scripts k6 automáticamente.
- **Diagnóstico**: al fallar un test, correlacionar métricas, agrupar anomalías y proponer la causa raíz (latencia de DB, saturación de CPU).
- **Automatización**: generar tickets con resumen ejecutivo, evidencia y recomendaciones; proponer PRs con ajustes de configuración (timeouts, pool sizes).
- **Limitación**: la IA no sustituye la ejecución real ni la validación humana de cambios de arquitectura.

  

[En el siguiente artículo, **“CD — Parte 5: LCA — Load, Stress y Chaos Engineering”**, entraremos en la validación de resiliencia real: pruebas de carga, estrés y caos para asegurar que el sistema se mantiene estable y recuperable bajo condiciones extremas.](https://jarroba.com/cd-entrega-continua-parte-5-lca-load-stress-y-chaos-engineering/)

## Serie: CI/CD y la IA: De la teoría a la práctica

1. [CI/CD: Introducción — qué es, por qué importa y quién lo hace](https://jarroba.com/ci-cd-introduccion-que-es-por-que-importa-y-quien-lo-hace.md)
2. [CI/CD: Conceptos básicos — pipeline, job, stage, step y gates](https://jarroba.com/ci-cd-conceptos-basicos-pipeline-job-stage-step-y-gates.md)
3. [CI/CD: Branching, Git Flow y Pull Requests](https://jarroba.com/ci-cd-branching-git-flow-y-pull-requests.md)
4. [Pre-CI: Arquitectura general del pipeline CI/CD y comprobaciones previas](https://jarroba.com/pre-ci-arquitectura-general-del-pipeline-ci-cd-y-comprobaciones-previas.md)
5. [CI (Integración Continua): análisis, tests, calidad y seguridad](https://jarroba.com/ci-integracion-continua-analisis-tests-calidad-y-seguridad.md)
6. [CD (Entrega Continua) — Parte 1: empaquetado, SBOM y remediación](https://jarroba.com/cd-entrega-continua-parte-1-empaquetado-sbom-y-remediacion.md)
7. [CD (Entrega Continua) — Parte 2: Image Scan y Service Tests](https://jarroba.com/cd-entrega-continua-parte-2-image-scan-y-service-tests.md)
8. [CD (Entrega Continua) — Parte 3: Deploy a Dev y Smoke Tests](https://jarroba.com/cd-entrega-continua-parte-3-deploy-a-dev-y-smoke-tests.md)
9. [CD (Entrega Continua) — Parte 4: Deploy a Staging y Performance Smoke Tests](https://jarroba.com/cd-entrega-continua-parte-4-deploy-a-staging-y-performance-smoke-tests.md)
10. [CD (Entrega Continua) — Parte 5: LCA — Load, Stress y Chaos Engineering](https://jarroba.com/cd-entrega-continua-parte-5-lca-load-stress-y-chaos-engineering.md)
11. [CD (Entrega Continua) — Parte 6: Validaciones finales, Manual Approval y Deploy a Producción](https://jarroba.com/cd-entrega-continua-parte-6-validaciones-finales-manual-approval-y-deploy-a-produccion.md)

