Mostrando entradas con la etiqueta development. Mostrar todas las entradas
Mostrando entradas con la etiqueta development. Mostrar todas las entradas

martes, 14 de marzo de 2017

Aprovisionando ambientes AWS con Ansible



En recientes fechas se nos encomendó la misión de optimizar costos y el uso de recursos de Amazon Web Services utilizados para el despliegue y operación de aplicaciones de uno de los clientes principales de InnBit.

Esta reestructura fue vista como una oportunidad para implementar mejoras en la forma de trabajo con AWS que habíamos estado teniendo. Un punto muy particular es el aprovisionamiento de ambientes que implica lanzar una nueva instancia de EC2, actualizar paquetes, instalar dependencias, configurar el ambiente y desplegar la aplicación para dejar todo listo para que esté disponible para su uso.

Todos los pasos descritos con anterioridad son repetitivos y son propensos a ser automatizados por lo que se decidió incluir la herramienta Ansible para facilitar las tareas de aprovisionamiento y despliegue así como reducir posibles errores y el tiempo que se empleaba para poner a punto las aplicaciones.

Ansible


Ansible es una herramienta de código abierto escrita en python para la automatización y orquestación de tareas 

A diferencia de otras soluciones similares, no requiere la instalación de agentes remotos pues su funcionamiento es mediante la ejecución remota de comandos mediante mecanismos como ssh o Windows Remote Managment.

Los comandos son definidos en archivos de texto en formato YAML y permite realizar ejecuciones de comandos repetibles y distribuidas en varios nodos.

Caso de uso


Durante 2016 se desarrollaron aplicaciones que estuvieron en producción casi todo el año. Cuando concluyó este, dichas aplicaciones también terminaron su ciclo debido al fin por el cual fueron construidas. Aún así el cliente solicitó que se mantuvieran activas para fines demostrativos. 

Por ciertas razones, en su momento se reservó una instancia EC2 con las siguientes características
  • Red Hat Enterprise Linux 
  • Reservada hasta el 20 Junio de 2017
  • t2.medium


De acuerdo a los datos de uso y pruebas, se estima que esta instancia sería capaz de manejar de 3 a 4 aplicaciones con baja demanda. De este modo se determinó que la instancia RHEL sería aprovechada para hospedar las aplicaciones con propósito demostrativo.

Para facilitar la configuración y puesta en marcha de varias aplicaciones en un mismo servidor se decidió generar imágenes docker con cada una de las aplicaciones. Estas imágenes serían almacenadas en el registro de contenedores de EC2 (EC2 Container Registry, ECS) donde estarían disponibles para la ejecución de contenedores.

Otro beneficio de utilizar docker es el redireccionamiento de bitácoras. Anteriormente, para revisar una bitácora era necesario ingresar al servidor y explorar los archivos mediante comandos de Linux para procesamiento de texto. Conforme se incrementa el número de servidores y la incorporación de servidores surge la necesidad de concentrar las bitácoras en un solo punto de modo que la detección de errores y solución de problemas sea más ágil.

Docker ofrece un controlador que permite captar la bitácoras generadas por las aplicaciones dentro de los contenedores y enviarlas al servicio CloudWatch el cual incorpora una funcionalidad para concentrar bitácoras y explorarlas.

Todo el proceso desde la instalación de dependencias hasta la ejecución de las aplicaciones en forma de contenedores fue definido mediante un proyecto Ansible quedando el panorama como se muestra en la imágen.




Proyecto Ansible

Para intentar mantener ordenado y simple el proyecto, se ha organizado de la siguiente manera.

Inventario y Archivos de recursos

El inventario es el archivo de nombre hosts, el cual contiene un grupo de servidores con la ubicación de la instancia RHEL en Amazon.

En la carpeta resources/yum se guardan definiciones de repositorios para instalar los paquetes nginx y docker de acuerdo a la documentación de ambos productos. La idea es que estos archivos sean copiados, utilizando Ansible, a la instancia remota en la ubicación adecuada.

En la carpeta resources/env se guardan archivos con las variables de ambiente requeridas por las aplicaciones. En este punto se pretende nuevamente copiar estos archivos de configuración al servidor y leerlos mediante docker al momento de lanzar los contenedores.

Playbooks

Los playbooks son archivos en formato YAML donde se definen todos los comandos que serán ejecutados en el servidor.

Se separaron las tareas de instalación y configuración de acuerdo al paquete y/o aplicación para mantener compactos los archivos.

nginx.playbook.yml. Instalación típica de NGINX para RHEL, en este caso se utilizó ansible para copiar el archivo ./resources/yum/nginx.repo con la ubicación de paquetes actualizados para la instalación.




awscli.playbook.yml. Instalación de la linea de comandos de AWS. Este se utilizará para la interacción con EC2 Container Registry.


docker.playbook.yml. Instalación y configuración de Docker de acuerdo a la documentación oficial. De igual modo que el anterior, se actualizó la definición de repositorios mediante el archivo ./resources/yum/docker.repo que es copiado al servidor para posteriormente realizar las tareas de actualización de paquetes. Al final se genera el grupo docker y se define al usuario ec2-user como miembro de modo que pueda ejecutar comandos docker sin permisos de super usuario.



cop13.playbook.yml. Ejecución de contenedor docker a partir de una imagen alojada en EC2 Container Registry. Esta imágen contiene una aplicación Ruby on Rails que será ejecutada en el puerto 3000 del contenedor. Mediante ansible, además de lanzar el contenedor, también se establece la correspondencia de puertos (3000:3000), el archivo con las variables de entorno requeridas y el redireccionamiento de bitácoras a CloudWatch.


igf.playbook.yml. Ejecución de un segundo contenedor docker a partir de otra imagen alojada en ECR. La ejecución del contenedor es similar al anterior con pequeñas diferencias como la imagen que se toma, el puerto del servidor que se redirecciona al contenedor (3100:3000), las variables de entorno y el destino de bitácoras dentro de CloudWatch.


rhel-demo-server.playbook.yml. Este archivo incluye referencias ordenadas a los demás archivos de modo que permite mantener la secuencia lógica con las cuales se van a ejecutar las instrucciones.

Conclusiones


Al final los archivos de ansible permitieron la puesta en marcha de las aplicaciones partiendo de una instancia nueva de EC2. Como ventaja estos archivos permiten la replicación automatizada de este ambiente en nuevas y diferentes instancias.

Estos scripts también son propensos de ser incluidos en un conducto de entrega y despliegue contínuo, pero será tema de otra entrada del blog.

viernes, 30 de diciembre de 2016

La odisea de certificarse en Bluemix


Pues para rematar un año que la he pasado de nube en nube, me propuse como última batalla épica del año completar una certificación relacionada con la plataforma PaaS de IBM conocida con el nombre de Bluemix.

Bluemix es un servicio que proporciona una plataforma para el despliegue de aplicaciones construidas en diferentes tecnologías (Java, Node.js, Ruby, Go, etc). 

Además cuenta con un amplio catálogo de servicios administrados que pueden ser facilmente vinculados a las aplicaciones. De estos servicios se pueden mencionar bases de datos, almacenamiento de objetos, cómputo cognitivo, monitoreo, repositorios de código, despliegue contínuo, contenedores docker, mensajería, entre muchos otros. 

Bluemix está pensada en ser una oferta de servicios de nube a nivel plataforma (PaaS), es decir facilita la puesta en marcha de aplicaciones y consumo de servicios sin la necesidad de entrar en lios a nivel de infraestructura. Además se basa en proyectos conocidos en la comunidad de desarrollo como Cloud Foundry y Docker además de utilizar un enfoque de microservicios accesibles via REST / HTTP.

Durante algunos proyectos en el año y un pequeño acercamiento con gente de IBM se tuvo la oportunidad ganar experiencia en esta plataforma y dado que parece una navaja suiza que ofrece todo lo necesario a un desarrollador que quiere enfocarse en la construcción de la solución decidí completar alguna certificación en esta plataforma tratando de narrar el proceso de la forma más pseudo-épica posible (dados mis vagos conocimientos Homerísticos).

Saliendo de Ítaca

El punto de partida fue encontrar algún examen dentro de la oferta de IBM relacionado con los temas de Bluemix lo que me llevó al examen C5050-285 - IBM Cloud Platform Application Development v1.

Los objetivos del examen son algo extensos pero se pueden resumir en:

  • Organizaciones, Espacios, Usuarios, Dominios y demás lios de acceso a la plataforma
  • Generalidades de la plataforma CloudFoundry y el despliegue de aplicaciones
  • Servicios de datos ofrecidos, haciendo énfasis en Cloudant
  • Servicio de contenedores basado en Docker
  • Servicio de mensajería basado en Apache Kafka
  • Generalidades de Alchemy API
  • Servicios de DevOps como son el repositorio de código, delivery pipeline,  track and plan
Una vez fijado el objetivo y viendo que había mucho que estudiar comenzó mi búsqueda de material.


Consultando al oráculo

Dado que en el momento de embarcarme en esta empresa no tenía educación más o menos formal de temas de Bluemix, más allá de desplegar aplicaciones y habilitar algunos servicios, decidí buscar algún curso en línea que sirviera de inducción a los variados temas y me diera mejores armas para afrontar el examen. 

Mi punto de partida fue el curso de udemy IBM Bluemix Application Development & Certification, el cual abarca casi la totalidad de los temas además de incluir demostraciones, trivias y examenes muestra. 

Me tomó alrededor de dos meses completar los temas dedicándole de 2 a 3 horas regularmente, e incluso al finalizar el curso tuve que regresar a repasar los temas iniciales. Varios de las demostraciones me sirvieron de práctica al recrearlas paso a paso y los examenes muestra finales me sirvieron mucho de calentamiento.

Una vez que completé el curso leei la guía de estudio publicada por IBM, la cual es un muy buen resumen de todos los temas. Además al final de la misma contiene unos códigos de descuento para la evaluación preeliminar y el exámen.

Dentro de los recursos de estudio ofrecidos por IBM también se cuenta con un documento con preguntas muestra disponible de manera gratuita. 

Un último recurso que ocupé fue el examen muestra en linea, disponible en el portal de Pearson Vue, con el titulo A5050-285 Assessment: IBM Cloud Platform Application Development v1. Esta evaluación consiste en 48 preguntas y al final da un reporte similar al del examen real.


Gorgonas, sirenas y otros mounstuos

Además del estudio de la teoría sin duda fue fundamental la práctica que tuve tanto en las peticiones para clientes como en pequeños ejercicios de auto estudio que podrían ser resumidas en lo siguiente.

Debido a proyectos
  • Despliegue de una aplicación node.js
    • Vinculada a servicios Watson
    • Vinculada a una base de datos Cloudant
    • Almacenada en el repositorio JazzHub
    • Desplegada mediante Delivery Pipeline
  • Despliegue de una aplicación web ruby on rails
    • Vinculada a una base de datos Postgresql
    • Vinculada a un contenedor de ObjectStorage
    • Configurada en alta disponibilidad con un balanceador de carga
    • Vinculada a una instancia de Redis
    • Desplegada con un buildpack específico
  • Despliegue de un worker ruby on rails
    • Vinculada a una base de datos Postgresl
    • Vinculada a una instancia de Redis
    • Desplegada con un buildpack específico
Ejercicio de autoestudio
  • Instalar Docker localmente y realizar los tutoriales básicos 
  • Construcción una imagen Docker y publicación en Bluemix
  • Prueba de concepto de publicación y consumo de mensajes en Message Hub (Kafka)
  • Recordar conceptos de Scrum y experimentar como encajan en Track and Plan
  • Leer teoría de las aplicaciones de 12 Factores

Conquistando Troya

El día pactado para el examen fue el 29 de diciembre del 2016 y la cita fue en el centro de certificación de casa (aprovechando que solo hay que subir un piso). 

El examen contiene 48 preguntas a realizar en 90 minutos con un mínimo de 32 aciertos para acreditarlo (66%). Había preguntas de casi todos los temas, aunque las más recurrentes tenían que ver con temas de despliegue en CloudFoundry, autoescalamiento, monitoreo y Cloudant. 

La mayoría de las preguntas eran distintas a las realizadas en los examenes de prueba pero en su mayoría temas que se habían estudiado. Muchas preguntas planteaban situaciones prácticas que requerían un poco de razonamiento detenido y algunas más solo teniendo experiencia práctica era posible responder.

Al final el examen me pareció un buen reto y un poco más duro de lo que esperaba pero el estudio y la práctica me permitieron acreditarlo exitosamente al final. Además, más allá del resultado, me quedo con una visión más amplia de esta propuesta de IBM y mucho conocimiento nuevo en temas como Docker, Kafka y Cloud en general.




lunes, 24 de octubre de 2016

Descubriendo lo elemental de la conversación en Watson

Recientemente, para uno de los clientes, se ha estado trabajando con "la mezcla azul" de IBM y su oferta de servicios de nivel plataforma (PaaS), es decir servicios administrados con el propósito de montar aplicaciones. Por mencionar algunos de estos servicios se tienen los servicios de despliegue de aplicaciones para diferentes lenguajes (node.js, java, ruby on rails,...), bases de datos relacionales y no-sql, almacenamiento de objetos, balanceo de carga, servicios de integración y despliegue contínuo, repositorios de código, entre otros.

Dentro de la oferta de servicios ofrecidos destacan aquellos agrupados bajo el nombre de Watson los cuales están enfocados al "cómputo cognitivo", o dicho en otras palabras son una serie de servicios que permite generar aplicaciones donde la experiencia de usuario es cercana a la interacción que se podría tener con otra persona como si de una conversación se tratara.

Precisamente el servicio conversation es el punto medular para el desarrollo de soluciónes que permitan a un usuario la interacción de forma cuasi-natural con una computadora, también conocidas como bots.

En principio, el servicio de conversación parecía un poco intimidatorio, pues la documentación presenta un mar de conceptos que requieren un poco de estudio y experimentación. De este modo se ha intentado sintetizar un poco la información y presentarla de manera más pragmática a los lectores de la lengua de Cervantes.

Dialog vs Conversation

Anteriormente existía como tal el servicio de dialogo dentro de la oferta de Bluemix. Este servicio tenía el mismo objetivo que la conversación, aunque se definía mediante un archivo XML que debía ser construido desde un editor de texto y se conformaba de una gran variedad de elementos, algunos no tan bien documentados. 

Actualmente el servicio de diálogo ha sido retirado de Bluemix para dar paso a la conversación la cual incorporó una serie de mejoras respecto a su predecesor de las cuales podemos destacar: incorporación de una interfaz gráfica para la construcción del servicio; incorporación de intenciones y entidades que permiten mejorar el flujo de la conversación; simplificación del API para consumo desde aplicaciones; espacios de trabajo para agrupar elementos.

Espacios de trabajo

Las conversaciones están organizadas en espacios de trabajo (workspaces) los cuales son definidos por un nombre y un idioma.

Al generar un espacio de trabajo se genera un identificador único, el cual es utilizado para interactuar con la conversación que contiene a través de llamadas al API y así poder integrar aplicaciones.

Una vez creado un espacio de trabajo se requiere definir los elementos base de la conversación: intenciones, entidades y el diálogo.



Otra bondad del servicio es que cada espacio de trabajo puede ser exportado en un archivo en formato JSON totalmente portable ya sea con fines de respaldo o para clonar el espacio de trabajo original.

Intenciones

Dentro del servicio son palabras clave precedidas por el símbolo # y reconocidas por un nombre. Las intenciones se alimentan mediante ejemplos y mediante algoritmos estadísticos permiten determinar que tan aproximado es un texto introducido por un usuario a uno de los ejemplos y categorizar dicha entrada en una intención. 

Intención que permite identificar respuestas negativas

Entidades

Las entidades son utilizadas para extraer información relevante a partir del texto de entrada. Las entidades pueden ser utilizadas para refinar el comportamiento de la conversación y establecer respuestas más específicas.

Las entidades son precedidas por el símbolo @ y se definen por un valor y una lista opcional de sinónimos.

Entidad nombres. Los valores se utilizan para determinar la entidad.

Diálogo

El diálogo se asemeja a una máquina de estados, llamados nodos dentro del servicio, en el cual si se satisface una condición, se lleva a cabo una transición a otro estado. El diálogo permite generar una respuesta de acuerdo a una entrada de texto, dependiendo del nodo en el cual se encuentre la conversación. 

Diálogo conformado por nodos. Cada nodo tiene una condición y una salida
Dentro del diálogo, las entidades y las intenciones pueden ser utilizadas como condiciones para que el diálogo identifique la respuesta más adecuada.

Textos de entrada

El texto de entrada por un lado permite definir la información de entrada que será procesada por la conversación y por otro es la acción que dispara la evaluación de condiciones y la transición entre los nodos del diálogo. Esto es, que la conversación se mantendrá en un nodo en espera a que se proporcione un nuevo texto de entrada.

Gráficamente se puede observar el ícono del "globo" de conversación con los tres puntos entre los nodos lo cual representa que en ese punto se espera un texto de entrada.


Condiciones

En cada nodo se puede especificar una o más condiciones, de modo que si estas se cumplen entonces la conversación es ubicada en dicho nodo y el servicio regresa la respuesta establecida en el mismo.

Las condiciones pueden ser intenciones, entidades o valores específicos y puede haber más de una condición en el mismo nodo evaluándolas con los operadores AND y OR. Cabe mencionar que las condiciones se van cumpliendo de acuerdo a las intenciones y entidades identificadas en el texto de entrada de cada nodo.

En el nodo padre como condición se observa la conjunción (AND) de una intención y la negación de una entidad. En el nodo hijo se observa la disyunción (operador OR) de dos intenciones.
Las condiciones definen en gran medida el flujo de la conversación, pues cada vez que se introduce un texto se evaluan las condiciones del nodo hijo ubicado a la derecha del nodo actual. Si la condición no se cumple se continua con el nodo hermano ubicado justo abajo y así sucecivamente hasta ubicarse en algún nodo que cumpla las condiciones en espera de repetir el proceso.

Las condiciones también pueden ser palabras reservadas del mismo servicio: conversation_start se utiliza para indicar el nodo inicial; Anything else se utiliza como valor por defecto para cuando las condiciones de ningún nodo son satisfechas por el texto de entrada.

Después que la conversación inicia se espera un texto de entrada. Después de ser evaluado se busca en la primera opción una entidad @nombre, en la segunda una intención #greeting y que no aparezca ningún @nombre. En caso que ninguna condición se cumpla se continua la conversación en el nodo Anything else.

Continuar desde...

La opción Continue from... permite llevar la conversación de un nodo a otro totalmente distinto a manera de salto, similar a cuando se cambia de una página  de la mitad del libro al final para ver el glosario durante una lectura.



Esta opción es muy útil para reutilizar ramas de la conversación o recuperar la misma de un texto de entrada inesperado.

La claúsula Continue from... permite dirigir el flujo de la conversación a una entrada de texto, la condición de un nodo o el texto de salida.

Contexto

El contexto es un elemento que contiene valores que son mantenidos durante toda la conversación. Es posible agregar valores adiciones al contexto basándose en el estado de la conversación, entidades reconocidas o intenciones detectadas. Para esto se debe cambiar el modo de la respuesta de simple a avanzado para poder editar el objeto JSON.

Una vez en el modo avanzado se define la llave context y dentro del mismo los valores personalizados que pueden ser recuperados desde la aplicación cliente.

Estableciendo una respuesta avanzada en formato JSON para el nodo.
Los valores personalizados son sumamente útiles para el cliente pues pueden servir para casos de uso como: disparar acciones automáticas; mostrar recomendaciones o valores sugeridos; dirigir el flujo de la conversación.

REST API e integración con otros servicios de Watson

Como todos los servicios de Watson, la conversación expone una interfaz de programación de aplicaciónes via REST/HTTP. En este caso solo se expone un método que permite enviar el texto de entrada, junto los valores del contexto de la conversación al servicio y esperar un texto de respuesta. 

Internamente el servicio mantiene el estado de la conversación a través de un ID único y un seguimiento de las peticiones asociadas a la conversación, por lo cual es requerido enviar ese ID de conversación en cada petición dentro del contexto.

Dado que los servicios de Watson han sido desarrollados con el enfoque de microservicios, no se contemplan puntos de integración directa entre ellos. Sin embargo, es posible constuir una aplicación que se conecte a los diferentes servicios mediante el API REST y funcione como invocador de los mismos y la conversación pueda definir el momento de dicha invocación de acuerdo al estado de la misma. 

Conclusiones

El servicio de conversación es una interesante propuesta de IBM aplicable a casos donde se pretenda mejorar la experiencia de usuario para consultar información específica. 

Algunos casos de uso de este servicio pueden ser: servicio de preguntas frecuentes; asistente para dirigir la consulta de información; orquestador e integrador de fuentes de información.

Una vez que se ejercita un poco es sencillo construir un servicio personalizado para cada caso de uso particular que puede ser integrado via REST API en aplicaciones web y móviles. 

Referencias