¡Actualiza tus Azure Functions! ¡Ya!

Este articulo puede ser considerado una continuación de los anteriores, pero en este caso vamos a tratar de ir al grano respecto a una situación que algunos todavía podemos estar pasando y sobre la cual no se ha tomado acción, asi que vamos a ello.

Recordemos, desde diciembre del 2022 los runtime V2 y V3 de Azure Functions ya no están soportados, pero ¿eso significa que ya dejaron de funcionar las Functions que tenemos en producción? Pues no, ahí siguen operando a menos que Microsoft anuncie su apagado definitivo (como ya paso con otros servicios que comentamos aquí y aquí) peroooo…. sin garantías de que sigan funcionando como se espere, una razón (simplificando mucho) es que Microsoft puede “meter mano” en la infraestructura compartida pero teniendo en mira solo los parámetros de operación de la versión V4 (la soportada actualmente) y las versiones de los lenguajes soportados por V4. Por ejemplo si tu Function fue hecho en una versión de Node antigua (pero entonces soportada por la V3) y aun no has migrado a la V4, no hay garantías ni soporte del funcionamiento esperado de tu aplicación, si pues no hay “Pero si ayer funcionaba”, es que simplemente no se ha sido diligente en seguir los ciclos de vida de la tecnología que estamos usando.

Reiterando lo que ya conversamos anteriormente, esto deriva del principio de Responsabilidad Compartida, al elegir trabajar con un servicio IaaS, PaaS o un SaaS, estamos aceptando el nivel de intervención que el proveedor ha definido para ese tipo de servicio, así que un PaaS (como Azure Functions) va a implicar que el proveedor tome un rol muy proactivo respecto al ciclo de vida y mantenimiento del servicio que esta ofreciendo, así que si uno quiere que Azure lo “deje en paz” por mucho tiempo respecto al mantenimiento, pues… no queda sino optar por un servicio IaaS como las Máquinas Virtuales, con todo lo que eso implica.

Bueno, discusiones de obsolescencia aparte, queda claro que ya estamos tarde, si tenemos Functions de versión 3 o 4 nuestras aplicaciones ya no están bajo soporte, por lo que toca efectuar la migración respectiva (lo cual puede implicar cambios de código para alinearnos a versiones modernas de los lenguajes/frameworks), así que el primer paso sería averiguar que Functions requieren actualización.

Para este problema la solución mas “sencilla” seria revisar cada Functions y ver si hay alguna alerta, como la que vimos anteriormente:

El problema es que esto solo tiene sentido si en nuestras subscripciones tenemos pocas Functions, por lo que el paseito seria sencillo, pero… si tenemos varias subscripciones y Functions desplegados ¿Como hacemos? Si, lo suyo seria algún query o script para lograrlo, así que usando Azure Copilot conseguí este query para ejecutar en Azure Graph:

resources 
| where type == 'microsoft.web/sites'
| where properties.kind == 'functionapp'
| extend runtimeVersion = tostring(properties.siteConfig.netFrameworkVersion)
| where isnotnull(runtimeVersion) and runtimeVersion contains '4.'
| project id

La mala noticia es que este query no funciona, el valor “runtimeVersion” siempre retorna una cadena vacia, por lo que hacer comparaciones alrededor de este valor no tiene mucho sentido.

Asi que conversando con algunos MVPs me entere que el camino era el uso de PowerShell, y luego de unas pruebas vi que la solución que me brindo Brett Miller era la adecuada:

PS /home/brett> $query = "resources
| where type == 'microsoft.web/sites'
| where properties.kind == 'functionapp'
| extend runtimeVersion = tostring(properties.siteConfig.netFrameworkVersion) "
$functions = Search-azGraph -Query $query

PS /home/brett> $functions | foreach-object { 
$appSettings = Get-AzFunctionAppSetting -Name $_.name -ResourceGroupName $_.resourceGroup            
    [pscustomobject]@{
       functionname = $_.Name  
       runtimeVersion = $appSettings.FUNCTIONS_EXTENSION_VERSION
    }
}

Claro que para que esto funcione debemos ejecutarlo en el lugar correcto: el Cloud Shell que nos da el Portal de Azure o el propio Cloud Shell de Windows, y para que el query se efectue correctamente hay que instalar el paquete respectivo, por lo que solo hay que ejecutar previamente esta linea dentro del Cloud Shell:

Install-Module -Name Az.ResourceGraph

Y como pueden ver, ahora si conseguí la información que estaba buscando:

Upps… pensé que ya había migrado todos los Functions que uso para mis demos, a cualquiera le puede pasar, pero lo importante es que ya tenemos la información necesaria para ubicar nuestros Functions obsoletos y empezar la migración.

No puedo dejar de mencionar que Stefano Demiliani, otro fellow MVP, también encontró una solución para este problema, la cual esta detallada aquí.

Así que… ¡no hay excusas! ubica tus Functions a actualizar y ¡migra ya!

Todo lo que querías saber sobre las “versiones” en Azure y no te atrevías a preguntar (2)

Bueno, esto tardo un poco mas de la cuenta, pero aquí continuamos con lo ya empezado, tratar de entender los ciclos de vida y “versiones” de los diversos servicios de Azure, así que vamos a ello y hoy veremos algunos datos que nos servirán para planear bien la provisión de nuestros servicios, y si en la ocasión anterior conocimos los casos vinculados a las deprecación de servicios y a las generaciones de computo (máquinas virtuales), por lo que hoy toca continuar con los…

Servicios PaaS, en este caso empezaremos enfocándonos en nuestros queridos Azure Functions, como todos sabemos si uno opera en el modo Consumo no tiene margen de maniobra para elegir la infraestructura base sobre la que va a correr nuestro código, pero eso cambia si se opta por los modos Premium o App Service, en ese sentido, al provisionar un nuevo Function desde el Portal (1), podemos ver diversas opciones para desplegar nuestro Function: Finish Reading: Todo lo que querías saber sobre las “versiones” en Azure y no te atrevías a preguntar (2)

Actualizando sobre las Managed Identities

Como mencionamos en nuestros posts anteriores, esto de las Managed Identities va en constante evolución por lo que este articulo se cala de maduro para actualizar unas cuantas cosas respecto a lo comentado anteriormente, así que vamos a ello:

Nueva forma de asignar permisos en el portal de Azure

En el articulo interior incluía varios pantallazos de como asignar un rol sobre un recurso (KeyVault/Azure Storage) a otro recurso (Function/Web App), pues bien, la forma ha cambiado ligeramente, pero esta vez para resumirlo he creado un pequeño video, aquí va:

Mejoras en el soporte para Service Bus

Como comentábamos anteriormente si uno quería usar Managed Identities en un Service Bus como trigger para un Azure Functions, tenia que usar la “sintaxis keyvault” desde los Application Settings, pero con la limitante de que esto solo funcionaba para Azure Functions Premium, pues bien ahora ya es posible usar MI como mecanismo de conexión/seguridad entre Azure Functions y Services, quedando la configuración así:

Dos detalles a considerar: Finish Reading: Actualizando sobre las Managed Identities

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

Microservicios: claro y simple

Desde hace tiempo hemos escuchado mucho sobre la conveniencia de usar Microservicios para el desarrollo de aplicaciones frente al esquema “monolitico” tradicional, de hecho la primera exposición seria que tuve sobre el tema fue durante el Agiles 2015, donde Maria Gomez dio un excelente charla planteando el esquema, de la cual comparto y recuerdo la facilitación gráfica respectiva:

_DSC3014

Desde entonces muchas dudas afloran ¿entonces ya no tendremos transacciones ACID? ¿como validamos la consistencia? ¿como deberemos modelar los datos? lo cual sumado a las ventajas ofrecidas por Docker hace necesario tener las bases teóricas claras para acometer este tipo de desarrollos.

En ese sentido, junto al lanzamiento de Visual Studio 2017, Microsoft presento una aplicación de referencia, basada en Contenedores y Microservicios, llamada eShopContainers que esta disponible en GitHub para ir siguiendolo (pues es un trabajo en construcción aún), miren nomas lo ambiciosa que es:
eShopOnContainers_Architecture_Diagram

Si, ambiciosa en cuanto a la diversidad de tecnologías a usar: Docker, Linux, .Net Core, Xamarin, etc pero lo mas importante a mi modo de ver es el libro que se esta construyendo, y que se puede descargar aquí.

He empezado a leerlo y me ha gustado mucho, se cubre con claridad que son los Microservicios, como se relacionan con Docker, los nuevos paradigmas a seguir, un concepto interesante llamado Data Sovereignty, como estructurar las entidades, lo cual hace caer en cuenta de la necesidad de ir entendiendo los conceptos de DDD, y lo mejor de todo, con un lenguaje claro y bien estructurado, lo dicho… ya estas tardando en descargar el libro!

Muchas gracias a Cesar de la Torre de Microsoft por este trabajo emprendido que nos ayudara mucho a los desarrolladores.

Novedades en VSTS!! …. que impactan a nuestros proyectos Docker

Pues si, retomando los contenidos técnicos y en este caso haciendo seguimiento a las novedades del ultimo Connect, nos topamos con estas (entre otras) que afectan a nuestra herramienta favorita (claro que estoy hablando de Visual Studio Team Services, VSTS):

  • Versionado de tareas (Build Task), esto esta interesante, ahora podremos “congelar” la versión de las tareas a fin de no ser afectados por los cambios que Microsoft haga sobre nuestras dependencias en VSTS, estando en nuestras manos el luego actualizar a la versión mas actual.
  • Crear Builds y Release desde Azure (Portal), algo para simplificar las tareas DevOps , si has visto los articulos publicados veras que tradicionalmente hemos creado nuestras Web Apps desde el portal Azure para luego ir a VSTS a fin de enlazarlo y definir nuestro flujo de Construcción y Despliegue, ahora lo que se nos ofrece es empezar a construir nuestro flujo desde el entorno del Portal de Azure, siendo que luego también estará definido en VSTS, sera motivo de darle un vistazo.
  • Agentes en Linux (Preview), este si es el bombazo, pues tradicionalmente los agentes de compilación que VSTS instancia cada vez que lanzamos un proceso de Integración Continua son Maquinas Virtuales Windows, ahora tenemos la posibilidad de que estos agentes sean generados de manera “elastica” ya sea en Windows o en Linux según el requerimiento de nuestro proceso de Build o de Release, lo cual cambiara radicalmente nuestra forma de trabajo con Docker y otras tecnologías como explicare a continuación.

Como sabrán hace unos meses empece a hacer mis experimentos de despliegue de una aplicación .Net (Core) dentro de Docker, lo cual pude realizar satisfactoriamente luego de mucho esfuerzo, que me llevo a establecer los siguientes pasos: Finish Reading: Novedades en VSTS!! …. que impactan a nuestros proyectos Docker

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.

 

Completando el ciclo de ALM: Release Management (II)

Prosiguiendo con la entrega anterior, pasamos a los pasos 4 y 5 de este proceso que consiste en configurar cada uno de los entornos de despliegue en los que se va a desplegar la aplicación, la idea que implementaremos en esta ocasión sera la siguiente:

  • Cada vez que se efectué un cambio en el código fuente se disparara una Build (Integración Continua, esto ya lo tenemos bien sabido)
  • Si la Build es exitosa se disparara una Release
  • El primer paso de la Release sera desplegar automáticamente al entorno QA
  • Efectuado el despliegue a QA, un aprobador humano dará su conformidad, o no, al contenido desplegado
  • Si el despliegue en QA ha sido aprobado, recién entonces se efectuara el despliegue al entorno PRO

Obvio que este esquema puede extenderse para incorporar mas entornos, para añadir pruebas de carga en la nube, distintas categorías entre aprobadores, etc, pero para demostrar el concepto esta prueba sera suficiente.

De momento vamos a identificar correctamente nuestros entornos, así que nos vamos al entorno llamado por defecto “Default Environment” y le cambiamos el nombre…

Clipboard01

A QA:

Clipboard02

Finish Reading: Completando el ciclo de ALM: Release Management (II)

Completando el ciclo de ALM: Release Management (I)

Repasemos un poco lo que hemos aprendido hasta ahora: sabemos como configurar nuestro Visual Studio On… digo Visual Studio Team Services para crear un Team Project, desarrollar una aplicación en ASP.NET para finalmente compilar y desplegar dicha aplicación cada vez que efectuemos un cambio en el código fuente (Integración Continua).

Todo perfecto, pero recordemos que si queremos definir un conjunto de entornos (QA, DEV, STA, PRO…) entre los que sucesivamente vayamos escalando nuestra aplicación, hacíamos uso de la funcionalidad de Azure llamada “slots”, la cual de una manera sencilla nos permitía intercambiar contenidos entre los diversos entornos, esta técnica es muy practica y nos permite cierto grado de protección a fin de poder revisar nuestros cambios antes de que hagamos el despliegue en el entorno definitivo.

Devops-release

Ahora tenemos una opción adicional, y es que desde la gestión que hace VSTS/TFS manejemos de manera separada la forma en que nuestro “paquete” va siendo desplegado y escalado en los entornos de aprobación hasta su destino “final”: producción, y al hacerlo logramos introducir un factor que sera de gran utilidad de cara al aseguramiento de la calidad de lo entregado: la aprobación de versiones, vale decir que a una persona (o grupo de personas) se le notifica que hay una nueva versión de la aplicación en determinado entorno y que le corresponde dar su conformidad a dicha versión, lo cual derivara en que la versión en cuestión sea propagada al siguiente entorno, y así sucesivamente. Adicionalmente este cambio nos va a permitir manejar ya no solo el historial de nuestras Builds sino tambien el historial de nuestros despliegues, pudiendo ver si todos los despliegues propuestos han pasado los tests de carga y/o fueron aprobados satisfactoriamente por QA o el cliente.

Finish Reading: Completando el ciclo de ALM: Release Management (I)

Buenos cambios para el entorno DevOps en Microsoft

Guau.. vaya con las novedades de Connect 2015, bastantes cosas en desarrollo multiplataforma, cloud, Windows… pero centrémonos en lo que corresponde a nuestro interés como DevOps y entusiastas del ALM, asi que vamos con calma….

Adiós Visual Studio Online…. hola Visual Studio Team Services, si, un nombre puede ayudar mucho, y desde que Microsoft le dio el nombre oficial a lo que originalmente conociamos con Team Foundation Service me ha sido complicado explicar que VSO no es un IDE como Visual Studio pero en el browser, sino por el contrario una herramienta ALM (Scrum, repositorio, build…), ahora este cambio de nombre puede ayudar un poco mas a entender las cosas, así que repitamoslo una vez mas: Visual Studio Team Services (VSTS).

Preview de Release Management para VSTS, una gran noticia, quienes han seguido mis artículos sobre despliegue, se habrán percatado que el proceso de paso a entornos lo había configurado como un paso final del proceso de Build, pues bien… una etapa tan importante requiere una gestión por separado que facilite no solo colocar la aplicación en el primer entorno, sino también mover las versiones de la aplicación entre diversos entornos, y ese es el objetivo de RM que ha evolucionado de ser un producto separado a ser una parte integral del entorno de VSTS, permitiéndonos entre otras cosas establecer aprobadores manuales que decidan si una versión de nuestra aplicación ya esta lista para pasar al siguiente nivel, como detalle adicional es importante indicar que no es necesario que tu ciclo de Build lo hayas gestionado con VSTS sino que tu paquete también puede provenir de Jenkins, y claro… como era de esperar nuestro entorno destino no es solo Windows. En las próximas semanas iremos desgranando un poco estas facilidades.



 

Preview de Code Search en VSTS, una ayuda que nos permitirá ubicar el código deseado de manera potente a través de nuestros repositorios via web.

Soporte para Subversion en TFS y pronto en VSTS, hay que reconocerlo a pesar del crecimiento de Git, hay muchos desarrolladores en el mundo Java que se sienten muy cómodos con Subversión, así que en breve se tendrá como opción el que nuestros Team Projects se creen con Subversión como tipo de repositorio, la cosa es tener opciones ¿no?

A seguir poniéndonos al día!