Éste es el último post de la serie sobre la Implementación del patrón Deployment Pipeline en DevOps. En artículos anteriores expliqué qué es una Deployment Pipeline, cuáles eran los beneficios de uso, cómo diseñar una Deployment Pipeline para DevOps y finalmente cómo usar Jenkins para implementar dicha pipeline.
Ahora me gustaría dar un paso más explicando cómo se implementa, desde un punto de vista práctico, la Deployment Pipeline usando Jenkins. No pretende ser un manual ni una guía de cómo se realiza esta implementación, pero sí pretende facilitar el primer paso para su implementación y como dice Lao-Tse “Un viaje de mil millas comienza con un primer paso”.
El objetivo de este artículo es construir un esqueleto de la Deployment pipeline que sirva de guía para su implementación real. La implementación específica de cada paso de la pipeline será propia para cada proyecto según la tecnología utilizada, pero nos servirá para tener un marco o patrón de trabajo.
Pipeline As Code con Jenkins
En el post anterior comentábamos que íbamos a usar Jenkins con algunos plugins. En concreto vamos a usar el plugin Blue Ocean para la visualización de la pipeline.
En versiones anteriores de Jenkins teníamos que construir nuestra pipeline desde la interfaz web lo que implicaba realizar la creación manual de Jobs y un esfuerzo adicional en la gestión de la pipeline.
La tendencia actual es tratar todos los elementos del ciclo de vida del desarrollo de software como código “as Code” y la definición de la pipeline no iba a ser menos.
La principal ventaja de esto es que podemos almacenar la definición de nuestra pipeline en el servidor de versiones y tratarlo como cualquier elemento de código (pruebas, calidad, revisiones…).
Para ello Jenkins permite la implementación de la pipeline a través de un Jenkinsfile escrito con un lenguaje de scripting específico.
Ejemplo de Jenkinsfile
Un ejemplo muy básico de Jenkinsfile que podemos usar para construir nuestra pipeline y que usé para la definición de la pipeline de los artículos anteriores es el siguiente:
Este código no está completo, pero sirve para ilustrar cómo se construye la pipeline. Si se observa el código se ve cómo se define cada etapa (“stage”) y dentro de cada una de ellas los pasos que se ejecutan, “steps”.
Completar estos pasos dentro de cada etapa ya es específico de cada proyecto y tecnología usada.
Por ejemplo, en la “commit stage” el código se puede compilar usando Maven, Gradle, etc, los tests unitarios se podría ejecutar con un framework xUnit y el análisis de código se podría hacer con Kiuwan o Sonarqube.
La realización de los despliegues a los distintos entornos se podrían hacer usando Ansible o cualquier otra herramienta de gestión de la configuración.
Por último, para los tests de aceptación podríamos usar Gherkin junto con Cucumber y Selenium.
En resumen, la pipeline lo que establece es el esqueleto que da soporte a la ejecución y visualización de los procesos concretos de entrega de valor, pero el trabajo efectivo se debe hacer en dichos pasos.
Puede parecer complicado, pero para la definición de los pasos el propio Jenkins incorpora un generador de código en base a lo que queramos hacer, lo que facilita mucho su uso.
Consideraciones finales
Antes de terminar quería hacer unas consideraciones a la hora de implementar una Deployment pipeline con Jenkins de esta manera:
- Es importante empezar la pipeline en estado rojo. Es decir, fallida e ir evolucionando paso a paso siempre controlando que no se nos promociona a producción algo que no queremos. Es interesante poner antes de cada despliegue una pregunta de confirmación para evitar que nada suba a producción sin control. Esto es tan sencillo como incluir la siguiente sentencia en nuestro Jenkinsfile:
- Como ya comenté en el post anterior, una vez establecida la pipeline, es trabajo de todo el equipo mantener en estado correcto la pipeline para asegurar que disponemos de una línea de entrega a producción efectiva. Si nuestra pipeline pasa mucho tiempo en estado fallido, algo estamos haciendo mal.
- DevSecOps. Una definición de DevSecOps que me gusta especialmente es la que dice que DevSecOps es poder coger cualquier elemento de la pipeline y poder demostrar que la seguridad está contemplada en ese punto. Por tanto a la hora de implementar nuestra pipeline no debemos olvidar incorporar mecanismos de seguridad que nos aseguran que el código que entregamos es seguro.
- El patrón descrito en este artículo se puede utilizar tanto para aplicaciones tradicionales como para aplicaciones y arquitecturas basadas en contenedores, simplemente hay que configurar los pasos de las etapas según la tecnología seleccionada.
Pues bien, en este post he descrito muy brevemente cómo podemos hacer uso de la característica de Pipeline as Code dentro de Jenkins y beneficiarnos de sus ventajas. Espero que haya servido para que animar a su uso.
Si han quedado dudas, podéis poneros en contacto con nosotros sin compromiso.
Emiliano Sutil es Project Manager en Xeridia