---
title: CD (Entrega Continua) — Parte 3: Deploy a Dev y Smoke Tests
url: https://jarroba.com/cd-entrega-continua-parte-3-deploy-a-dev-y-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 3: Deploy a Dev y Smoke Tests", Ramón Invarato, jarroba.com
categories: Ingeniería del Software, Inteligencia Artificial
tags: ci-cd, deploy, devops, helm, Kubernetes, smoke-tests
series: CI/CD y la IA: De la teoría a la práctica (part 8 of 11)
---

# CD (Entrega Continua) — Parte 3: Deploy a Dev y Smoke Tests

> Despliegue del artefacto verificado en el entorno de desarrollo y validación rápida con smoke tests para detectar fallos evidentes.

> Esta parte cubre el primer despliegue real del ciclo: el deploy al entorno de desarrollo y la validación inmediata mediante smoke tests para confirmar que el servicio está vivo y funciona.

  

## Deploy a Dev

 

Es un despliegue controlado del artefacto o imagen en un entorno de desarrollo que replica la configuración de producción en lo esencial. Incluye provisión con IaC (Infrastructure as Code), gestión de secrets, activación de observabilidad y ejecución de smoke tests, para dar feedback rápido a desarrolladores antes de promover a entornos superiores.

 

Este paso se ejecuta **después del merge** a la rama destino (por ejemplo `develop` o `release/x.y`), o bien como pipeline independiente si se usa promoción de artefactos.

 

Se recomienda promover la **misma imagen firmada** entre entornos y usar entornos efímeros para PRs.

 

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

 

### Dos modelos de pipeline

 

Se recomienda usar **pipeline por rama** para entornos de integración y preproducción (por su flexibilidad), y **promoción de artefactos** para producción (por la trazabilidad y reproducibilidad):

 

**Pipeline por rama destino (recomendado en entornos corporativos):**

 
- PR → CI en rama feature → merge a `develop` → CD de `develop` despliega a Dev.
- Merge a `release/x.y` → CD de release despliega a Preprod.
- Merge a `main` → CD de main despliega a Producción.
- **Ventaja:** separación clara de responsabilidades y políticas por rama.

 

**Pipeline único con promoción de artefactos (alternativa):**

 
- Un único pipeline construye el artefacto y lo publica; luego se promueve la misma imagen entre entornos (Dev → Staging → Prod).
- **Ventaja:** garantiza que exactamente la misma imagen pasa por todos los entornos.

 

**¿Cuándo usar cada uno?**

 
- **Trazabilidad estricta y reproducibilidad en producción**: construir una vez y **promover artefactos**.
- **Velocidad y flexibilidad en integración**: pipelines por rama para Dev/Staging.
- **Híbrido recomendado:** pipeline por rama para Dev/Staging + promoción del artefacto firmado para Producción.

 

### Pasos de esta etapa

 
1. **Seleccionar artefacto**: usar la imagen construida y firmada; preferible promover la imagen publicada en el registry en lugar de reconstruirla.
2. **Provisionar entorno**: namespace/cluster efímero o persistente para Dev; aplicar configuración de runtime (config maps, secrets gestionados por [vault](https://www.hashicorp.com/es/products/vault)).
3. **Desplegar con IaC**: Helm, Kustomize o Terraform para infra y manifiestos; usar valores específicos para Dev.
4. **Configurar observabilidad mínima**: logs, métricas y trazas activas ([Prometheus](https://prometheus.io/), [Grafana](https://grafana.com/), [OpenTelemetry](https://opentelemetry.io/)) para detectar fallos.
5. **Ejecutar Smoke Tests**: health checks, endpoints críticos, autenticación básica.
6. **Reportar resultados**: publicar resultados estructurados (JSON/SARIF) y métricas; si falla, detener y crear ticket/PR de remediación.
7. **Trazabilidad**: registrar versión de imagen, SBOM, firma y commit asociado en el despliegue.

 

### Buenas prácticas

 
- **No reconstruir la imagen** en cada entorno; promover la imagen publicada.
- **Entornos efímeros** para PRs o features (preview environments) y un entorno Dev persistente para integración continua.
- **Paridad de configuración** con staging/producción (variables, límites, sidecars) salvo datos sensibles.
- **Secrets gestionados** fuera del repo ([Vault](https://www.hashicorp.com/es/products/vault), [SealedSecrets](https://docs.cloudnativerioja.com/tutoriales/Encriptar_y_desencriptar_secrets_con_Sealed_Secrets/), [Azure Key Vault](https://azure.microsoft.com/en-us/products/key-vault)).
- **Rollback automático**: mantener estrategia de rollback si el smoke test falla.
- **Feature flags** para habilitar/deshabilitar funcionalidades en Dev sin desplegar nuevo código.
- **Políticas de acceso** y auditoría para quién puede promover a entornos superiores.

 

### Ventajas

 
- Feedback rápido para desarrolladores.
- Detecta problemas de integración en entorno cercano a producción.
- Facilita debugging con trazas y logs reales.

 

### Desventajas

 
- Coste en recursos y tiempo si no se optimiza (entornos efímeros mal gestionados).
- Posible divergencia de configuración si no se mantiene paridad.
- Riesgo de exponer datos sensibles si los secrets no están bien gestionados.

 

### Ejemplo completo con GitLab CI

 

Este ejemplo incluye: promoción de imagen firmada, verificación de firma, generación y almacenamiento de SBOM, despliegue con Helm a `dev`, smoke tests y creación automática de issue si falla.

 

```yaml
stages:
  - promote
  - deploy
  - smoke
  - notify

variables:
  REGISTRY: registry.example.com
  IMAGE_NAME: myapp
  NAMESPACE: dev
  HELM_CHART_PATH: ./chart
  SBOM_FILE: sbom-cyclonedx.json

# Job: verificar y preparar imagen (promoción)
promote_and_verify:
  stage: promote
  image: docker:24.0.0
  services:
    - docker:dind
  variables:
    DOCKER_DRIVER: overlay2
  script:
    - echo "Promote job: tag=${IMAGE_TAG:-latest}"
    - docker login $REGISTRY -u "$REGISTRY_USER" -p "$REGISTRY_PASSWORD"
    - docker pull $REGISTRY/$IMAGE_NAME:${IMAGE_TAG}
    # Verificar firma con cosign (clave pública en variable secreta)
    - |
      if ! cosign verify --key "$COSIGN_PUBKEY" $REGISTRY/$IMAGE_NAME:${IMAGE_TAG}; then
        echo "Image signature verification failed" >&2
        exit 2
      fi
    # Generar SBOM (Syft) y guardarlo como artifact
    - syft $REGISTRY/$IMAGE_NAME:${IMAGE_TAG} -o cyclonedx-json > $SBOM_FILE
  artifacts:
    paths:
      - $SBOM_FILE
    expire_in: 1h
  rules:
    - if: $CI_PIPELINE_SOURCE == "web" || $CI_PIPELINE_SOURCE == "pipeline" || $CI_COMMIT_BRANCH == "develop"

# Job: escaneo de imagen opcional (Trivy)
image_scan:
  stage: promote
  image: aquasec/trivy:latest
  dependencies:
    - promote_and_verify
  script:
    - trivy image --format json --output trivy.json --severity HIGH,CRITICAL $REGISTRY/$IMAGE_NAME:${IMAGE_TAG} || true
    - cat trivy.json
    - |
      CRITICAL_COUNT=$(jq '.Results[].Vulnerabilities[]? | select(.Severity=="CRITICAL")' trivy.json | wc -l || true)
      HIGH_COUNT=$(jq '.Results[].Vulnerabilities[]? | select(.Severity=="HIGH")' trivy.json | wc -l || true)
      echo "HIGH: $HIGH_COUNT CRITICAL: $CRITICAL_COUNT"
      if [ "$CRITICAL_COUNT" -gt 0 ]; then
        echo "Critical vulnerabilities found, failing pipeline" >&2
        exit 3
      fi
  artifacts:
    paths:
      - trivy.json
    expire_in: 1h
  rules:
    - if: $CI_COMMIT_BRANCH == "develop"

# Job: deploy a Dev con Helm
deploy_to_dev:
  stage: deploy
  image: alpine/helm:3.12.0
  dependencies:
    - promote_and_verify
  before_script:
    - apk add --no-cache curl jq bash
    - echo "$KUBE_CONFIG_BASE64" | base64 -d > /tmp/kubeconfig
    - export KUBECONFIG=/tmp/kubeconfig
  script:
    - echo "Deploying $REGISTRY/$IMAGE_NAME:${IMAGE_TAG} to namespace $NAMESPACE"
    - helm upgrade --install myapp $HELM_CHART_PATH \
        --namespace $NAMESPACE \
        --create-namespace \
        --set image.repository=$REGISTRY/$IMAGE_NAME \
        --set image.tag=${IMAGE_TAG} \
        --wait --timeout 5m
    - kubectl -n $NAMESPACE annotate deployment myapp "ci.commit=${CI_COMMIT_SHA}" --overwrite || true
    - kubectl -n $NAMESPACE annotate deployment myapp "ci.image=${REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG}" --overwrite || true
  rules:
    - if: $CI_COMMIT_BRANCH == "develop"

# Job: smoke tests post-deploy
smoke_tests:
  stage: smoke
  image: curlimages/curl:8.3.0
  dependencies:
    - deploy_to_dev
  before_script:
    - apk add --no-cache jq
    - 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}' || echo "")
    - if [ -z "$SERVICE_HOST" ]; then SERVICE_HOST=$(kubectl -n $NAMESPACE get svc myapp -o jsonpath='{.spec.clusterIP}'); fi
    - echo "Service host: $SERVICE_HOST"
    - |
      # Health check
      if ! curl -fS --retry 3 --max-time 10 "http://$SERVICE_HOST/health"; then
        echo "Smoke test failed" >&2
        exit 4
      fi
  rules:
    - if: $CI_COMMIT_BRANCH == "develop"

# Job: notificar y crear issue si falla
notify_on_failure:
  stage: notify
  image: curlimages/curl:8.3.0
  when: on_failure
  script:
    - echo "Creating issue for failed pipeline"
    - |
      curl --request POST --header "PRIVATE-TOKEN: $GITLAB_API_TOKEN" \
        --header "Content-Type: application/json" \
        --data '{
          "title":"[CD] Fallo en Deploy/Smoke tests - '"${CI_PROJECT_PATH}"' '"${CI_COMMIT_SHORT_SHA}"'",
          "description":"Pipeline: '"${CI_PIPELINE_URL}"' \nBranch: '"${CI_COMMIT_BRANCH}"' \nImage: '"${REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG}"' \nJob: '"${CI_JOB_NAME}"' \nLogs: see job logs",
          "labels":"security,remediation"
        }' "https://gitlab.example.com/api/v4/projects/${CI_PROJECT_ID}/issues"
  rules:
    - if: $CI_COMMIT_BRANCH == "develop"
```

 

**Detalles a tener en cuenta:**

 
- **Promoción sin reconstruir**: `promote_and_verify` hace pull de la imagen ya publicada y verifica su firma con `cosign`. Garantiza que la imagen que se despliega es la misma que pasó los controles previos.
- **SBOM**: `syft` genera el SBOM y se guarda como artifact para trazabilidad.
- **Image scan**: `image_scan` usa `trivy` y falla si hay vulnerabilidades críticas (ajusta política según tu gobernanza).
- **Deploy**: `deploy_to_dev` usa `helm upgrade --install` y anota el deployment con metadatos (commit, imagen).
- **Smoke tests**: `smoke_tests` valida el health endpoint; si falla, `notify_on_failure` crea un issue automáticamente en GitLab.
- **Secrets**: `REGISTRY_USER`, `REGISTRY_PASSWORD`, `COSIGN_PUBKEY`, `KUBE_CONFIG_BASE64`, `GITLAB_API_TOKEN` deben estar como variables protegidas de GitLab.

 

### IA

 

**No sustituye** el despliegue real.

 

**Sí mejora** el proceso en estas áreas:

 
- **Generación de manifiestos** optimizados ([Helm](https://helm.sh/)/[Kustomize](https://kustomize.io/)) y sugerencias para reducir imágenes y capas.
- **Diagnóstico post-deploy**: analizar logs y trazas para identificar la causa raíz de fallos.
- **Automatización de rollbacks**: predecir si un despliegue es riesgoso y sugerir rollback.
- **Generación de PRs de remediación** con cambios en configuración o Dockerfile.
- **Optimización de entornos efímeros**: decidir cuándo crear o destruir previews según coste/beneficio.

  

## Smoke Tests

 

Son comprobaciones rápidas y deterministas que validan la salud y las funciones críticas del servicio tras un despliegue en un entorno (Dev, Staging). Deben ser **rápidos, idempotentes y con salida estructurada** para integrarse con gates y procesos de remediación.

 

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

 

### Lo que incluye esta etapa

 
- **Comprobaciones de salud**: endpoints `/health`, `/ready`, `/metrics` y checks de liveness/readiness del orquestador.
- **Pruebas de endpoints críticos**: llamadas a rutas esenciales (login, flujo de pago, endpoints de lectura/escritura clave) con aserciones simples sobre código HTTP y esquema básico de respuesta.
- **Verificación de dependencias**: comprobar conectividad a bases de datos, colas y servicios externos esenciales.
- **Validación de configuración**: comprobar que variables de entorno, secrets y configuraciones aplicadas están presentes y con valores esperados (sin exponer secrets en logs).
- **Comprobaciones de observabilidad**: asegurar que logs, métricas y trazas se emiten y son accesibles.
- **Tiempo y tolerancia**: tests rápidos con timeouts cortos y retries limitados para evitar bloquear el pipeline.
- **Salida estructurada**: resultados en JSON/SARIF para ingestión por dashboards, gates o creación automática de issues.

 

### Buenas prácticas

 
- **Que sean rápidos**: objetivo < 2–5 minutos; timeouts y retries controlados.
- **Aislar lo crítico**: seleccionar un conjunto pequeño de endpoints que representen la salud funcional mínima.
- **No exponer secretos**: nunca imprimir secrets en logs; validar su presencia sin mostrar valores.
- **Idempotencia**: diseñar tests que no alteren datos de forma irreversible; usar datos sintéticos o entornos efímeros.
- **Integración con gates**: fallos críticos deben detener la promoción; fallos menores pueden crear tickets automáticos.
- **Observabilidad**: adjuntar trazas/logs mínimos al reporte para acelerar diagnóstico.
- **Retries inteligentes**: permitir 1–2 reintentos con backoff corto para mitigar flakiness transitorio.
- **Entornos efímeros para PRs**: ejecutar smoke tests en previews y destruir el entorno al cerrar el PR.

 

### Ventajas

 
- **Feedback inmediato** sobre si el despliegue es viable.
- **Prevención de regresiones en producción** al bloquear promociones con fallos evidentes.
- **Bajo coste** comparado con suites E2E completas.

 

### Desventajas

 
- **Cobertura limitada**: no detectan problemas de negocio complejos.
- **Posible flakiness** si las dependencias externas no están bien simuladas.
- **Falsa sensación de seguridad** si la selección de checks es pobre.

 

### Ejemplos

 

Comprobación health simple (curl):

 

```bash
curl -fS --retry 3 --max-time 10 "http://$SERVICE_HOST/health"
```

 

Smoke test con aserciones en bash:

 

```bash
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" "http://$SERVICE_HOST/api/v1/status")
if [ "$HTTP_CODE" -ne 200 ]; then
  echo "Smoke test failed: status $HTTP_CODE" >&2
  exit 1
fi
```

 
- **Uso de frameworks**: [Newman/Postman](https://learning.postman.com/docs/collections/using-newman-cli/command-line-integration-with-newman) para colecciones de smoke; [k6](https://k6.io/) para checks ligeros de latencia; scripts en [pytest](https://docs.pytest.org/en/stable/), [JUnit](https://junit.org/) o [SuperTest](https://www.npmjs.com/package/supertest) para aserciones programáticas.
- **Integración con Helm**: usar `helm test` para ejecutar hooks de smoke tras deploy si el chart los define.

 

### IA

 

**No sustituye** la ejecución real de los tests ni la verificación determinista. Actúa como **asistente de productividad y diagnóstico**.

 

**Sí mejora** el proceso:

 
- **Generación de suites de smoke**: proponer o generar colecciones de endpoints críticos basadas en el código, [OpenAPI](https://www.openapis.org/) o historial de incidentes.
- **Diagnóstico automático**: al fallar un smoke test, analizar logs y trazas, agrupar errores relacionados y proponer la causa raíz.
- **Sugerencia de retries y timeouts**: optimizar parámetros para reducir flakiness sin perder detección temprana.
- **Creación automática de tickets**: rellenar issue templates con evidencia, trazas y recomendaciones.
- **Priorización**: combinar impacto de negocio con frecuencia histórica para decidir qué checks incluir en smoke.

  

[En el siguiente artículo, **“CD — Parte 4: Deploy a Staging y Performance Smoke Tests”**, veremos cómo se promueve el artefacto a un entorno de preproducción con paridad a producción, y cómo se validan E2E y rendimiento ligero antes de avanzar hacia fases más exigentes.](https://jarroba.com/cd-entrega-continua-parte-4-deploy-a-staging-y-performance-smoke-tests/)

## 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)

