Taller de Continuous Delivery

Por estos días me encuentro trabajando en la preparación de un Taller sobre Continuous Delivery. El taller surgió a partir del pedido concreto de un cliente, pero obviamente armar un curso para dictarlo solo una vez no es negocio, así que seguramente agende para volver a dictarlo en un futuro (interesados contactarme ;-)).

El taller es de índole de práctica, o sea los participantes ponen manos en la masa. Para ello he preparado una imagen de máquina virtual para que los alumnos hagan los ejercicios. Hay algunos ejercicios de carácter más teórico (por ejemplo diseño de ambientes) pero la mayoría son de índole práctica orientados a herramientas (por ejemplo configurar Jenkins para hacer deploy automatizado de una aplicación en diversos ambientes).

Comparto aquí un video con un poco más de información.

Versionado de base de datos

Este es un tema que curiosamente para mi muchos equipos no tienen incorporado como práctica. A mi parecer en la actualidad la estrategia más común para esto es lo que desde hace años comenzó a hacer Ruby on Rails:

  • escribir los scripts incrementales de actualización de la base siguiendo una convención de naming incremental (números secuenciales o timestamp invertidos). Estos scripts al ser texto plano se pueden almacenar naturalmente en el repositorio de código junto al código de la aplicación
  • por otro lado se agrega una tabla en la propia base de datos para llevar registro de los scripts aplicados lo cual determina la versión de la base de datos.

En el caso de Ruby on Rails, uno debe encargarse de escribir los scripts (para escribir los puede usar un DSL en lugar de sql) y luego el propio framework brinda funcionalidades para crear la tabla de versión, ejecutar los scripts y llevar control de su ejecución. No estoy seguro si Rails fue el primer framework en implementar esta estrategia pero en la actualidad existen diversas herramientas en distintos lenguajes que la implementan como ser: FluentMigrator (con foco en C#), LiquidBase (con foco en Java/Grails).

Una herramienta que implementa esta estrategia y con la que he estado trabajando este último tiempo es Flyway, les comparto un video que muestra su uso y explica algunos detalles.

Entrega continua principio #1: 3 repositorios por aplicación

Creo que en la actualidad está ya claro que debemos tener un repositorio para versionar el código de nuestra aplicación. Algunos también versionan  en ese mismo repositorio la configuración de la aplicación. Para algunos casos esto puede ser suficiente, pero en contextos de entrega continua no me parece apropiado.

En primer lugar la configuración y el código tienen un tasa de cambio distinta, el código cambia mucho más rápido que la configuración. Al mismo tiempo la configuración suele variar dependiendo del ambiente en que se despliegue la aplicación. Finalmente, dependendiendo de la organización puede que la configuración del ambiente productivo sea reservada y sólo algunos miembros de la organización puedan accederla. La propuesta entonces es tener un repositorio exclusivo para almacenar la configuración de la aplicación. En particular, yo suelo crear en ese repositorio un branch por cada ambiente. Adicionalmente para facilitar el trabajo del equipo de desarrollo suelo almacenar junto al código, la configuración del ambiente desarrollo.

Finalmente necesitamos un tercer repositorio para almacenar los scripts de despliegue. La idea de poner estos scripts en un repositorio exclusivo tiene que ver otra vez con su tasa de cambio esporádica y también con el hecho de que es posible que estos scripts sean creados/manipulados por personas distintas a las que escriben el código, típicamente sysadmins.

En algunos casos particulares puede que sea necesario un cuarto repositorio, por ejemplo si uno quisiera generar modulos Puppet para automatizar el provisioning de la aplicación.

Pensándolo bien, creo que el título del artículo no es preciso, el principio es versionar todo,  el hecho de usar 3 repositorios es más bien una forma de implementarlo, que puede no aplicar siempre.

Nuevo proyecto de CI / CD

Hacía fines de diciembre del año pasado me contactaron de una empresa para que los ayudara con una iniciativa de Integración Continua. Intercambiamos un par de mails, tuvimos una llamada telefónica de 20 minutos y acordamos una primera reunión.

Desde mi punto de vista la práctica de integración continua no es un fin en sí mismo sino que es una herramienta. Por ello, una de las primeras cosas que pregunté fue: ¿Cuál es su problema? ¿Qué esperan solucionar con esta práctica? La respuesta fue clara, había dos problemas principales: por un lado la calidad del producto y por otro el desperdicio de tiempo invertido en el despliegue de la aplicación a los distintos ambientes. Esto me permitió entender que la cuestión iba bastante más allá de la integración continua.

El desafió me pareció muy interesante, pues se trataba de una empresa grande, con equipos distribuidos geográficamente en distintos lugares de latinoamérica y cuyo negocio estaba centrado en la venta de soluciones de banca. La empresa contaba con un plataforma de productos que vendía a distintos clientes y cada venta implicaba una implementación/customización de los productos. De esta forma había equipos trabajando sobre los productos y en paralelo un equipo de implementación para cada cliente que compraba el producto.

En términos de administración de la configuración a primera vista la naturaleza del negocio llevaba a tener un trunk de producto con un branch por cada cliente. Fácil decirlo, no tan fácil de implementarlo sobre todo teniendo el código de todos los productos en un único repositorio CVS.

La plataforma tecnológica era Java, un clásico en sistemas de banca. Pero dado que la solución se vendía a distintos clientes la aplicación debía funcionar sobre distintos ecosistemas tanto a nivel base de datos, application server y service bus.

Un último condimento no menor es que gran parte del código venía arrastrándose desde hacía varios años y tenía dependencia con componentes open source ya sin soporte (por ejemplo Apache Hivemind). Adicionalmente también se estaban usando versiones viejas de algunas herramientas (por ejemplo java6  y maven2).

Cabe destacar que varias de este cuestiones no las sabia inicialmente, sino que las fui descubriendo una vez empecé a trabajar.

La situación era compleja y las expectativas del cliente eran muy grandes. Mi propuesta fue simple y concreta:

Busca un equipo que esté interesado en trabajar en esta iniciativa. Yo me siento y trabajo con el equipo codo a codo 1 mes para resolver los impedimentos que el equipo considere le impiden construir software de calidad.

Al cliente, le gustó la propuesta y la bola empezó a rodar.

Continuará…

Continuous: Integration vs Delivery vs Deployment

En los últimos dos años he repetido incontables veces la diferencia entre estas tres prácticas y dado que no encontré ninguna explicación online que me satisfaciera, he decidido escribir mi propia explicación.

Continuous Integration: el software suele desarrollarse en equipo, donde cada miembro trabaja en su máquina en una porción del software. En ese contexto, la práctica de Continuous Integration propone integrar de forma continua el trabajo realizado por cada miembro del equipo. Esto implica una serie de cuestiones como ser el uso de controlador de versiones y contar con un ambiente de integración donde puedan ejecutarse verificaciones sobre software integrado.

Continuous Delivery: en términos organizacionales esta práctica es poner en manos del negocio la decisión de cuándo ir a producción. Más concretamente eso implica que cada build exitoso pueda (si el negocio así lo decide) ir a producción. entiéndasee build como el artefacto resultante del proceso de integración)

Continuous Deployment: está práctica va más allá de Continuous Delivery e implica que cada build exitoso va automáticamente a producción. Tal como propone Jez Humble, un mejor nombre para esta práctica sería Continuous Release. Continuous Deployment implica Continuous Delivery pero no al reves.

Estas tres prácticas tienen un aspecto técnico relacionado a herramientas y aspecto humano relacionado a hábitos y reglas que las personas deben incorporar y que personalmente considero que es el mayor desafío a la hora de intentar implementar estas prácticas. Ejemplo: de nada sirve tener un controlador de versiones si los miembros del equipo hacen commit una vez por día.

El orden en que describí cada práctica tiene que ver con el orden natural de adopción de las misma. Cabe aclarar cada práctica puede implementarse con distintos “niveles de profundidad” los cuales dependerán del contexto de cada proyecto/organización.

Muchas veces al explicar estas prácticas la audiencia tiende a decir que quiere implementar Continuous Delivery ante lo cual suelo aclarar: “No todas las prácticas son necesarias para todo contexto” y a continuación pregunto: “¿Su negocio realmente necesita continuous delivery?” En determinados contextos tener Continuous Delivery puede ser imprescindible para que el negocio sea competitivo, mientras en otros contextos (posiblemente más estables a nivel de negocio), sea simplemente un nice-to-have.

Como comentaba un amigo que trabaja en la industria petrolera: “Nosotros tenemos 3 releases anuales planificados e inamovibles”, en un contexto así posiblemente no se justifique el esfuerzo que implica adoptar continuous delivery. Distinto es el caso de un negocio muy variable que requiere de cambios constantes en sus aplicaciones donde no tener Continuous Delivery podría implicar perder el negocio.

Por su parte la práctica de Continuous Integration tiene algunas particularidades respecto de las otras dos prácticas. En primer lugar, es una práctica higiénica, lo cual implica que en términos generales siempre debe utilizarse. En segundo lugar es una práctica “a puertas cerradas” en el sentido que su uso está complementamente en manos del equipo de desarrollo. No es necesario aprobación y/o interacción con personas de otras áreas de las organización ni con el usuario. Si bien puede ser útil tener ayuda del grupo de infraestructura para montar un servidor de integración continua, la realidad es que no es algo imprescindible, el propio equipo puede montar un servidor de integración continua en la máquina de alguno de los miembros del equipo o bien podría utilizar algún servicio online (como Travis o CloudBees).

Para quienes quieran profundizar les recomiendo es artículo de Jez Humble: Continuous Delivery vs. Continuous Deployment.

Para cerrar les comparto un par de imagenes (de mi autoría) que esquematiza la diferencia/relación entre estas prácticas.

ci_y_cd

 

cd_y_cd

Octopush by Olx

Como parte del proyecto de Continuous Delivery en Olx, generamos una herramienta para controlar el acceso al ambiente de staging. Esta herramienta se llama Octopush y está construida con Php y MySql. La semana pasada Olx liberó Octopush bajo licencia Apache.

Los interesados en colaborar/ver/usar Octopush pueden encontrar el código el código en GitHub (github.com/olx-inc/octopush).

Explicar lo que hace esta herramientas no es tan trivial por eso grabé este breve video.

Continuous Delivery en Olx

Hace aproximadamente un año comencé a trabajar en un proyecto de implementación de continuous delivery en Olx. Mi rol dentro de dicho proyecto era el de facilitador colaborando principalmente con Diego Garber, release manager de Olx y product owner del proyecto.

Cuando digo facilitador lo digo en un sentido muy amplio, ya que mis tareas incluian un poco de gestión, un poco de diseño, capacitación, configuración/troubleshooting de Jenkins y hasta programación en Php. Básicamente ayudaba a que cada involucrado cumpliera con sus tareas, lo cual podía incluso implicar que en ciertas ocasiones me encargara yo mismo de la ejecución de dichas tareas, ya fueran configurar un repositorio GitHub o escribir algo de código.

releases

En estos días estamos cerrando el proyecto y me complace el hecho de que no sólo hemos cumplido con la mayoría de los objetivos inicialmente planteados, sino que aún más importante, hemos agregado valor a la organización permitiendo que el área de tecnología pueda dar respuestas más rápidas a las necesidades del negocio, acortando el ciclo de feedback y potenciando el retorno de la inversión.

En las próximas semanas iré compartiendo algunos datos más de esto, por el momento termino este artículo con un gráfico que muestra la evolución de la cantidad de releases desde que arrancamos el proyecto. En el  mismo se puede apreciar que se pasó de 60 releases mensuales en marzo de 2013 a 180 en enero de 2014.