Azure · Sitecore

Escalando Sitecore Azure Web App

Antes de escalar Sitecore Azure Web App, debes leer la experiencia que tuve y que voy a compartir en este post.

Azure Web App

En Azure, puedes cambiar fácilmente recursos existentes casi en tiempo real para satisfacer las necesidades del negocio, y esto también se aplica a Web Apps donde puedes Scale Up y/o Scale Out tu aplicación.

Sitecore

Sitecore ofrece diferentes modelos de arquitectura para adaptarse a las necesidades del cliente, y sus roles varían dependiendo de la topología elegida. Sin embargo, tienes la posibilidad de escalar ya sea vertical u horizontalmente.

El entorno

Todo está alojado en Azure, utilizando Web Apps, y provisionado siguiendo la topología Sitecore XP Scaled. Aquí tienes una idea de cómo se veía el entorno

sitecore architecture azure paas blog vinicius deschamps

Antes de avanzar es importante conocer la diferencia entre Azure Web App y App Service Plans

Azure Web Apps vs App Service Plans

Durante la creación de Azure Web App, se te solicita que proporciones los Instance Details (1) que corresponde a la Web App, y el App Service Plan (2) que debe ser uno de los siguientes: crear uno nuevo o elegir uno existente desde la lista desplegable.

azure azure app service vs azure app service plan create blog vinicius deschamps

La relación entre Web App y App Service Plan se puede ilustrar con la imagen a continuación

azure app service vs app service plan blog vinicius deschamps

N Las Web Apps pueden usar el mismo App Service Plan, siempre que los recursos que el App Service Plan pueda manejar.

Además de eso, una idea que ayuda a entender es pensar como

  • App Service Plan es el servidor físico o virtual que tiene los recursos (CPU, memoria, etc)
  • Web App es el servidor web donde se sitúan la configuración y los ajustes

Dicho esto, queríamos escalar Out tanto CM como CD, y todo salió bien con el CD, así que intentemos hacer lo mismo en CM.

Idea de Scale Out CM

Cuando escalas tu aplicación, se añade un Load Balancer delante de tu Azure Web App, y Sitecore CM espera exactamente eso para una escala horizontal

Puedes configurar múltiples instancias detrás de un balanceador de carga. Todas las instancias deben conectarse a una base de datos maestra ubicada de forma central

https://doc.sitecore.com/developers/100/platform-administration-and-architecture/en/scaling-and-configuring-content-management.html

Por lo tanto, decidimos simplemente Scale Out la Web App de CM

Todo salió mal #1

Una vez que todas las instancias estaban en funcionamiento, se realizaron un par de pruebas y todo funcionaba muy bien.

Sin embargo, cuando varios usuarios comenzaron a trabajar, las cosas empezaron a salirse de control con las instancias reiniciándose aleatoriamente sin motivo y con el siguiente mensaje

WARN Shutdown message: CONFIG change

Siempre busca los pequeños detalles

Al escalar CM, el entorno pasó de 1 a N servidores, y Sitecore tiene diferentes requisitos para hacer que esto funcione

Parámetro InstanceName

Debes asegurarte de que cada instancia de CM tenga un nombre único, y eso está bien porque el valor por defecto establecido en el archivo Sitecore.config es (nombre de la máquina y nombre del sitio IIS), y cuando escales obtendrás una App Service clonada que se ejecuta con un nombre único.

<!--  INSTANCE NAME
            Unique name for Sitecore instance.
            Default value: (machine name and IIS site name)
      -->
    <setting name="InstanceName" value="" />

Publicación

Solo una instancia de CM puede realizar publicaciones, y debes asegurarte de que cada instancia de CM apunte a la instancia de CM de publicación, y de nuevo eso está bien porque el entorno tiene un Servicio de Publicación dedicado.

ValidationKey y DecryptionKey

Asegúrate de que los valores sean los mismos en todas las instancias de Sitecore dentro del entorno y de que el modificador IsolateApps no esté presente en ninguno de los valores, y en la configuración del entorno estos parámetros estaban establecidas de forma fija y estática.

Indexación

El sub-rol de indexación está habilitado en el rol Content Mangement por defecto. Si tienes más de una instancia del Content Management, debes deshabilitar la indexación en todas menos en una instancia.

Dado que un Scale Out simplemente clona el sistema de archivos, y no permite que tengamos control en el sistema de archivos de cada nuevo servidor para modificar la configuración de Indexing, Sitecore CM se confundía con varios servidores realizando el rol de indexación.

Ahora, que se identificó el problema, la idea era provisionar un nuevo Content Management usando su propio App Service (y App Service Plan) donde el sistema de archivos podría modificarse según sea necesario.

Así que, llamemos a este nuevo Content Management CM02 y al existente CM01.

Habilitar el sub-rol de Indexing CM02

La idea es tener CM02 con el sub-rol de Indexing, y para lograrlo se debe hacer una modificación en el Web.config

<add key="role:define" value="ContentManagement, Indexing, Indexer"/>

A partir de Sitecore 9.2, cuando asignas el indexing sub-role a un servidor, ese rol gestiona la indexación de contenido automáticamente y los otros roles de servidor que no han sido asignados a este sub-rol no indexan contenido

https://dev.sitecore.net/Downloads/Sitecore%20Experience%20Platform/92/Sitecore%20Experience%20Platform%2092%20Initial%20Release/Release%20Notes

Deshabilitar el sub-rol de Indexing CM01

IMPORTANTE: Si estás usando Sitecore 9.2 y posterior, no necesitas deshabilitar la indexación en otros CM

Para cada índice que hayas configurado, debes cambiar su indexUpdateStrategies a manual como se muestra en el ejemplo a continuación

<index id="sitecore_index" type="Sitecore.ContentSearch.SolrProvider.SolrSearchIndex, 
 Sitecore.ContentSearch.SolrProvider">
 <param desc="name">$(id)</param>
 <param desc="core">$(id)</param>
 <param desc="propertyStore"
 ref="contentSearch/indexConfigurations/databasePropertyStore"
 param1="$(id)" />
 <strategies hint="list:AddStrategy">
 <strategy ref="contentSearch/indexConfigurations/indexUpdateStrategies/manual" />
 </strategies>

Una vez aplicados estos cambios, así es como se veía el entorno

sitecore architecture azure paas scaled out blog vinicius deschamps

Todo salió mal #2

Ahora ya tenemos todo lo necesario para un entorno con múltiples CM

  • Balanceador de carga delante de los CMs
  • Parámetro InstanceName con nombres únicos
  • Un servidor de Publicación
  • Mismo ValidationKey y DecryptionKey para todos los CMs
  • Un CM para gestionar Indexing

Y las cosas parecían muy prometedoras, bueno… bueno… hasta que las instancias del CM01 escalado comenzaron a fallar y, nuevamente, de forma aleatoria y con exactamente el mismo mensaje.

WARN Shutdown message: CONFIG change

¿Qué más podría estar mal? Después de investigar, encontré algo que respondió a nuestra pregunta

De acuerdo con la documentación de Sitecore Managed Cloud

Scale out is not supported for CM

https://doc.sitecore.com/developers/managed-cloud/en/scaling-options-for-managed-cloud.html

La solución

Dicho eso, la única posibilidad sería tener CMs adicionales, cada una en su propio App Service Plan.

Sin embargo, como ya no estamos escalando la CM App Service, no tenemos un balanceador de carga para repartir la carga entre las múltiples CMs y hay algunas cosas importantes a saber:

  • Azure Load Balancer no funciona con Azure App Services, incluso si configuras VNet para ellos
  • WAF y Application Gateway no son compatibles con servidores de Content Management

Así que, o bien propones una solución de terceros que te ayude a tener un Load Balancer para tus CMs o puedes usar Azure Front Door, pero ten en cuenta lo siguiente:

El uso de esta tecnología dentro de una solución Sitecore está permitido, pero el equipo de Soporte de Sitecore solo puede ayudar con problemas del producto Sitecore que no sean únicos al uso de la tecnología, es decir, un problema del producto Sitecore que se pueda replicar sin la tecnología presente.

En algunos casos, el equipo de Soporte de Sitecore puede pedir la replicación del problema sin el uso de la tecnología, aunque intentarán evitarlo.

https://kb.sitecore.net/articles/682999#Notes

En mi caso, voy a usarla y así es como debe ser

sitecore content management azure front door blog vinicius deschamps

Configurar Azure Front Door

Busca Front Doors y haz clic en Front Doors en el campo de búsqueda de Azure

azure search front doors blog vinicius deschamps

Haz clic en Add para crear un nuevo Front Door

azure front doors add blog vinicius deschamps

En Basics elige el Resource Group apropiado o crea uno nuevo, y Next : Configuration >

azure create a front door basics blog vinicius deschamps 1

En Configuration verás 3 pasos, comencemos haciendo clic en la señal + en Step 1

azure create a front door configuration frontends domains blog vinicius deschamps 1

En Add a frontend host proporciona el Host name (1), asegúrate de elegir Enabled para Session Affinity (2) y disabled para Web Application Firewall (3) – ya que Sitecore no lo requiere – y haz clic en Add

azure create a front door configuration frontends domains add a frontend host blog vinicius deschamps

Pasemos al Step 2 haciendo clic en la señal +

azure create a front door configuration backend pools blog vinicius deschamps

Add a backend pool dándole un Name (1) y + Add a backend (2)

azure create a front door add a backend pool blog vinicius deschamps

Elige un Backend host type (1), en nuestro caso un App Service, luego elige el Backend host name (2) y su Backend host header (3), y haz clic en Add

azure create a front door configuration backend pools add a backend app service blog vinicius deschamps

Asegúrate de repetir el paso anterior haciendo clic en + Add a backend hasta tener todos los CM Web Apps añadidos

azure create a front door add a backend pool repeat add a backend app services blog vinicius deschamps
azure create a front door add a backend pool repeat complete add a backend app services blog vinicius deschamps

Una vez que tengas todas las Web Apps, puedes continuar en las opciones de Add a backend pool y simplemente hacer clic en Add

azure create a front door configuration backend pools add a backend health probe load balancing blog vinicius deschamps

Finalmente, configuremos el Step3 haciendo clic en la señal +

azure create a front door routing rules blog vinicius deschamps

Dale un Name (1), y elige sus Frontends/domains (2) y el Backend pool (3), luego pulsa Add (4)

azure create a front door routing rules add a rule blog vinicius deschamps

Ahora que tienes los 3 pasos configurados, haz clic en Review + Create

azure create a front door review create blog vinicius deschamps

Revisa la información y haz clic en Create

azure create a front door review create create blog vinicius deschamps

Debes esperar hasta que Front Door esté provisionado, y puedes acceder desde tu navegador al nombre de host que configuraste, en mi caso es https://blog-vinicius-deschamps.azurefd.net

azure front door access sitecore cm blog vinicius deschamps

Genial, pero probablemente no querrás compartir un dominio azurefd.net con tus Content Editors para que accedan a tu CM. Veamos cómo configurar un dominio personalizado.

Dominio personalizado Azure Front Door

Ve a Front Door (1), selecciona Front Door designer (2), luego haz clic en el + (3) en Frontends/domains

azure front door front door design frontends domains add new domain blog vinicius deschamps

Debes elegir un Custom host name, y recibirás un mensaje indicando que se debe realizar una configuración CNAME en tu DNS

azure front door add a custom domain blog vinicius deschamps

Estoy usando Azure DNS, así que fui a mi dominio viniciusdeschamps.cloud (1), seleccioné Overview (2) y + Record set (3)

azure dns new record set blog vinicius deschamps

En Add record set, añade un Name (1), selecciona el Type (2) y añade el Alias (3), luego pulsa Ok (4)

azure dns add record set azure front door cname blog vinicius deschamps

Regresa a Front Door y escribe tu Custom host name (1) de nuevo, elige Enabled (2) para Custom Domain HTTPS, y en un entorno de Producción usa tu propio certificado, pero en mi caso voy a usar Front Door managed (3), y no olvides dejar Enabled (4) Session Affinity y pulsa Add (5)

azure front door add a custom domain after adding dns cname blog vinicius deschamps

En Front Door Designer verás la siguiente advertencia

The host ‘your-custom-host.domain’ is not present in any of the routing rules.

The host ‘your-custom-host.domain’ is missing a default route ‘/*’ path for both the HTTP and HTTPS protocolos

azure front door the host is not present in any of the routing rules blog vinicius deschamps

Selecciona las Routing rules existentes

azure front door routing rules update existing rule blog vinicius deschamps

Y en Frontends/domains elige el domain recientemente agregado de la lista

azure front door update routing rule frontends domains blog vinicius deschamps

Luego, presiona Update

azure front door update routing rule hit update button after select new frontends domains blog vinicius deschamps

Una vez hecho, haz clic en Save en el diseñador de Front Door

azure front door there are pending changes click save to apply blog vinicius deschamps
azure front door with custom domain and new rules blog vinicius deschamps

Espera un momento hasta que recibas una confirmación de que la configuración se aplicó; en mi caso tomó un tiempo porque elegí el Front Door managed certificate

azure front door updating the custom https configuration blog vinicius deschamps
azure front door updated the custom https configuration blog vinicius deschamps

Sitecore Identity Server Unauthorized_Client

Una vez que el Azure Front Door se actualizó con el nuevo Custom Domain, intenté acceder a https://prodcm.viniciusdeschamps.cloud/sitecore y cuando se lanzó Identity Server apareció el siguiente mensaje

Sorry, there was an error: unauthorized_client

Y esto ocurre porque en la configuración de Identity Server debes establecer desde qué URL se deben aceptar las solicitudes de autenticación

sitecore identity server sorry there was an error unauthorized client blog vinicius deschamps

Para solucionarlo, debes ir a la App Service de Sitecore Identity Server (1), Advanced Tools (2) y Go (3)

azure app service sitecore identity server advanced tools go blog vinicius deschamps

Selecciona Debug console, y PowerShell

azure app service kudu debug console powershell blog vinicius deschamps

Navega a site\wwwroot\Config\production, y accede al siguiente archivo Sitecore.IdentityServer.Host.xml y modifica la siguiente línea

<AllowedCorsOriginsGroup1>https://sc91vdsch-cm.azurewebsites.net|https://</AllowedCorsOriginsGroup1>
sitecore identityserver host xml add new custom domain blog vinicius deschamps

Al agregar todas las URLs de Content Management como sigue, y hacer clic en Save

<AllowedCorsOriginsGroup1>https://sc91vdsch-cm.azurewebsites.net|https://sc91vdsch-cm02.azurewebsites.net|https://sc91vdsch-cm03.azurewebsites.net|https://prodcm.viniciusdeschamps.cloud</AllowedCorsOriginsGroup1>
sitecore identityserver host xml add new custom domain save blog vinicius deschamps

Una vez guardada la modificación, debes Restart el App Service de Sitecore Identity Server

azure app service sitecore identity server overview restart blog vinicius deschamps
azure app service sitecore identity server are you sure you want to restart blog vinicius deschamps

Una vez que el reinicio se complete, intenta acceder a Sitecore CM usando el dominio personalizado configurado en Azure Front Door, en mi caso https://prodcm.viniciusdeschamps.cloud/sitecore y voilá sin error

sitcore identity server fully accessible type credentials blog vinicius deschamps

Me dio redirección al Sitecore Experience Platform, y como puedes ver al CM02 pero eso no es lo que quiero para mis usuarios finales, así que hay pasos adicionales para abordarlo. Bueno, al menos sabemos que el Front Door está separando el tráfico

sitecore not using azure front door custom domain blog vinicius deschamps

Dominios personalizados para App Services

Navega a los App Services, y elige uno de los CMs (1), selecciona Custom Domains (2) y copia el Custom Domain Verification ID (3)

azure app service custom domains custom domain verification id blog vinicius deschamps

Ve a tu proveedor de DNS, en mi caso Azure DNS, y vamos a añadir un nuevo Record Set

azure dns new record set blog vinicius deschamps

El paso a continuación es verificar la propiedad del dominio, y debes rellenar la información de la siguiente manera

  • Name – asuid.SUBDOMAIN (p. ej. asuid.prodcm)
  • Type – TXT
  • Value – Pega el valor que copiaste de Custom Domain Verification ID
azure dns add record set custom domain verification txt blog vinicius deschamps

Regresa a Custom Domains, y haz clic en Add custom domain (3)

azure app service custom domains add custom domain blog vinicius deschamps

Teclea tu Custom Domain (1), luego haz clic en Validate (2)

azure app service add custom domain validate blog vinicius deschamps

A veces tarda un poco hasta que se sincronice el registro, y podrías ver el siguiente mensaje

Domain ownership

To verify domain ownership create CNAME and TXT record with your DNS provider

Como ya tenemos un CNAME configurado para Azure Front Door, el registro CNAME no es necesario

azure app service add custom domain add custom domain domain ownership blog vinicius deschamps

Espera un rato y trata de Validate el Custom Domain de nuevo, y si todo está OK, deberías ver lo siguiente y haz clic en Add custom domain

azure app service add custom domain add custom domain blog vinicius deschamps

IMPORTANTE: Debes añadir el mismo dominio personalizado a cada CM App Service!

Y por último, cuando accedas a tu Azure Front Door dominio personalizado para acceder a Sitecore, notarás que ahora tienes una URL única para todo el Content Management, que en mi caso es https://prodcm.viniciusdeschamps.cloud

sitecore using azure front door custom domain blog vinicius deschamps

Y eso es todo!

Espero que te haya gustado, y nos vemos en mi próxima publicación.

Foto de Marius Masalar en Unsplash

AzureAzure Web AppsSitecore
Escalando Sitecore Azure Web App — Vinicius Deschamps