Viendo la seguridad de la configuración con Azure KeyVault, .Net Core y Azure DevOps

Por aquí ya hemos hablado una vez y otra sobre como gestionar los datos sensibles (como las cadenas de conexión) de nuestras aplicaciones, porque, claro, nadie debería de poner los datos de producción en el código fuente que grabamos en nuestro repo, ¿verdad?

Anteriormente las opciones pasaban por efectuar mezclas/transformaciones de tal manera que en tiempo de compilación se generara un archivo final con los datos sensibles correspondientes a cada entorno, lo cual si bien nos daba simplificación para colocar la clave correcta en el paquete y entorno correcto, nos obligaba a seguir versionando las cadenas de conexión en el código fuente (por no mencionar que había que compilar mas de una vez); la otra opción pasaba por gestionar dentro del entorno de destino (en nuestros ejemplos: WebApps) sobrescribiendo de esta manera los valores que vinieran desde el código fuente.

Dado que ni nuestro repositorio ni nuestra herramienta de integración/despliegue deberían contener datos sensibles, usaremos un servicio de nube que nos da la seguridad necesaria para gestionar nuestras credenciales, el Azure KeyVault, el cual nos permite almacenar de manera segura y granular ya sea certificados digitales como data sensible, pudiendo restringir quienes pueden acceder a que datos y a que no (aplicando Control de acceso basado en roles: RBAC). Un mecanismo usual de accesos a estos recursos sensibles es programar dentro de nuestra aplicación un código que lea los valores en tiempo de ejecución (procurando no releer el valor a cada uso, sino hacerlo una única vez), en este caso usaremos un enfoque distinto que consistirá en leer los valores almacenados en KeyVault durante nuestro pipeline de despliegue, alterando secciones del archivo appsettings.json (porque nuestro ejemplo se basara en .Net Core) que se alojara en nuestra Web App destino (aunque también funciona perfectamente en un despliegue sobre IIS).

Así que estos serán los pasos que seguiremos:

  • Crear un KeyVault
  • Crear un «Secret» dentro de nuestro KeyVault, ahí sera donde almacenaremos una cadena de conexión a la base de datos
  • Identificar el «Principal» mediante el cual nuestro Team Project se conecta a Azure
  • Dar los permisos sobre nuestro KeyVault a dicho principal
  • Identificar en nuestra aplicación las secciones a modificar en tiempo de ejecución
  • Enlazar nuestro TeamProject contra el KeyVault, fijando el scope respectivo
  • Configurar el reemplazo de valores en el appsettings.json
  • Validar que nuestros cambios han sido desplegados en el entorno destino

Para esta demo asumiremos que tendremos tanto un pipeline de Build como de Release, de una aplicación en ASP.Net Core, en nuestro ejemplo usare la aplicación de ejemplo del libro de EF Core in Action (excelente libro que tuve el honor de revisar) cuyo código fuente se puede descargar aquí, y claro, como es usual el despliegue lo haremos contra una Azure Web App.

Para el primer paso seguiremos las instrucciones dadas en la primera parte de este articulo, en mi caso he usado estos nombres: RG_DevmoVault01 para el Resource Group y ErnestoDemoKeyVault para el KeyVault, como en este caso la creación la hemos hecho vía linea de comandos verificaremos que podemos revisar este recurso en el Portal de Azure, así:

Finish Reading: Viendo la seguridad de la configuración con Azure KeyVault, .Net Core y Azure DevOps

Presentando Azure DevOps

El día de hoy Microsoft anuncia Azure DevOps, que a primera vista podría ser un nuevo rebranding de VSTS, pero la realidad detrás de este cambio es mucho mas compleja, así que trataremos de explicarlo haciendo un poco de historia.

Team Foundation Server es presentado el 2005 como una solución integrada para las necesidades ALM de la época, en que se empezaba a buscar herramientas que apoyaran la gestión interactiva de proyectos, así como ir desarrollando los conceptos de Integración Continua y Gestión de Pruebas, rápidamente el producto fue adoptado por buena parte de las organizaciones que ya estaban trabajando con .Net como su plataforma de desarrollo de software, las versiones 2008 y 2010 fueron una mejora incremental que fueron simplificando el trabajo de los equipos, pero aun así el configurar un proyecto de Integración Continua requería pelearse con componentes de terceros y editar archivos XML.

El primer punto de quiebre se produce 2011 con el lanzamiento del preview de Team Foundation Service (que luego seria renombrado como Visual Studio Online) que al inicio era una implementación basada en Azure de los servicios que ofrecía TFS (y que me entusiasmo mucho apenas saque mi cuenta), pero que además de proveer al publico de una infraestructura ALM sin depender de la instalación de un servidor, permitió a Microsoft acelerar sus ciclos de entrega de novedades y pruebas de nuevas funcionalidades, siendo que la versión 2012 de TFS incluía como novedad esencial (al menos para mi) un nuevo modelo de creación de Builds Definitions, basado en XAML, que efectivamente hizo mas sencillo el proceso de despliegue… si usabas las plantillas proveidas en el producto! y es que la idea original era posibilitar la creación de plantillas personalizadas para diversos tipos de entorno (recuerdo que por ahí encontré una plantilla para facilitar el despliegue con ClickOnce, pero que nunca pude hacerla funcionar), para este año ya era mas que notorio el crecimiento de Git y GitHub como plataforma preferida de los desarrolladores, así que la versión 2013 de TFS incluía su propio repositorio Git (al igual que el entonces llamado Visual Studio Online), pero los cambios recién empezaban… Finish Reading: Presentando Azure DevOps

Usando Deployment Groups para facilitar nuestros despliegues sobre servidores (I)

Pues si, de vuelta… ya tocaba tener algo que compartir con ustedes, y en esta ocasión algo nuevo que sea de utilidad para quienes despliegan sus aplicaciones en servidores, pero… mejor contextualicemos.

Cuando originalmente empece a hacer mis pruebas de despliegue automatizado de aplicaciones en .Net tuve que hacerlo sobre servidores Windows, y para lograr eso se tenia que hacer varios pasos, instalar Web Deploy, asignar usuarios, activar servicios, pre configurar los WebSites o Aplicaciones Web, exportar un perfil, usar ese perfil dentro de la configuración de nuestro despliegue XAML, etc.. de hecho la cosa era tan tediosa que tuve que escribir una documentación de varias paginas para mi antiguo trabajo explicando como se hacia el proceso, y bueno… esa en parte fue la razon por la cual me he enfocado especialmente en lo que es despliegue sobre Web Apps, pero claro siempre me quedo el bichito de como ayudar a optimizar las cosas si la necesidad es trabajar con servidores ya sea IaaS u On Premise.

Así que desde hace unos meses he estado leyendo sobre una nueva funcionalidad que te ofrece VSTS llamada Deployment Groups (ya disponible de manera oficial) que esencialmente permite que tu aplicación se despliegue de manera sencilla hacia un servidor o conjunto de servidores, esto lo logra mediante la ejecución de un script (que ya veremos luego) en la(s) maquina(s) destino que esencialmente instala un agente que facilita la ejecución de los diversos pasos necesarios para la configuración el despliegue de nuestra aplicación, y cuando me refiero a configuración me refiero a que es posible realizar de manera desatendida la creación del Website o Aplicación Web en los servidores destino. Mas aun, esta funcionalidad permite agrupar nuestros servidores de manera lógica, de tal manera que no sea lo mismo desplegar a los servidores de QA que a los de Producción.

Todo bien, así que lo que trataremos ahora es de desplegar nuestra aplicación a un conjunto de Maquinas Virtuales creadas en Azure, las cuales estarán detrás de un balanceador de carga el cual nos proveera de una URL o IP unica, siendo que a la hora de efectuar la petición o request la respuesta podrá provenir de cualquiera de las maquinas virtuales que hayamos desplegado, lo cual facilita mucho la disponibilidad de nuestra aplicación, pero que a la vez proporciona retos respecto al manejo de sesiones y recursos compartidos. Finish Reading: Usando Deployment Groups para facilitar nuestros despliegues sobre servidores (I)

¡Mudanza en MySQL

Tal vez algunos recuerden pero hace un tiempo migre este blog de Blogger a un servicio WordPress alojado en Azure, ha sido un buen tiempo desde la migración pero lo que no comente plenamente en su momento es que para poder funcionar WordPress requiere contar con una base de datos MySQL, siendo que al momento de la migración Azure no proveía un servicio manejado de MySQL por defecto se nos ofrecía una base de datos gratuita proveída por ClearDB, lo cual nos hace tener que administrar ese servicio en «otro lado».

El caso es que entre las muchas novedades lanzadas por Microsoft en el Build del año pasado estaba el lanzamiento de una versión manejada (o sea que no tenemos que instalar un servidor Linux) de MySQL, por lo cual una de las cosas que pasaba por mi cabeza era migrar de ClearDB a Azure Database for MySQL, pero por una razón u otra siempre lo postergaba (aun cuando ya había creado una instancia en la misma zona geográfica y Resource Group que este blog!)

Y como suele suceder a veces es un hecho externo el que te hace pasar a la acción y en este caso fue la decisión de ClearDB de descontinuar los servicios gratuitos que estaba ofreciendo, dando como opción hacer un upgrade dentro de sus nuevos planes, pero como supondrán decidí hacer lo contrario y hacer pleno uso de mi BD en Azure, para lo cual seguí las instrucciones detalladas de este excelente post, con un salvedad que paso a contar:

El autor da las instrucciones para que una vez que, vía MySQL Workbench, nos hemos conectado a la BD destino y origen invoquemos un Wizard que efectúe la migración por nosotros y así lo intente, pero por alguna razón el efectuar pruebas consume el numero de conexiones que se pueden hacer hacia ClearDB, por lo que decidí jugar con otra opción: usar el backup que te ofrece ClearDB y tratar de restaurar en Azure, para lo cual entre a la consola web de ClearDB y exporte el ultimo backup disponible.

Una vez descargado el .zip exportado lo que tuve que hacer fue:

  1. Desempaquetar el archivo .sql que esta dentro del .zip (¡Si toda la base de datos esta en un archivo SQL!)
  2. En mi BD de Azure crear un schema con exactamente el mismo nombre existente en la instancia de ClearDB (para mas seguridad pueden copiar el comando de creación desde la BD origen)
  3. Seleccionar nuestra nueva bd/schema y ejecutar el SQL en cuestión.

Luego toca proseguir con las instrucciones del post respecto a la configuración de seguridad y conexión en nuestra Azure Web App de WordPress, pero adicionalmente es necesario editar el archivo wp-config.php de nuestro site, a fin de que todos los parámetros estén actualizados completamente, y claro luego de eso verificar que funcione adecuadamente, lo cual como pueden ver, va perfectamente.

Asi que … ¡gracias ClearDB, hola Azure Database for MySQL!

Las perspectivas PaaS Linux sobre Azure

Si hace unos años me hubieran dicho que estaría comentando sobre lo que menciona el titulo, me hubiera puesto a reír, pero el contexto tecnológico cambia de manera constante y este es el escenario en que los desarrolladores debemos tener claras nuestras opciones a la hora de considerar Linux como plataforma.

De mas esta comentar sobre las oportunidades que nos ofrece .Net Core para poder llegar a escenarios en los que tradicionalmente Windows estaba vedado, pero también debemos tener en cuenta las perspectivas de poder integrarnos y trabajar con otros stacks, así que si… Linux nos va a rodear bastante a los que trabajamos con .Net.

Ahora bien,  trabajar con Máquinas Virtuales Linux siempre ha sido posible desde que los proveedores de cloud empezaron a ofrecer IaaS, pero si uno basa su estrategia cloud en depender de máquinas virtuales que básicamente replican la arquitectura que se tenía on premise, no se está sacando partido de las potencialidades de la nube (optimización de costos y escalamiento) ni  tampoco se esta asumiendo un enfoque pragmático frente a los retos (o limitaciones) inherentes a la nube, como pueden ser los niveles de servicio asegurados por el proveedor (SAL), lidiar con las latencias, etc, esto y la necesidad de brindar a nuestros equipos de desarrollo con plataformas que aceleren su productividad nos deben obligar a mirar la nube más allá del IaaS.

Es con esta mirada que debemos analizar la propuesta PaaS que nos da Azure en el entorno Linux; recordemos que tradicionalmente si queríamos implementar una Web App lo que estábamos provisionando “por detrás” era una MV Windows con un IIS especialmente configurado para permitir las ventajas como slots, escalamiento, kudu, etc… lo cual nos va bien para aplicaciones .Net pero por ejemplo no nos permite correr aplicaciones Ruby, aparte de que existen escenarios en que se requiere cierta librería PHP que ¡oh sorpresa! tiene una fuerte dependencia con el sistema operativo Linux, así que era natural que Microsoft Azure venga a ofrecer una solución de Web Apps basada en Linux como una opción para los desarrolladores, misma que en este momento esta en versión de prueba.
top-level-create
Finish Reading: Las perspectivas PaaS Linux sobre Azure

Tip: Asignando Nombre DNS a nuestras MV en Azure

Una cosa a la que estábamos acostumbrados desde las primeras versiones de IaaS en Azure, era que en cuanto provisionábamos una MV se nos asignaba inmediatamente un nombre DNS por defecto …. Azure.  Por lo que era sencillo luego apagar la máquina y volver a acceder a ella basándonos en el nombre, esto cambio ligeramente con la introducción de los Resource Groups, siendo que si uno crea una MV usando esta “nueva” modalidad, por mas que uno haya definido un nombre para nuestra MV dicho nombre solo sirve como identificador del servicio dentro de Azure, mas no como parte del alias DNS, por lo que al crear nuestra flamante máquina virtual solo obtenemos la IP respectiva, la cual se perderá si apagamos la máquina y luego la reiniciamos.

Originalmente esto se podía solventar con un script de Resource Manager, pero también hay una forma visual muy sencilla de hacerlo, y para demostrarlo lo haremos desde el principio con una nueva MV de Windows Server 2012, así:

clipboard03

Finish Reading: Tip: Asignando Nombre DNS a nuestras MV en Azure

Y ahora verificando la performance (II)

Ok, esta vez si me he demorado en la segunda parte de esta serie sobre como agregar pruebas de performance a nuestros procesos de despliegue, en nuestro articulo anterior vimos como agregar configurar una prueba de carga sencilla, básicamente registrábamos una URL, el volumen de la prueba y listo… ya podíamos hacer una prueba preliminar que nos podría ser muy útil en algunos casos (como cuando todos los parámetros de una búsqueda están en el QueryString, por ejemplo), pero si queremos mayor granularidad en los parámetros de la prueba la alternativa es usar los Web Performance and Load Test Project que han ido evolucionando y que mediante el uso de Azure nos permiten desde Visual Studio tener unos resultados de prueba muy configurables, así:

Clipboard26

Y eso esta genial, pues nos permite (mediante nuestra cuenta de VSTS) provisionar recursos Azure que hagan la respectiva prueba mientras sea necesario, y que podamos ver dichos resultados desde nuestro Visual Studio, pero… ¿que tal si queremos que esta validación de carga decida si un despliegue ha ido bien o no? Pues eso es lo que trataremos de conseguir en este post.

En concreto lo que haremos sera agregar un proyecto de carga a nuestra solución, incluirla en el repositorio y de esta manera valernos de sus archivos para incluir un nuevo tipo de tarea durante nuestro proceso de despliegue, asumiremos que estamos trabajando con una solución Web que ya tiene configurado su repositorio asi como sus procesos de Build y Despliegue como hemos visto en anteriores artículos, ¿ok? Finish Reading: Y ahora verificando la performance (II)

Los dilemas de la Gestión de la Configuración en Entornos de despliegue

Si, se que les debo el como configurar la prueba de performance avanzada, pero en el interin quiero compartir unas reflexiones a propósito de la gestión de la configuración que vino a mi mente durante el DevDays.

Quienes han ido a mis diversas sesiones sobre VSTS o DevOps, sabrán que siempre hago referencia al lio que nos significa el gestionar los parámetros de configuración conforme una aplicación pasa de un entorno, el como manualmente uno tenia que tener mucho cuidado para asegurarse que la aplicación en Producción no apunte a la BD incorrecta, por mencionar el ejemplo mas claro.

Al empezar usar técnicas de Integración y Entrega Continua el primer enfoque que utilice para aliviar estos problemas fue el basarme en las Transformaciones, de esta manera se gestionaba un Web.Config «maestro» (en el caso de Java y Maven el escenario es muy similar solo que en este caso se trata de «pom»s»), que podía ser usado sin problemas en los equipos de desarrollo, pero al momento de efectuar la construcción de una nueva versión el compilador modificaba el Web.Config reemplazando porciones de este con contenidos especialmente definidos en archivos «delta» que contenían las variantes de cada destino al cual se iba a destinar la versión respectiva, en consecuencia ocurrían los siguientes hechos:

  • Se requiere hacer una Build Definition por cada potencial entorno al cual se iba destinar la aplicación, para de esta manera indicar que la construcción cogiera el «delta» correcto.
  • Si una versión puesta en un entorno es aprobada para ser «promovida» a un entorno superior, es necesario que dicha versión haya sido etiquetada o identificada adecuadamente a fin de poder recuperar el código fuente vigente entonces a fin de generar un paquete para el destino indicado.
  • Todos los «deltas» tienen que estar versionados en el código fuente, lo cual puede ser un problema si se desea mantener reserva sobre las cadenas de conexión a los entornos de Producción.

Aun así esto significa un gran avance con respecto a la gestión usual de editar y copiar a mano los archivos de configuración, donde revisas varias veces para ver que todo esta Ok. Otra opción, que no me gusta, es el de gestionar un repositorio (a veces separado del de código fuente) con todos los archivos de configuración de las diversas aplicaciones y que el proceso de despliegue simplemente copie el archivo respectivo en destino, y en algunos casos efectuar las mezclas necesarias de archivos.

La nube viene a significar una mejora en estos problemas, como vimos anteriormente  es muy sencillo configurar para que sea el Entorno (en este caso un Azure Web App, aunque AWS ofrece algo similar en su Elastic Beanstalk) sea quien almacene los mencionados parametros, y mas aun… gestionar ranuras de despliegue que permitan mover de manera sencilla el paquete de un lado a otro (en realidad mediante un cambio de DNS), conservando cada entorno su propio conjunto de parametros, sin que estos tengan que almacenarse en el código fuente.

Muy bien, parte de los problemas simplificados, uno solo creaba una Build Definition con paso de despliegue a un entorno y luego mediante la consola del entorno se encargaba de hacer los respectivos swaps o intercambios de contenidos, pero eso nos dejaba con los siguientes hechos:

  • Se salia fuera del ciclo automatizado de Integración y Entrega Continua para hacer el movimiento entre entornos.
  • Solo funciona en un entorno PaaS, si se trabaja con IaaS u On Premise, esta ventaja esta totalmente fuera de nuestro alcance.
  • Si se trabaja con AWS, hay que tener cuidado con no publicar valores en los archivos de configuración, pues (a diferencia de Azure) las variables definidas en el entorno solo funcionan si NO están definidas en los archivos de configuración, siendo que lo que este en los archivos tiene prioridad sobre el entorno.

El escenario ha mejorado bastante con la introducción de Release Management, que permite manejar el proceso de Build de una manera separada del de Despliegue, para que de esta manera uno genere un paquete, lo despliegue (cogiéndolo de un punto de contacto común), y si luego se aprueba su paso a otro entorno (mediante el flujo de aprobadores que ya hemos visto) el sistema efectuara la copia respectiva del paquete, y claro si seguimos trabajando aprovechando las ventajas de la gestión de parametros en el entorno… pues ya tenemos casi todo solucionado, solo que entre otras cosas… esto sigue siendo valido solo para PaaS.

En el ultimo DevDays tuve la ocasión de conversar con el gran Donovan Brown, el cual me ayudo con unos detalles de Release Management que no había configurado del todo bien, y en adición a ello le resumí brevemente sobre el enfoque de uso de Azure Web Apps para guardar parametros, y me dijo que es una buena opción para soluciones no complejas, pues solo podemos guardar AppSettings y Cadenas de Conexión, siendo que si requerimos grabar una entrada compleja (como la configuración de Redis) esto solo podríamos hacerlo mediante archivos de configuración, y como de nuevo esto nos regresa al tema de las transformaciones y las build independientes, me sugirió revisar el concepto de tokenización.

Investigando, pude entender (gracias a este interesante articulo) que mediante la tokenización lo que se pretende es que se despliegue un archivo de configuración con marcas (tokens) que luego en el proceso de despliegue (no en la compilación, ojo) sean sobreescritas por parámetros definidas en la Release Definition, resultando en que el web.config (por ejemplo) que llega al entorno destino ya tiene todos los valores correctos para dicho entorno, siendo que estos valores ya no son gestionados por el repositorio de código fuente, sino por el motor de Entrega Continua (en nuestro caso VSTS, pero el concepto es aplicable a otros motores), esta tendencia recién esta avanzando pero se simplifica mucho ahora que es posible definir tareas personalizadas a nuestro VSTS (y me imagino que ya habrá algún plugin Jenkins que logre el mismo efecto), ya que de momento no vienen de serie… pero eso no quita que en un futuro el proceso de tokenización venga de serie, de momento… tocara toquetear un poco… en el caso de ser necesario (cuando no se este usando PaaS y/o necesitemos gestionar valores complejos).

Asi pues, siempre hay formas de mejorar y afinar la solución para casos no cubiertos plenamente ¿qué otras opciones se les ocurren para estos dilemas?

 

Y ahora verificando la performance (I)

Varias cosas han pasado desde que empezamos a probar en nuevo modelo de Builds en VSTS, primero creamos una build sencilla que desplegaba a una Azure Web App, luego probamos como usar los Resource Groups para desplegar entornos, luego retiramos el paso de despliegue de la Build para trasladarlo a Release Management luego de su integración con VSTS, y hace poco agregamos Sonar como parte del proceso de análisis de nuestro código dentro de la compilación.

Y como el ciclo de evolución del proceso DevOps nunca para, en esta ocasión veremos como hacer algo a lo que le he tenido bastante respeto desde la época de las builds con el modelo XAML, en este caso la evaluación de la performance y estabilidad de nuestras aplicaciones web desplegadas.

En corto, la posibilidad de probar nuestras aplicaciones Web precede aun a .Net, recuerdo cuando probé Web Application Stress Tool (Homer) para hacer unas pruebas sencillas sobre ASP Clásico, de ahí le perdí el rastro pero la cosa se puso interesante desde Visual Studio 2013 se permite que los tests de carga se basen en las capacidades de la nube, lo cual significa que durante nuestras pruebas se provisionaran las maquinas virtuales que hagan falta para cubrir la cantidad usuarios y peticiones deseadas, esto ya lo había probado desde Visual Studio (revisar aquí y aquí), con buen resultado, pero… ¿como hacer que estas pruebas se ejecuten cuando se produzca cierto tipo de despliegue?

Antes de proseguir hay algunas consideraciones a tener en cuenta:

Los recursos que Azure provisiona para efectuar estas pruebas tienen un costo (si se va por encima de los minutos de carga incluidos con nuestra suscripción de VSTS) por lo que hay que tener cuidado de no lanzar estas pruebas por cada commit que los desarrolladores efectúen, así que la sugerencia general seria tener un sitio de DEV donde se despliegue continuamente pero sin efectuar las pruebas de cargar, luego definiríamos un sitio QA (por ejemplo) al cual se desplegara ya sea de manera manual o de manera programada el contenido existente en DEV (con Release Management lo que se despliega son paquetes que no necesariamente son recién compilados) y al efectuar ese despliegue se lanzaran las pruebas de carga, las cuales si son exitosas indicar que en el proceso de despliegue esta listo para ser sometido a aprobación (si lo hemos definido así) para decidir su pase a otro entorno.

Con estas consideraciones en mente procederemos con nuestra primera prueba para lo cual no sera necesario usar Visual Studio simplemente agregar un paso adicional a nuestro proceso de despliegue, esto es porque a veces lo que nos interesa es simplemente ver que tan bien resiste una URL en concreto a cierta petición.

Para esto vamos a la pestaña de Release de nuestra instalación de VSTS, elegimos nuestro plan actual, seleccionamos el «entorno lógico» sobre el cual agregaremos nuestra prueba de carga y agregamos el Step de Cloud-based Web Performance Test, así:

Clipboard01

Clipboard02

Ok, ahora toca parametrizar el paso para lo cual dejaremos los parámetros mas o menos así, en breve explicare el significado de cada parámetro:

Clipboard06

Antes de proseguir prestemos atención al parámetro Registered connection, lo que ocurre es que cada prueba de carga se hace con cargo a los recursos y facturación de una cuenta de VSTS y podría darse el caso de que la organización tenga mas de una instancia de VSTS, así que corresponde indicar explícitamente dicha cuenta, así que hagamos clic sobre el enlace que dice Manage, que nos abrirá una nueva pestaña en el navegador para agregar un Endpoint (como ya hicimos anteriormente para enlazar Sonar y la cuenta de Azure), y en este caso elegiremos Generic, así:

Clipboard04Y llenamos los parametros de configuración de nuestra instancia de VSTS, pero ojo, al hacerlo deberemos utilizar los datos de nuestra conexión alterna a VSTS, algo de lo que hablamos hace tiempo cuando empezamos a trastear con Git.

Clipboard05

Listo, ya hemos enlazado nuestra prueba de carga a nuestra cuenta de VSTS,  personalmente yo agregaria un checkbox que permita usar la instancia actual y no hacer nada mas, pero siempre es bueno tener una conexión alterna a VSTS especialmente de cara a la integración con herramientas de terceros en Git.

Ok, antes de grabar repasemos los parámetros que estamos configurando:

  • Registered connection: como lo vimos, la instancia de VSTS sobre la cual se hara la facturación de esta prueba de carga.
  • Website Url: La dirección que vamos a probar, en este caso estoy probando la raiz del site (o mejor dicho del slot) en que acabo de hacer el despliegue, cabe indicar que tranquilamente podria haber colocado cualquier URL interna de nuestro site, o peor aun, una URL totalmente externa no manejada por nosotros, pero eso no queremos ¿verdad?
  • Test Name: El nombre con el que identificaremos a esta prueba.
  • User Load: La cantidad de usuarios supuestos que se estarán conectando a nuestra URL.
  • Run Duration (sec): El tiempo de duración de la prueba.
  • Load Location: La zona geográfica de Azure desde donde se hará la prueba, es muy interesante y conveniente hacer la prueba desde una zona que no sea la que aloja a nuestro site, en mi caso la URL esta alojada en East-2, así que la prueba la estoy lanzando desde West.

Marcamos Enabled y grabamos, ya estamos listos para empezar, asi que lo mas sencillo sera hacer un cambio en nuestro codigo fuente, lanzar una nueva Build manualmente, o si queremos divertirnos relanzar un paquete antiguo al ciclo de Release, en todo caso esperamos un poco y veamos cuando nuestra Release se empieza a ejecutar y llega al paso que hemos agregado:

Clipboard08

Para después terminar:

Clipboard09Normalmente pasaríamos a aprobar o rechazar esta Release, pero ahora me interesa conocer los resultados de nuestra prueba, así que vamos a la pestaña Tests, y elegimos la opción LoadTest, para luego seleccionar la prueba mas reciente (en mi caso tengo algunas pruebas anteriores, pero si es la primera vez deberías tener una sola prueba en tu lista).

Clipboard10

Y así entramos a un detalle de los resultados de la prueba:

Clipboard11

Notemos algo interesante, aparentemente nuestra prueba salio ok (o sea, no hubo errores 500 o timeouts) pero el panel nos indica 2 errores, así que veamos el detalle:

Clipboard12

En mi caso el mensaje de error dice «The value 85.10138 exceeds the warning threshold value of 75«, lo cual nos viene a indicar no un error en el sitio que estamos probando sino un exceso en la capacidad de la instancia provisionada para hacer la prueba, esto apunta a que forzamos la maquina dandole 250 usuarios concurrentes, lo cual se relaciona a las pocas opciones de configuración que ofrece este tipo de prueba.

Listo, sencillo y ya podemos empezar a sacar conclusiones, pero como verán esta prueba es muy sencilla y en adición al ya mencionado problema del threshold no permite saber si por ejemplo el comportamiento es diferente desde un browser u otro, desde un tipo de red, etc, para lograr este tipo de análisis lo que se nos ofrece es la posibilidad de crear un test muy detallado desde dentro de Visual Studio y que cuando se efectúe el despliegue Visual Studio Team Services pueda «leer» todos estos parámetros archivados y ejecutar tras bastidores las pruebas programadas, esto sera tema de nuestro próximo post, de momento sugiero familiarizarse con este tipo de prueba, pues los conceptos siguen siendo validos cuando los escalemos, aparte de que estas pruebas tienen su lugar si  hacemos peticiones Get que luego repercuten a nuestra BD, o queremos probar la mejora si usamos un servicio de cache, etc.

Espero sus comentarios 😉

Actualizando la Gestión de la Configuración de ASPNET CORE con Azure

Hace medio año conversábamos acerca de la potencialidad que Microsoft nos empezaba a ofrecer para desarrollar aplicaciones para plataformas Linux y Mac, en el caso Web la iniciativa se llamo ASP NET 5, y en ese sentido se presento una manera para acceder de manera transparente a los valores de configuración (antiguamente manejados por los Web.config) para no tener que preocuparnos si se guardaban dichos valores en un archivo JSON o si por el contrario estábamos guardando dichos valores mediante la consola que Azure nos da para gestionar las Web Apps.

Pues bien, en este lapso varias cosas han transcurrido, y una de ellas es que ASP.NET 5 ahora se llama ASP.NET Core, decisión de Microsoft que ayuda a tener claridad para entender que «este» .Net que corre de manera multiplataforma no es la «siguiente versión» luego de .NET 4.X, así que correspondía regresar al desarrollo puro y duro para verificar si nuestra clase Helper seguía funcionando,  como es lógico habiendo pasado de una versión beta a una release candidate, las API se han actualizado por lo cual algunos de los metodos que se utilizaban ya no funcionan o funcionan de manera diferente, asi que correspondió hacer el ejercicio de revisar el código y dejarlo operativo.

De igual manera aproveche la ocasión para incorporar algo que se me quedo pendiente: soporte para cadenas de conexión, de esta manera seguiremos teniendo (como en ASP.NET 4x) la opción de trabajar en desarrollo con una BD local, y en entornos de despliegue (QA, PROD, etc) con una conexión gestionada por el entorno de Azure, evitando de esta manera trabajar con las ya conocidas Transformaciones, de esta manera si antes teníamos un fragmento de codigo asi:

 services.AddEntityFramework()
                .AddSqlServer()
                .AddDbContext<ApplicationDbContext>(options =>
                    options.UseSqlServer(Configuration["Data:DefaultConnection:ConnectionString"]));

Con el uso de nuestro HelperConfig quedaria asi:

            services.AddEntityFramework()
                .AddSqlServer()
                .AddDbContext<ApplicationDbContext>(options =>
                    options.UseSqlServer(HelperConfig.GetConnectionString(Configuration, "DefaultConnection")));

Y de esta manera seria posible acceder de manera transparente al valor de la cadena de conexión que podria estar en nuestro JSON, asi:

  "Data": {
    "DefaultConnection": {
      "ConnectionString": "Server=(localdb)\\mssqllocaldb;Database=aspnet5-WebTestConfig2-b1ec5227-eb73-448b-86ee-63e3746185e7;Trusted_Connection=True;MultipleActiveResultSets=true"
    }
  },

O, como mencionamos antes, en la consola de Azure:

ConnectionsStrings

Todo esto lo he subido a GitHub junto a un proyecto Web sencillo (vamos, la aplicación por defecto de Visual Studio 2015) para que uds lo descarguen y revisen su funcionamiento, particular atención merecen los siguientes archivos:

https://github.com/fisica3/HelperConfig/blob/master/src/WebTestConfig2/Helper.cs (la clase HelperConfig en si y todo lo necesario para que funcione)

https://github.com/fisica3/HelperConfig/blob/master/src/WebTestConfig2/appsettings.json (Los AppSettings y Connection Strings involucrados)

https://github.com/fisica3/HelperConfig/blob/master/src/WebTestConfig2/Startup.cs (Clase de arranque que prepara la Inyección de Dependencias e invoca a HelperConfig.GetConnectionString)

https://github.com/fisica3/HelperConfig/blob/master/src/WebTestConfig2/Controllers/HomeController.cs (Controlador que hace uso de HelperConfig.GetAppSettings)

En los próximos días explicare un poco mas de este pequeño proyecto, espero que les sea de utilidad y no se olviden de enviarme sus comentarios.