AWS OpsWorks: automatizando la creación de servidores

OpsWorks LogoLas nubes por definición son sistemas informáticos que crecen o decrecen según la necesidad. Son conjuntos de servidores/servicios que se adaptan a la demanda. Con todo esto, llegamos a una de las cosas más interesantes de AWS, el auto-escalado o la tolerancia a fallos, además de la personalización de los servidores. Podemos controlar la carga de los servidores que haya. Además automatizar el arranque y parada a ciertas horas de algunos de los servidores. O podemos duplicar los sistemas para evitar los ‘single point of failure como una casa’.

En OpsWorks tenemos herramientas muy interesantes relacionadas con esto. Algo rústicas, quizá clásicas dirían algunos. Pero gracias a ello, sin límites en la flexibilidad para configurar. Y si lo llevamos al extremo, este mismo sistema nos puede servir para automatizar la creación de nuestros servidores con herramientas como Chef y Kitchen. Todo esto y mucho más es lo que se puede hacer con el clásico OpsWorks.

Primero tendremos que ver qué son las AMIs. Cómo crear una manualmente o automáticamente. Y finalmente veremos cómo se usan, para hacernos una buena idea de qué podemos hacer en OpsWorks, y si es o no lo que necesitamos. Quizá es interesante ir a Docker con el EC2 Container Service o a CloudFormation, pero esto son otros temas..

No voy a entrar al detalle de cómo hacer cada cosa, no terminaría nunca. Así que si buscas una guía general para enfrentar después cada detalle poco a poco, este es tu post.

Las Amazon Machine Images, AMIs para los amigos

Las AMIs significan instancias de máquinas de Amazon. Son servidores con todo el software empaquetado y listo para arrancar y servir. Si usamos EC2, veremos lo sencillo que es arrancar un nuevo servidor. EC2 es la herramienta básica de AWS, con ella tenemos un panel de control desde el que veremos todas nuestras instancias.

EC2 arrancando nueva instancia

En esta imagen podemos ver cómo se navega entre el catálogo de AMIs disponibles. Cuando vamos a arrancar un servidor y a configurarlo manualmente, veremos que hay un mercado enorme de servidores listos para usar. Podemos encontrar Linux limpios recién instalados, igualmente Windows. Tenemos una cantidad ingente de máquinas pre-instaladas para correr entornos LAMPP, WAMPP, MAMPP, con CMSs, todo tipo de bases de datos, todo tipo de software tanto de pago como Open Source. Es decir, hay publicados muchos servidores pre-empaquetados y listos para usar. Algunas máquinas son de uso gratuito, otras se pagan por hora. Depende de si el software que llevan tiene coste de licencia o no.

No tienes porqué usar una AMI completa parecida al entorno que necesitas. Habrá que estimar si quieres eso o crear tu propia AMI. Puedes acabar teniendo una caja negra dependiendo de cómo decidas trabajar. Una caja negra pre-configurada en la que tendrás que ceñirte a las especificaciones de los creadores. La alternativa es: elegir el sistema operativo básico y construir el servidor a nuestro gusto. Podremos construir nuestros servidor manualmente o usando el mismo OpsWorks como ya decía, automatizando toda la instalación de herramientas. Estos servidores construidos serán los que guardaremos en nuestras AMIs. Podremos publicarlos en el marketplace de Amazon o dejarlas en nuestra zona privada. Y estas AMIs nuestras, serán las que posteriormente mejor vamos a usar en OpsWorks.

Qué es OpsWorks

OpsWorks es el sistema por el cual se puede automatizar el arranque, despliegue, paradas e incluso la configuración de nuestros servidores donde van a correr las aplicaciones software. Ya llegaremos a todo esto. Primero tenemos que en OpsWorks podemos crear varias pilas de trabajo, en cada pila de trabajo tendremos varias capas, y algunas de las capas son recursos que pueden provenir de otras partes del sistema.

Un caso de estudio, un OpsWorks con 4 pilas de trabajo:

opsworksdashboard

Podemos ver que tenemos cuatro stacks configurados en eu-west-1. Inicialmente teníamos una pila de pruebas, y otra de producción. La llamada OLD Develop era la pila de pruebas en donde desplegábamos las nuevas versiones del software. Aquí probábamos que todo iba bien. Es una réplica de producción, pero más pequeña. Luego tenemos la OLD Production, que es igual que OLD Develop pero con más recursos e instancias más grandes.

Esto derivó a un sistema en el que localmente en cada ordenador de cada desarrollador replicábamos un entorno completo igual al de producción, usando Vagrant. Ya no era necesario tener dos entornos. Aunque sí era interesante por eso de evitar el famoso problema de ‘¡En mi máquina funcionaba!’. Para reducir gastos, se cerró el entorno de pruebas en AWS y se derivó a los otros dos cuando pasamos las recetas de creación de servidores a la última versión: AMI factory y Production.

En la AMI factory, como su nombre indica tenemos programada la creación de un servidor completo desde cero. No tenemos más que lanzar la creación; arranca un Ubuntu 14.04 LTS con toda la batería de herramientas y configuraciones. Acto seguido sale, como recién salido del horno, una nueva AMI que podemos guardar en nuestra zona de EC2 para luego reutilizar en la pila de producción que queramos. Luego veremos estas dos últimas pilas al detalle.

Partiendo de una AMI hecha manualmente

Recapitulando, una forma de empezar rápido sería con EC2. Lanzamos una instancia del sistema operativo que queremos, por ejemplo un Ubuntu 14.04 LTS. También tenemos la opción de usar una AMI de otros, y adaptarla como decíamos anteriormente. Es decir, arrancamos, configuramos todo lo que necesitamos y lo guardamos en una AMI con el nombre que queramos. Esto es bastante rápido pero a la larga seguro que nos olvidaremos de todas las configuraciones que estamos haciendo y probablemente marranearemos el sistema. Con el paso del tiempo podemos olvidarnos de qué tantas cosas hicimos. Y quizá introduzcamos errores difíciles de subsanar. Más que nada, porque probablemente no nos acordaremos de absolutamente todos los cambios que hemos ido haciendo.

Con estas AMIs tendremos de vez en cuando que arrancar una instancia nueva a partir de nuestra AMI, actualizarla, aplicar los cambios que necesitemos y de nuevo guardarla. Podemos nombrarla con algún identificador o poniéndole versión. Ya cada uno como quiera. Esto es lo más rápido, pero repito, al final acabas teniendo una caja negra en la que no sabes muy bien que es lo que tienes. Esta es la forma rápida y menos trabajosa de hacer las cosas.

Automatizando la creación de una AMI

Lo ideal es entonces automatizar la creación de nuestras AMIs. Esto es lo que podemos hacer como en el caso de estudio anterior. La pila AMI factory de este proyecto simplemente está pensada para arrancar una instancia de Ubuntu 14.04 LTS, como he dicho antes, y configurarlo todo para el proyecto.

OpsWorks AMI factory

Como podemos ver en las recetas de Chef, con ocho recetas tenemos configurado un nuevo servidor recién salido del horno. Aquí lo que tenemos es una aplicación Symfony. Las aplicaciones de Symfony son aplicaciones muy ligeras. Generalmente son más pequeñas que CMSs completos. Aunque cada vez más podemos encontrar proyectos muy grandes desarrollados sobre Symfony.

Así que manos a la obra, con las siete primeras recetas se ha configurado un servidor con todas las herramientas que va a necesitar el proyecto. Hay una zona de OpsWorks en donde podemos pasar todos los parámetros de configuración. Es en Stack Settings, en donde podemos elegir configuraciones, e incluso pasar un JSON personalizado con todas las variables que queremos. Por ejemplo claves de la base de datos, certificados de seguridad, tamaño de fichero swap, tamaño de ramdisk, etc.. Es decir, cualquier cosa que podamos hacer manualmente en un servidor localmente o en la nube, también se puede automatizar en una receta de Chef. Cualquier cosa se puede configurar con Chef y OpsWorks, cualquier tipo de servidor, es decir, todo. Esto es sencillo aquí, y puede que sea engorroso en otras herramientas como BeanStalk o los famosos Docker, que están en una capa por encima del sistema operativo.

Lo que quiero decir es que con Chef podemos controlar al milímetro cualquiera de las configuraciones del sistema operativo que necesitemos. Cualquier cosa que podamos hacer mediante línea de comandos en un servidor, aquí también lo podremos hacer. Incluso para rizar el rizo, con Kitchen y Chef 12 en local, podremos incluso replicar un entorno casi idéntico a una pila de OpsWorks en local. Con variables de entorno e incluso el custom JSON. Jeje, esto también es material para otro post..

Reutilizando una AMI creada en una pila de OpsWorks en otra pila

Si nos fijamos en la pila anterior de la AMI factory, podemos ver que la última receta se llama ops12::clean_before_create_ami. Esta receta lo que hace es limpiar la instancia recién creada. Entonces deja la instancia lista para pararla, y guardar como una nueva AMI. Mucha gente comparte recetas de Chef, sobretodo de la versión 11 aunque cada vez más la comunidad de desarrolladores va compartiendo de la versión 12. Chef usa Ruby para automatizar las personalizaciones. Por ejemplo, la receta de limpieza final es la siguiente:

bash "clean_before_create_ami" do
  user "root"
  code <<-EOH
  /etc/init.d/monit stop
  /etc/init.d/opsworks-agent stop
  rm -rf /etc/aws/opsworks/ /opt/aws/opsworks/ \
    /var/log/aws/opsworks/ /var/lib/aws/opsworks/ \
    /etc/monit.d/opsworks-agent.monitrc \
    /etc/monit/conf.d/opsworks-agent.monitrc \
    /var/lib/cloud/ /var/chef /opt/chef
  dpkg -r opsworks-agent-ruby
  dpkg --purge opsworks-agent-ruby
  dpkg -r chef
  dpkg --purge chef
  EOH
end

Simplemente son varios comandos de Linux que los ejecuta desde el usuario root para desinstalar el agente de OpsWorks. Chef es una tecnología de automatización de acciones. Estas acciones las puedes ejecutar en servidores. Y tengo entendido que todo esto es uno de los pilares que sustenta AWS, me han dicho los maestros jedi de la nube..

Si conoces Vagrant, y has usado ficheros de aprovisionamiento, es muy sencillo pasarlo a recetas de Chef. Chef, como decía antes, usa Ruby como lenguaje de programación y unas estructuras de directorios con las que configurar el entorno. Podemos junto con Kitchen crear en local nuestro entorno de desarrollo. Tendremos entonces nuestra cocina Kitchen en donde crear nuestras recetas de Chef.

Balanceando y auto-escalando

Con todo esto llegamos al balanceado y auto-escalado de las instancias. Es decir, a partir de Chef podremos controlar nuestras instancias de lo que necesitemos. Podremos crear todo tipo de servidores. Entonces, estos servidores tendrán un tamaño óptimo, que debería de ser el mínimo necesario para dar el servicio. Ahora viene el balancear la carga y arrancar nuevos servidores según la carga o el tiempo predefinido. Por ejemplo una pila de trabajo real, en la que tenemos una capa de aplicación con estos servidores:

OpsWorks instances

Aquí podemos ver 2 servidores de tipo 24/7 que siempre están arrancados. Si fallara uno estará el otro. Y dos servidores de tipo Load, los 3 y 4, que arrancan automáticamente si la carga de los servidores 1 y 2 es alta. Esto es el corazón del sistema que hace correr la aplicación web, en este caso un Magento como se puede ver. Antes de las instancias tendremos un balanceador de carga y después una base de datos.

Me he saltado la definición de las capas. Podemos ver un caso sencillo de dos capas:

OpsWorks layers

Aquí simplemente tenemos la capa de las intancias y la de la base de datos. En este proyecto, como no hay demasiada carga de trabajo en las instancias de momento no es interesante balancear la carga. A continuación otro proyecto con tres capas:

OpsWorks layers

Creo que no hace falta explicarlo mucho ya que es obvio. Un balanceador que balanceará las visitas entre las instancias. Este balanceador se comunica con las instancias para saber cuál está online. La capa de la aplicación que corre el Magento. Y la base de datos por debajo. Aquí podemos añadir todas las capas que necesitemos, cada una con los elementos que queramos.

Terminando

Para terminar no me queda más que decir que el principal trabajo en OpsWorks es el trabajo de chef de cocina. Suena chistoso pero así es. Con Kitchen y Chef puedes hacer todo lo que quieras con los servidores, incluso automatizar la creación de ellos. Se pueden arrancar los servidores desde cero, que se creen desde cero en el momento de ser necesarios. Pero es mejor crear los servidores a parte como indicaba al principio del post, para guardarlos en una AMI. Así esta AMI arrancará más rápido ya que no tendrá que instalar desde cero todas las herramientas.

Estas AMIs incluso se pueden empacar y prescindir por completo de todo el sistema OpsWorks. Podemos crearlas para luego usarlas en EC2 directamente. Podemos usarlas ya con el software instalado y hacer grupos de autoescalado en EC2. Meterles las configuraciones, en fin, aquí no hay límites. Pero si lo que necesitas es hacer muy a menudo despliegues es muy interesante OpsWorks porque puedes automatizar hasta los despliegues continuos después de las pruebas de integración.

OpsWorks deployments

Aquí tenemos la zona de despliegues de un proyecto sencillo. Al desplegar podemos elegir en qué instancias desplegamos qué aplicaciones. Podemos elegir sobre qué instancias desplegamos, o replegamos. Podemos elegir primero unas instancias, y si despliega correctamente, luego desplegar el resto. Así te aseguras de que si falla puedes dejar de desplegar en el resto hasta encontrar el problema y no dejar de dar el servicio.

Vamos a dejarlo, que ya me he extendido demasiado. Otro día más. Si has vuelto a llegar hasta aquí abajo te lo agradezco si dejas un mensaje así sabré que alguien me lee y no has sido una visita que rebota sin llegar al final xD

¡Un saludo!

Compartir..

Dejar un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

2 × 3 =