Lección 2 de 312 min
Integración y despliegue continuo
CI, entrega continua y despliegue continuo con GitLab CI/CD, Jenkins y AWS CodePipeline.
Viernes por la tarde. Para publicar la versión nueva hay que ejecutar las pruebas, compilar, copiar los archivos al servidor y reiniciar el servicio, siguiendo una lista de pasos que solo una persona se sabe de memoria. Un día alguien se salta uno y la tienda pasa una hora caída.
Un pipeline convierte esa lista en código: una secuencia de trabajos que se ejecuta sola con cada cambio, siempre de la misma manera. En esta lección verás qué significan las siglas CI y CD y cómo se escriben pipelines en tres herramientas muy usadas: GitLab CI/CD, Jenkins y AWS CodePipeline.
Integración, entrega y despliegue continuos
Las tres prácticas se apoyan unas en otras: no puedes desplegar automáticamente lo que no integras y pruebas automáticamente. Las dos últimas comparten siglas, CD, y eso provoca bastante confusión.
Integración continua (CI)
Integrar cambios pequeños a menudo y comprobar cada uno de forma automática.
La integración continua consiste en que todo el equipo integre su trabajo en la rama principal con frecuencia, al menos a diario, y que cada integración dispare un pipeline que compila el proyecto y ejecuta las pruebas. Si algo se rompe, lo sabes en minutos y sabes qué cambio fue.
El resultado es una rama principal que siempre funciona. Lo contrario es el llamado «infierno de la integración» (integration hell): semanas de trabajo por separado que, al juntarse, no compilan y nadie sabe por qué.
Úsalo cuando
En cualquier proyecto con más de una persona o con pruebas automáticas. Es el primer paso y el que más rendimiento da.
Ten en cuenta
Tener un servidor de CI no es hacer CI: si las ramas viven semanas sin integrarse, el pipeline solo te avisa tarde. Y un pipeline en rojo que nadie arregla deja de servir; repararlo es la prioridad del equipo.
# Lo mínimo: probar cada push y cada merge request
pruebas:
image: node:lts
script:
- npm ci
- npm testEntrega continua (continuous delivery)
Cada cambio que pasa el pipeline queda listo para producción; publicar es un botón.
La entrega continua amplía la CI: además de probar, el pipeline empaqueta la aplicación y la despliega en entornos de prueba, como uno de preproducción (staging). Cualquier commit de main que salga en verde es un candidato que podría ir a producción en cualquier momento.
El último paso, el de producción, sigue siendo una decisión humana: alguien pulsa el botón cuando conviene, por ejemplo después de avisar a soporte o fuera de las horas punta. Pero ese paso ya no es una lista de tareas manuales, sino el mismo proceso automático de siempre.
Úsalo cuando
Cuando necesitas controlar el momento de publicar: aprobaciones obligatorias, sectores regulados o lanzamientos coordinados con otras áreas.
Ten en cuenta
Si el botón se pulsa una vez al mes, cada despliegue acumula muchos cambios y vuelve a ser arriesgado. La idea es que publicar sea tan rutinario que puedas hacerlo cuando quieras.
desplegar-produccion:
stage: deploy
script: ./desplegar.sh produccion
environment: produccion
rules:
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
when: manual # el pipeline espera a que alguien lo lanceDespliegue continuo (continuous deployment)
Cada cambio que pasa todas las pruebas llega solo a producción, sin intervención.
En el despliegue continuo desaparece el botón: si el pipeline termina en verde, el cambio se publica. Un merge a main puede estar en manos de los usuarios a los pocos minutos.
Exige mucha confianza en el proceso: pruebas automáticas que cubran lo importante, feature flags para ocultar lo inacabado, monitorización que detecte problemas (lo verás en el módulo de observabilidad) y una forma rápida de volver atrás. A cambio, cada despliegue es pequeño y, si algo falla, es fácil saber qué fue.
Úsalo cuando
En aplicaciones web con buenas pruebas y monitorización, donde publicar rápido aporta valor y un error se puede revertir en minutos.
Ten en cuenta
No encaja cuando cada publicación necesita una aprobación formal, ni en aplicaciones móviles, que pasan por la revisión de las tiendas. Sin pruebas sólidas, solo consigues romper producción más deprisa.
desplegar-produccion:
stage: deploy
script: ./desplegar.sh produccion
environment: produccion
rules:
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH # sin «when: manual»: va soloNota
En la práctica, «CI/CD» se usa como nombre genérico para el pipeline. Cuando alguien diga «CD», pregunta si se refiere a entrega o a despliegue: la diferencia es si queda un botón al final.
Herramientas de CI/CD
Todas comparten las mismas piezas: un archivo que describe el pipeline, etapas (stages) que se ejecutan en orden, trabajos (jobs) con los comandos y unas máquinas que los ejecutan. Lo que cambia es dónde vive cada pieza y cuánto tienes que mantener tú.
GitLab CI/CD
Pipelines descritos en un archivo YAML dentro del propio repositorio de GitLab.
- Configuración:
- .gitlab-ci.yml
- Ejecuta:
- GitLab Runner
Basta con añadir un archivo .gitlab-ci.yml en la raíz del repositorio. En él declaras las stages y los jobs: los jobs de una misma stage se ejecutan en paralelo y la siguiente stage solo empieza si la anterior termina bien. Cada job lo ejecuta un runner, un programa que recoge trabajos y los lanza, normalmente dentro de un contenedor Docker con la imagen que indiques.
Los artifacts pasan archivos de un job a los posteriores (por ejemplo, la carpeta dist/ compilada) y la cache guarda las dependencias entre ejecuciones. Con rules decides cuándo se ejecuta cada job: solo en main, solo en merge requests o de forma manual. Con environment, GitLab registra qué versión hay desplegada en cada entorno y te permite volver a una anterior.
Úsalo cuando
Si tu código ya vive en GitLab: no hay nada que instalar ni conectar, y el resultado del pipeline aparece en cada merge request.
Ten en cuenta
En GitLab.com, los runners que pone GitLab consumen minutos de cómputo de tu plan; si los necesitas en abundancia, puedes registrar runners propios. Y cada job empieza en un entorno limpio: lo que necesite otro job, pásalo como artifact.
stages: [test, build, deploy]
default:
image: node:lts
before_script:
- npm ci --cache .npm --prefer-offline
cache:
key:
files: [package-lock.json]
paths: [.npm/]
pruebas:
stage: test
script: npm test
compilar:
stage: build
script: npm run build
artifacts:
paths: [dist/]
desplegar:
stage: deploy
script: ./desplegar.sh
environment: produccion
rules:
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCHJenkins
El servidor de automatización de código abierto más veterano, ampliable con plugins.
- Escrito en:
- Java
- Configuración:
- Jenkinsfile
- Alojamiento:
- autogestionado
Jenkins es un servidor que instalas y mantienes tú. Un controlador coordina los pipelines y reparte el trabajo entre agentes, las máquinas donde se ejecutan los pasos. Su gran baza es el catálogo de plugins: hay integraciones para casi cualquier herramienta, sistema de control de versiones o proveedor de nube.
El pipeline se describe en un Jenkinsfile dentro del repositorio. La sintaxis declarativa (bloques pipeline, agent, stages, steps y post) es la recomendada; existe también la sintaxis «scripted», en Groovy puro, más flexible pero más difícil de mantener.
Úsalo cuando
Cuando necesitas ejecutarlo todo en tu propia infraestructura, integrar sistemas poco habituales o la empresa ya tiene años de pipelines en Jenkins.
Ten en cuenta
Lo alojas tú: las actualizaciones, las copias de seguridad, la seguridad del servidor y la compatibilidad entre plugins corren de tu cuenta. Un Jenkins con decenas de plugins sin actualizar es un riesgo de seguridad clásico.
pipeline {
agent { docker { image 'node:lts' } } // requiere el plugin Docker Pipeline
stages {
stage('Pruebas') {
steps {
sh 'npm ci'
sh 'npm test'
}
}
stage('Desplegar') {
when { branch 'main' }
steps {
input message: '¿Desplegamos a producción?'
sh './desplegar.sh'
}
}
}
post {
failure { echo 'El pipeline ha fallado' }
}
}AWS CodePipeline
El servicio gestionado de AWS que encadena origen, compilación y despliegue.
- Proveedor:
- AWS
- Compila:
- CodeBuild
- Despliega:
- CodeDeploy
CodePipeline orquesta un pipeline formado por etapas: Source detecta cambios en el código (en GitHub, GitLab o Bitbucket a través de una conexión, o en un bucket de S3, entre otros), Build compila y prueba, y Deploy publica. Entre etapas puedes añadir aprobaciones manuales. No hay servidores que mantener y pagas por uso.
El trabajo lo delega en otros servicios. CodeBuild ejecuta los comandos de compilación en contenedores efímeros, siguiendo un archivo buildspec.yml del repositorio. CodeDeploy despliega en máquinas EC2, funciones Lambda o servicios de ECS, con estrategias como blue/green, que levanta la versión nueva junto a la antigua y cambia el tráfico cuando está lista.
Úsalo cuando
Cuando tu infraestructura ya está en AWS y quieres permisos con IAM, despliegues nativos a sus servicios y nada que administrar.
Ten en cuenta
Te ata a AWS y la configuración se reparte entre varios servicios, así que conviene definirla como código (con CloudFormation, CDK o Terraform, como viste en el módulo anterior). Su integración con la revisión de código es más limitada que la de una herramienta que vive junto al repositorio.
version: 0.2
phases:
install:
commands:
- npm ci
build:
commands:
- npm test
- npm run build
artifacts:
base-directory: dist
files:
- "**/*"Buenas prácticas para cualquier pipeline
Busca un feedback rápido: pon primero los jobs más rápidos (lint, pruebas unitarias) para fallar pronto y ejecuta en paralelo lo que no dependa entre sí. Usa la cache para no descargar las dependencias en cada ejecución. Y nunca escribas secretos en el archivo del pipeline: guárdalos como variables de CI/CD protegidas (solo disponibles en ramas y etiquetas protegidas) y enmascaradas (ocultas en los logs), como viste en el módulo de seguridad web.
Interactivo
GitLab CI/CD, Jenkins y AWS CodePipeline
Activa o desactiva opciones para compararlas cara a cara.
| Característica | GitLab CI/CD | Jenkins | AWS CodePipeline |
|---|---|---|---|
| Dónde se define | .gitlab-ci.yml en el repositorio | Jenkinsfile en el repositorio | Consola, CLI o infraestructura como código |
| Quién lo mantiene | GitLab, o tu equipo si es autogestionado | Tu equipo, por completo | AWS |
| Dónde se ejecutan los jobs | Runners de GitLab o propios | Agentes que configuras tú | CodeBuild, en contenedores efímeros |
| Cómo se amplía | Plantillas y archivos YAML compartidos con include | Un enorme catálogo de plugins | Integración con otros servicios de AWS |
| Coste | En GitLab.com, sus runners consumen minutos de tu plan; los tuyos, no | Gratuito; pagas los servidores y el mantenimiento | Pago por uso |
| Encaja si… | Tu código ya está en GitLab | Necesitas control total o integraciones poco comunes | Despliegas sobre todo en AWS |
Ponlo en práctica
Saber qué es cada cosa es la mitad del trabajo. La otra mitad es reconocer cuándo usarla.
Interactivo
¿Qué usarías?
Lee cada situación y elige la opción que mejor la resuelve. Fallar aquí no cuenta: es para practicar.
En tu banco, cada subida a producción necesita la firma de una responsable, pero quieres que cualquier commit de main esté probado y listo para publicarse en cuanto ella dé el visto bueno.
Para recordar
- Integración continua es integrar cambios pequeños a menudo y probar cada uno de forma automática.
- La entrega continua deja cada versión lista para producción a falta de un botón; el despliegue continuo quita el botón.
- Un pipeline se compone de stages que se ejecutan en orden y jobs que corren en runners o agentes; los artifacts pasan resultados de unos a otros.
- GitLab CI/CD vive junto al código, Jenkins da control total a cambio de mantenerlo y CodePipeline encaja si todo está en AWS.
- Pipelines rápidos, con cache y con los secretos en variables protegidas, nunca en el repositorio.
Comprueba lo aprendido
Cuestionario
Responde las 5 preguntas para completar la lección.
1.¿Qué diferencia la entrega continua del despliegue continuo?
2.En un
.gitlab-ci.yml, el jobcompilargenera la carpetadist/y el jobdesplegar, de una stage posterior, la necesita. ¿Qué usas?3.¿Qué es un runner en GitLab CI/CD?
4.Necesitas un token para desplegar en producción desde el pipeline. ¿Dónde lo guardas?
5.En AWS CodePipeline, ¿qué papel tiene CodeBuild?