Cómo saber cuándo una nueva instancia de Azure Web Apps está disponible

Estos días he estado investigando algún mecanismo para saber cuándo una nueva instancia ha sido asociada al balanceador en Azure Web Apps, lista para servir tu contenido. Para ello he utilizado Application Initialization Module, un módulo de IIS que te permite lanzar una serie de peticiones, que tiene cómo objetivo precalentar tu sitio web y obtener así una respuesta más rápida, sin necesidad de tener que esperar a una primera petición de un usuario de aquellas partes que requieren un tiempo mayor la primera vez que se acceden. En mi caso, me sirve como indicativo de que ese nuevo nodo ya está listo y asociado al balanceador. Para este ejemplo he utilizado un par de aproximaciones que te darán una idea de cómo funciona.

Dentro de la sección system.webServer he añadido lo siguiente:

    <applicationInitialization doAppInitAfterRestart="true">
      <add initializationPage="/Notify/LogicApp" hostName="arraffinity.azurewebsites.net" />
      <add initializationPage="/Notify/RequestBin" hostName="arraffinity.azurewebsites.net" />
    </applicationInitialization>

Como ves se realizan dos llamadas: una a /Notify/LogicApp y otra a /Notify/RequestBin que contienen la siguiente lógica:

using System.IO;
using System.Net;
using System.Text;
using System.Web.Mvc;
namespace ARRTest.Controllers
{
    public class NotifyController : Controller
    {
        // GET: Notify
        public void RequestBin()
        {
            var request = (HttpWebRequest)WebRequest.Create("http://requestb.in/1fl81uk1");
            DoRequest(request);
        }
        // GET: Notify
        public void LogicApp()
        {
            var request = (HttpWebRequest)WebRequest.Create("https://prod-07.northeurope.logic.azure.com:443/workflows/f335b522855146cda8a78505b3fac57e/triggers/manual/run?api-version=2016-06-01&sp=%2Ftriggers%2Fmanual%2Frun&sv=1.0&sig=EeQwQ4_ZS-L6UubWCwbA95XAf54e5PUYH3smX27Qaqg");
            DoRequest(request);
        }
        private void DoRequest(HttpWebRequest request)
        {
            var data = Encoding.ASCII.GetBytes(string.Format("webapp={0}&instanceName={1}", Request.Url.Host, Server.MachineName));
            request.Method = "POST";
            request.ContentType = "application/x-www-form-urlencoded";
            request.ContentLength = data.Length;
            using (var stream = request.GetRequestStream())
            {
                stream.Write(data, 0, data.Length);
            }
            var response = (HttpWebResponse)request.GetResponse();
            var responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();
        }
    }
}

Lo único que hacen ambas llamadas es una petición POST a dos URLs distintas. La primera de ellas al servicio RequestBin que me permite recoger una petición y visualizar el contenido de la misma:

RequestBin - Application Initialization Module
RequestBin – Application Initialization Module

De esta forma, antes de hacer algo más elaborado me aseguro de que mi configuración y llamada funcionan como espero.

Para el segundo ejemplo he utilizado el servicio Azure Logic Apps, que me permite encadenar una serie de acciones donde he incluido una notificación a través de email, para saber cuándo la nueva instancia está lista.

Logic App Run - Application Initialization Module
Logic App Run – Application Initialization Module

Para este ejemplo manda un correo muy simple con el nombre de la instancia y el dominio del sitio web.

Email - Application Initialization Module
Email – Application Initialization Module

Sin embargo, podría ser integrado con cualquier sistema que acepte peticiones HTTP y monitorizar asi cuándo el escalado ha tomado efecto o cuándo los nodos han sido reiniciados.

¡Saludos!