Construye tu primer Pipeline Declarativo de Jenkins para CI/CD
Construye un primer Pipeline Declarativo de Jenkins con etapas, agentes, checkout, pruebas, compuertas de despliegue, credenciales y acciones posteriores.
Construye tu primer Pipeline Declarativo de Jenkins para CI/CD
Tu primer Pipeline Declarativo de Jenkins debería responder una pregunta práctica: ¿puede Jenkins revisar tu código, compilarlo, probarlo y ejecutar pasos de despliegue solo cuando la rama correcta pasa? Un Jenkinsfile te da ese flujo de trabajo como código en el mismo repositorio que tu aplicación.
La sintaxis declarativa es un buen punto de partida porque te da una estructura predecible: pipeline, agent, stages, steps y post.
Entendiendo la Estructura del Pipeline Declarativo
El Pipeline Declarativo define todo el flujo de trabajo en un archivo llamado Jenkinsfile, que se almacena junto con el código de tu aplicación en tu repositorio SCM (por ejemplo, Git). Esta práctica se conoce como Pipeline como Código.
Elementos Clave de un Pipeline Declarativo
Un Pipeline Declarativo debe contener los siguientes bloques de nivel superior:
pipeline: El bloque externo obligatorio que define el contenido del pipeline.agent: Especifica dónde se ejecutará el pipeline o una etapa específica (por ejemplo,any,noneo etiquetas específicas).stages: Contiene uno o más bloquesstagesecuenciales.stage: Define un bloque conceptual de trabajo (por ejemplo, Compilar, Probar, Desplegar).steps: Contiene uno o más comandos o funciones ejecutados dentro de unstage.
pipeline {
agent any
environment { // Opcional: Define variables de entorno
APP_VERSION = '1.0.0'
}
stages {
stage('Build') {
steps {
// Los comandos van aquí
}
}
}
post { // Opcional: Acciones que se ejecutan después de que el pipeline finaliza
always {
echo 'Pipeline finalizado.'
}
}
}
Paso 1: Configurando el Trabajo de Jenkins
Para ejecutar un Pipeline desde el código, necesitas configurar un trabajo de Jenkins para que lea el Jenkinsfile desde tu repositorio.
- Navega a tu panel de Jenkins y selecciona Nuevo elemento.
- Ingresa un nombre para tu pipeline (por ejemplo,
mi-primer-pipeline-ci). - Selecciona el tipo de elemento Pipeline y haz clic en Aceptar.
- En la página de configuración, desplázate hacia abajo hasta la sección Pipeline.
- Cambia la definición de Script de Pipeline a Script de Pipeline desde SCM.
- Selecciona tu SCM (por ejemplo, Git).
- Ingresa la URL del Repositorio y configura tus credenciales si es necesario.
- Asegúrate de que la Ruta del Script esté configurada en
Jenkinsfile(el valor predeterminado).
Paso 2: Definiendo el Jenkinsfile para CI/CD
Crearemos un Jenkinsfile completo que simule un flujo de trabajo simple de CI/CD, integrando etapas estándar para un despliegue exitoso.
Supón que tienes una estructura de repositorio que contiene el código fuente de tu aplicación (por ejemplo, un proyecto simple de Python o Java) y el Jenkinsfile en la raíz.
Ejemplo Completo de Pipeline Declarativo
Este pipeline utiliza el agente node (si está configurado) y utiliza pasos básicos de shell (sh) para simular trabajo real. La etapa de despliegue es condicional, ejecutándose solo al completar exitosamente las etapas anteriores.
// Jenkinsfile
pipeline {
// 1. Definición del Agente: Especifica dónde se ejecuta todo el pipeline
agent {
label 'mi-agente-de-compilacion' // Usa una etiqueta específica si está disponible, o 'any'
}
// 2. Variables de Entorno: Define variables utilizables en todo el pipeline
environment {
REGISTRO_CONTENEDORES = 'registry.example.com'
NOMBRE_IMAGEN = 'miapp'
}
stages {
// Etapa 1: Checkout (Gestión de Código Fuente)
stage('Checkout Fuente') {
steps {
// El paso 'checkout scm' revisa automáticamente el código
// según la configuración definida en la configuración del trabajo de Jenkins.
checkout scm
sh 'echo "Código fuente revisado exitosamente."'
}
}
// Etapa 2: Compilar Artefactos
stage('Compilar Artefacto') {
steps {
sh 'echo "Iniciando compilación para $NOMBRE_IMAGEN:$BUILD_ID"'
// Simulación: Compilar una imagen Docker o un archivo jar/war
sh "docker build --label build_id=${BUILD_ID} -t ${REGISTRO_CONTENEDORES}/${NOMBRE_IMAGEN}:${BUILD_ID} ."
}
}
// Etapa 3: Pruebas y Compuertas de Calidad
stage('Ejecutar Pruebas') {
steps {
sh './run_unit_tests.sh'
sh 'echo "Ejecutando pruebas de integración..."'
// Ejemplo de recolección de resultados de pruebas (requiere plugins apropiados)
// junit '**/target/surefire-reports/*.xml'
}
}
// Etapa 4: Despliegue (Condicional)
stage('Desplegar en Staging') {
// La directiva 'when' asegura que la etapa solo se ejecute bajo condiciones específicas
when {
branch 'main'
}
steps {
sh "docker push ${REGISTRO_CONTENEDORES}/${NOMBRE_IMAGEN}:${BUILD_ID}"
sh 'kubectl apply -f k8s/deployment-staging.yaml'
script {
// Los bloques script permiten lógica Groovy tradicional dentro de pasos declarativos
echo "Despliegue exitoso en el entorno de Staging."
}
}
}
}
// 3. Acciones Posteriores: Define acciones basadas en el estado final del pipeline
post {
success {
echo 'Pipeline completado exitosamente. Notificando al equipo por Slack...'
// slackSend channel: '#devops-alerts', message: '¡CI/CD Exitoso!'
}
failure {
echo 'Pipeline fallido. Revisa los registros para errores.'
}
cleanup {
sh 'docker image prune -f --filter "label=build_id=$BUILD_ID"'
}
}
}
Paso 3: Ejecutando y Monitoreando el Pipeline
Una vez que el Jenkinsfile se haya confirmado y enviado a la rama configurada en tu trabajo de Jenkins:
- En la página del trabajo de Jenkins, haz clic en Compilar ahora (o espera la encuesta SCM/disparador webhook).
- Monitorea la compilación en el panel Historial de Compilaciones.
- Haz clic en el número de compilación en ejecución y selecciona Salida de Consola para ver los detalles de ejecución paso a paso.
- También puedes usar la visualización de Vista de Etapas (si el plugin está instalado) para ver el progreso de las etapas
Checkout,Compilar,ProbaryDesplegargráficamente.
Mejores Prácticas y Características Avanzadas
Utilizando Bibliotecas y Código Compartido
Para pasos complejos o altamente repetitivos, evita escribir Groovy verboso directamente en el Jenkinsfile. En su lugar, usa Bibliotecas Compartidas. Estas bibliotecas externas te permiten definir funciones comunes (como rutinas de despliegue estándar o funciones de notificación) que pueden ser llamadas desde múltiples pipelines, haciendo tu Jenkinsfile más limpio.
// Llamando a un paso de biblioteca compartida
stage('Configuración Personalizada') {
steps {
bibliotecaPersonalizada.inicializarEntorno(env: 'prod')
}
}
Trabajando con Credenciales
Nunca codifiques información sensible (contraseñas, tokens, claves API) directamente en el Jenkinsfile. Usa el sistema integrado de Gestión de Credenciales de Jenkins.
El paso withCredentials te permite acceder de forma segura a secretos almacenados:
stage('Autenticar Registro') {
steps {
withCredentials([usernamePassword(credentialsId: 'docker-registry-creds',
passwordVariable: 'PASS',
usernameVariable: 'USER')]) {
sh '''
printf '%s' "$PASS" | docker login \
--username "$USER" \
--password-stdin "$REGISTRO_CONTENEDORES"
'''
}
}
}
Selección de Agente
Consejo: Siempre define tu
agentespecíficamente usando unalabelen lugar deagent any. Usaragent anysignifica que el pipeline podría ejecutarse en el nodo controlador de Jenkins, lo cual es un riesgo de seguridad y puede afectar el rendimiento del controlador. Asegúrate de tener agentes (nodos) de Jenkins correctamente configurados con las herramientas necesarias (Docker, Maven, Node.js) instaladas.
Conclusión
Mantén el primer pipeline aburrido y confiable: elige una etiqueta de agente real, revisa el código, compila, prueba, controla el despliegue por rama y mantén los secretos en las credenciales de Jenkins. Una vez que funcione, agrega publicación de artefactos, escaneo de seguridad y promoción de entornos paso a paso.