Deployment continuo: el caso práctico

Por ver un poco cual sería el caso práctico de un sistema automático y continuo para hacer deployments (o despliegues), voy a compartir lo que estuve pensando el otro día.

Antes de nada debo decir que sigo sin haberlo implementado, así que hablo de ideas que tengo en mente, y no de un caso real.

Aunque en el artículo anterior hacía una introducción más detallada al tema de deployment/despliegue continuo, vuelvo a repetir el concepto:

El concepto en plan radical, es que cada vez que se haga un cambio en el código, automáticamente tu servidor de producción se actualice.

Esto es un poco hardcore, lo sé, porque muchas veces se introducen bugs, y se molesta a los usuarios innecesariamente, así que este sistema debe ser lo suficientemente inteligente para tratar de evitar esto en la mayor medida posible. Es mejor post-poner un par de dias un release, que molestar a cientos de usuarios con un bug.

Una vez dicho esto, y partiendo de la base de que ya se tiene un SCV (sistema de control de versiones), un sistema de build y un sistema de tests (tests unitarios, de integración y tests de casos de uso sobre la web, por ejemplo con selenium), el procedimiento para hacer despliegues continuos podría ser el siguiente:

  • Dado un nuevo build
    • Si los entregables no se han generado correctamente, fin de la historia, no hay deployment posible
    • Si algún test (test unitario, de integración, de casos de uso, o de lo que sea) ha fallado o no se ha podido realizar, no hay más que hablar, tampoco hay deployment
  • Si el build está bien, entonces se crea un backup de todo el servidor de producción (bases de datos, scripts, etc…)
    (La idea de este paso, como se verá luego, no es tanto hacer un backup real, como tener una replica similar a producción)

    • Si hubiera algún fallo generando los backups, nuevamente fin de la historia
  • Una vez se tiene el backup, hay que descargarlo y verificar que funciona. Esto significa, idealmente, hacer un clon de producción, es decir:
    • Descargar el backup que hemos creado en una máquina virtual “limpia”
    • Instalar el backup (tanto código como datos)
    • Pasar un subconjunto de tests, lo suficientemente grande para saber que la instalación ha funcionado, y lo suficientemente pequeño para que este paso no tarde demasiado (quizá algunos tests unitarios y varios casos de uso)
  • En este punto, debemos usar el último build que hemos obtenido en el primer paso y…:
    • actualizar el clon de producción
    • pasar nuevamente todos los tests de este nuevo build sobre ese clon de producción y ver que todo funciona bien (si algo falla, el nuevo build no se podrá desplegar y tendremos que mirar que ha ocurrido). Estos tests, deberían incluir:
      • tests unitarios
      • tests de integración
      • tests de consistencia de tablas (ver que la base de datos resultantes es la que tiene que ser)
      • tests de consistencia de datos (ver que no nos hemos pulido datos que estaban antes en producción)

Llegados a este punto, si todo ha funcionado,  sabemos que nuestro build puede instalarse por encima de un clon de producción y pasar TODOS los tests, es decir, que si el propio proceso de clonar producción funciona, repetir este proceso en producción debería nuevamente ser determinista y darnos el mismo resultado (usease, que nuestro build funcione y no cause problemas en producción).

Así pues, los pasos a realizar ahora por nuestro sistema automático de deployment, serían:

  • Subir el build a producción (de hecho, este paso se puede ir haciendo en paralelo a los pasos anteriores)
    • Este paso incluye descomprimir el build y prepararlo (si es que hay que preparar algo), pero sin tocar nada que pueda afectar a producción aún
  • Poner producción en modo “estamos actualizando, disculpen las molestias”
  • Hacer el backup real de las bases de datos y/o cualquier archivo que pueda ser susceptible de ser cambiado (idealmente backup de todo)
  • Ejecutar el script de auto-upgrade que tengamos, y actualizar tanto las bases de datos como el sistema de ficheros (tal cual se ha hecho en el clon de producción)
  • Desactivar el mensaje de “estamos actualizando”
  • Mandar un e-mail a quien corresponda avisando de que el sitio ha sido actualizado ;)
  • Y finalmente lanzar los tests para verificar que efectivamente todo funciona bien
    • Si por un casual alguno de estos tests falla, es que algo en nuestro sistema de clonado de producción/autodeployment está podrido, y nos dejará bien  jodidos. Nótese que tener un fallo en este punto es igual de chungo que haber hecho un release como los de toda la vida y ver que algo ha fallado, indicaría que algo en nuestro sistema de build/test está igualmente podrido… Este tipo de fallos no debería de ser normal.

Nótese que si algo falla en estos pasos (sobre producción), el sistema debería ser capaz de reestablecerse con el último backup realizado.

Después de haber comentado todo esto, también hay que tener en cuenta, que algunos pasos dependen mucho del tipo de sitio que se tiene, porque no es lo mismo hacer un backup de 50 megas, que de 5 teras, o de 2 peta bytes.  Si el volumen de información es muy grande, pues habrá que depender de los otros sistemas de backup que se dispongan, y usarlos convenientemente, con el fin de minimizar los tiempos de deployment.

En este tipo de casos, tampoco se podrá realizar un clon de producción para validar que el upgrade funciona, pero en vez de eso se puede coger sólo un subconjunto de los datos de producción (por ejemplo 1000 entradas, o 1 millón, yo que se). El tema es validar que todo funciona antes de subirlo.

Imagino que también cambia mucho el tema de si se trata de un servidor único, o son varios servidores. En el caso de que sean varios los servidores a los que afecta el  nuevo release, es posible que sea mejor introducir el nuevo build en uno de ellos, y si después de X tiempo no hay incidencias, que se propage a los demás.

Otra cosa que me gustaría comentar antes de finalizar el artículo, es que no quiero que se me malinterprete. En un caso práctico no tiene sentido hacer actualizaciones en el servidor para cada submit que se hace en el sistema de control de versiones.  Entre otras cosas, porque tampoco todos los tests pueden ser automáticos, a veces combiene hacer tests manuales. Así que probablemente lo que realmente tiene sentido y valor, es que para cada build se sepa si puede ser instalado en producción sin problemas o no (y para eso poder generar un pseudo-clon de producción es esencial), así como disponer de un botón que te haga deployments automáticos. Incluso puede tener sentido, que el sistema haga los deployments una vez al día o cada dos días, o incluso cada semana, durante las horas de menos visitas.

Para finalizar, debería quedar claro que cada cual debe adaptar estas ideas a sus recursos (sobretodo de tiempo) y sus necesidades, y sobretodo que los sistemas de despliegue automático y contínuo se pueden (y probablemente se deben) ir construyendo poco a poco.

Ale, pues nada más, espero vuestras críticas y comentarios, si es que a alguien le quedan fuerzas después de haber leido esta entrada ;)

PD: puff, creo que voy a tardar un par de días en traducir esto a inglés… madre de Dios, que tocho que me ha quedado

Trackback URL

, ,

5 Comments on "Deployment continuo: el caso práctico"

  1. Ivan
    06/05/2009 at 12:37 am Permalink

    Criticas y comentarios? Bueno, me parece interesante el tema este, pero no se.. me gustaria “ver resultados”. Cuando lo implementes, podrias comentar los resultados, a favor o en contra de este tipo de tecnicas tan agresivas.

    Yo soy mas tradicional en ese sentido. Me parece guay tener un buen sistema de build y que todo sea automatico, pero hijo, a la hora de llevar cualquier cosa a produccion o sacar un release de algo ¡¡piensatelo 2 veces!! De echo, mejor que se lo piense otro: el departamento de QA (si existe).

    Obviamente si no tienes QA (ni prevision de tenerlo) y tu mismo tampoco vas a hacer aunque sea un minimo QA, lo mejor es tener mogollon de tests (mejor unit tests que nada) y ahi ya hacer el deployment continuo o no da igual.

  2. Pau Sanchez
    06/05/2009 at 8:11 am Permalink

    Por eso al final concluia diciendo algo como que lo que realmente tiene sentido y valor, es poder saber para un determinado build se sepa si puede ser instalado en producción sin problemas o no, así como disponer de un botón que te haga deployments automáticos.

    En cualquier caso, yo pienso igual que tú, en el sentido de que antes de que saques un build tienes que estar seguro de que tiene el mínimo numero de bugs posibles, porque lo último que uno quiere es molestar a los usuarios.

    La pregunta que yo te hago es: Si dispusieras de un sistema automático de test equivalente a los tests que te pueda realizar una persona…. y tu programa/web/whatever pasara esos tests ¿harias deployment continuos, digamos, 1 por dia?

    Comento esto, porque indica donde está el cuello de botella en el proceso de release (al menos desde mi punto de vista).

  3. Ivan
    12/05/2009 at 12:17 am Permalink

    Contestando a tu pregunta: si puedo permitirme un departamento de QA dejaria que se mojaran ellos, sino podria llegar a probar este tipo de deployment y obrar segun los resultados. Es decir, prefiero confiar en una mezcla de “humanos” y tests automaticos, pero en caso de no disponer de “humanos” puede ser interesante del deployment continuos…

  4. Pau Sanchez
    13/05/2009 at 11:42 pm Permalink

    Yo creo que el punto clave del deployment continuo, es que también tienes que cambiar el chip con respecto a tus ciclos de desarrollo.

    Es decir, partiendo de una base en la que tienes la aplicación X subida, te hace preguntarte:
    – ¿cual es el siguiente bug a solucionar?
    – ¿cual es el siguiente feature a implementar?

    Con este sistema las prioridades se plasman al instante en el servidor. Como se suben pocos cambios a la vez, es menos probable hacer una pifiada del copón por estar 1 mes implementando cosas nuevas y luego subirlas. Y si haces algo mal, seguro que al dia siguiente ya te has enterado y puedes solucionarlo rápidamente (porque el desarrollador también lo tiene fresco). Hay que asegurarse de testear bien los cambios del copón ;)

    Bien es cierto, que si la pifias muy a menudo subiendo cosas al servidor, la gente va a pensar que tu web es un asco, porque siempre está fallando.

    PD: asumir que tus usuarios son testers no es muy buena idea, lo se, no pretendo que lo sean. Como ya dije, al final yo al menos, lo que pretendo sacar de estas ideas es saber para cualquier build, si sería deployeable, y tener un botoncito que lo deployee automáticamente. Qué builds deployeo o dejo de deployear de momento quiero seguir haciéndolo de forma manual.

Hi Stranger, leave a comment:

ALLOWED XHTML TAGS:

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Subscribe to Comments