Estrategias de provisioning + deployment (parte 1)

En los últimos años he participado en diversos proyectos utilizando diversas estrategias de deployment. Dado que este es un tema que está despertando cada vez más interés me parece que puedo colaborar compartiendo las experiencias que he tenido.

Esta primer estrategia que quiero compartir está basada en Puppet y en paquetes Debian. Todo el provisioning del ambiente se hace utilizando Puppet y luego para el deployment se usa el siguiente proceso:

  1. Jenkins buildea la aplicación y genera un paquete Debian incluyendo la aplicación buildeada.
  2. El paquete generado se publica en un repositorio de paquetes Debian.
  3. Se actualiza el Puppet master con la definición del nuevo paquete.
  4. Se envía un mensaje a cada máquina del ambiente para que el agente Puppet actualice la máquina instalando el nuevo paquete que trae la nueva versión de la aplicación. (esto es necesario porque generalmente no se quiere una actualización automática de los agentes y por ello su actualización automática está desactivada)

Algunos puntos interesantes de esta estrategia son:

  • Es muy fácil realizar el rollback pues se hace utilizando el sistema de paquetes del sistema operativo
  • El tratar nuestra aplicación como un paquete del sistema operativo gozamos de todos los beneficios/funcionalidades que provee el sistema operativo para gestión de paquetes. Un ejemplo de esto es la posibilidad de explicar las dependencias de nuestra aplicación con otros paquetes dejando así que el propio gestor de paquetes se encargue de su resolución.
  • Si bien en mi descripción me refiero a paquetes Debian (.deb) lo mismo puede hacer con paquetes de otras distribuciones.
  • Dependiendo de cómo se armen los paquetes, se puede  incluir en los mismos los archivos de configuración  de la aplicación.

sopackages_puppet

Esta estrategia (y algunas más) la estaré compartiendo con mayor profundidad en mi Taller de prácticas de DevOps que dictaré el próximo 19 de abril.

Continuará..

Ansible vs Puppet: mi opinión

Hace unos días escribí sobre el camino que recorrí con las herramientas de automatización de infraestructura y mencioné que luego de haber usado Puppet y Ansible, he decidido quedarme con este último. Esta decisión se debe principalmente a las cuestiones:

  • El DSL de Ansible me resultó mucho más amistoso que el de Puppet
  • Para trabajar en modo “standalone” Ansible incluye en su core un conjunto de utilidades/tareas que a mi me resultan muy útiles y que no están en el core de Puppet (a menos que uno instale módulos adicionales).
  • El modo de funcionamiento “push” de Ansible me gusta más que el modo pull de Puppet.

Resalté algunas partes de la frases anteriores para dejar bien en claro el nivel de subjetividad de las mismas.

Caminando las herramientas de automatización de infraestructura

En mi opinión hay 3 herramientas que han picado en punta en esta temática: Chef, Puppet y Ansible. Hay algunas otras (como por ejemplo CFEngine) pero toda la gente y casos que conozco utilizan alguna de las 3 mencionadas. En mi caso cuando comencé a meterme en este campo di una primera mirada a Chef, tenía por aquella época un cliente a quien yo estaba ayudando con otras cuestiones y que usaba Chef para administrar su infraestructura. A partir de ello hice algunas pruebas con Chef, pero nunca lo use en un “proyecto real”.

Poco tiempo después me salió un proyecto para automatizar todo el pipeline de deployment de un aplicación incluyendo el proceso de provisioning de ambientes. Las pruebas que había hecho con Chef no me habían convencido, asi que decidí probar con Puppet. Usé Puppet durante un buen tiempo en diversos proyectos hasta que este año trabajé en un proyecto con Ale Ferrari quien venía utilizando Ansible y en mi siguiente proyecto decidí probarlo.

Hoy en día mi elección es Ansible, pero las razones las compartiré en otro post.

Capas de automatización

Este último año y medio he estado trabajando intensamente en cuestiones de automatización de pipelines e infraestructura en general, usando principalmente Jenkins, Puppet y herramientas afines.

En particular, estos últimos meses he trabajado en la automatización de despliegues de un producto software bastante complejo. La complejidad en este caso está dada por la gran cantidad de componentes de código e infraestructura involucrados: varias bases de datos relacionales, bus de servicios, sistema de colas, servidor de aplicaciones, servidor web, dispositivos móviles, etc. Al mismo tiempo el producto tiene un requerimiento de correr sobre distintos sabores de infraestructura (Oracle, IBM, OpenSource), lo cual requiere que cada ambiente (desarrollo, test, etc) tenga también varios sabores.

Para la generación de estos ambientes y el deploy de la solución a cada uno de ellos diseñamos una arquitectura de automatización/deploy de 3 capas la cual describo brevemente a continuación.

Capa 1: Sistema operativo

El primer paso es levantar los servidores con el sistema operativo correspondiente (para el caso mencionado CentOS y Oracle Linux) y realizar algunos ajustes de base sobre el mismo (configuración de red, usuarios, etc). En general esto se hace utilizando la API de la plataforma de virtualización y algunos scripts de base. Puntualmente en el mencionado caso usamos el Hypervisor de VMWare y Puppet.

Capa 2: Software de base

Ya con el sistema operativo instalado y servidor 100% funcional hay que instalar software de base: motor de base de datos, el service bus, el web server, etc. Cada uno de estos componentes hay que instalarlos y configurarlos acorde a seteos específicos de la solución. En el caso mencionado esto lo hicimos usando scripts Ansible que se disparan desde RunDeck

Capa 3: Aplicación

Lo último que resta es instalar la solución en cuestión, lo cual implica crear los schemas de base datos, desplegar las aplicaciones en los servidores/contenedores web, desplegar los flujos en el bus de servicios, etc. En el caso en cuestión esto lo tenemos implementado con simples bash scripts que lanzamos desde Jenkins.

La implementación de esta solución en este caso puntual requirió del trabajo de distintas áreas de la organización: gente de infraestructura (capa 1), gente de operaciones (capa2), gente del grupo de producto (capa3) y obviamente hubo también un cierto esfuerzo de coordinación de todos ellos.

Hay algunas cuestiones de la implementación de este caso que aún hoy no me convencen (como usar Puppet Y Ansible al mismo tiempo, hubiera preferido usar sólo 1 de ellos) y que son consecuencia de decisiones tomadas por los distintas áreas de la organización. Más allá de las herramientas particulares, creo que el esquema general de esta solución es replicable en otros contextos usando incluso otras herramientas, es por ello que decidí compartir estas líneas.

capas_automatizacion