Loading...
Area: Optimizely CMS
Applies to versions: 12 and higher
Other versions:
ARCHIVED This content is retired and no longer maintained. See the version selector for other versions of this topic.

Deploying to Azure Web Apps

Recommended reading 
Note: This documentation is for the preview version of the upcoming release of CMS 12/Commerce 14/Search & Navigation 14. Features included here might not be complete, and might be changed before becoming available in the public release. This documentation is provided for evaluation purposes only.

This topic describes how to set up an Optimizely CMS site to run on Azure Web Apps. The example creates an Alloy sample site using the Episerver Visual Studio extension, but you can apply most steps to sites created in other ways.

Note: See also the Installing the Optimizely Alloy sample site in the Azure cloud video for information about cloud installation.

In this topic

Cloud requirements

  • You need a cloud-enabled license from the Optimizely License Center.
  • Microsoft Azure Portal requires an account with login details.
  • Content mirroring and workflows are not supported.
  • When you install a database using Microsoft Azure SQL Database, ensure that SQL Database supports each individual product and add-on that you want to use on the site for the site to work properly.
  • Ensure that each deployed application and module is designed for the cloud.

Setting up a cloud website

The following image illustrates a CMS website running in an Azure Web Apps environment with multiple instances. The website instances share the same SQL database and BLOB storage that stores binary file data in the cloud environment. The sites are load-balanced, and a Service Bus manages events between the CMS websites.

Using App Service plans, you can increase or reduce the number of CMS sites from the Azure portal.

Choose_pricing_tier.png

The following steps create an Optimizely CMS website running in an Azure website environment.

1. Creating a site 

  1. Creating a CMS site is based on the .NET Core new template, see Installing Optimizely.
  2. Install the NuGet package EPiServer.Azure to the project. See Installing Optimizely updates.
  3. Save your license file under the site root, on the same level in the folder structure as the /bin folder. The license is used and activated later when you deploy the website to Azure.

2. Creating Azure resources

Log in to the Azure portal and follow these steps to create the necessary Azure components:

  1. Create an Azure web app.
    1. In the Azure portal, select Create a resource in the top left corner, and select Web App.
      Create_web_app.png
    2. Choose whether to create a new Resource group or use an existing. (A resource group is a logical container into which web apps, databases etc are deployed.)
      imagec60l.png
    3. Enter a name for your web app. The name must be unique for all web apps in Azure.
    4. Select Publish: Docker Container, and your operating system and region.
    5. Select or create an App Service plan.
    6. Click Review + create at the bottom of the pane and then Create again after you have reviewed your settings.
      Tip: Select Pin to dashboard to make it easier to find your web app later.
  2. Create a new SQL database.
    1. Select Create a resource in the top left corner, and select SQL Database.
    2. Select an existing server or create a new one, and provide a login user and password.
      Configure_SQL_server.png
    3. Under Networking, select Connectivity method: Public endpoint and enable Allow Azure services and resources to access this server and Add current client IP address.
      Configure_SQL_server_Networking.png
    4. Adjust other settings as necessary. 
    5. Click Review + create and then Create again after you have reviewed your settings.
  3. Create Azure BLOB storage.

    When you run on Azure, you should store media (such as images) in Azure BLOB storage to enable scaling.

    1. Select Create a resource in the top left corner, and select Storage account.
    2. Enter a name for the storage. The storage container name must be in lowercase, such as mysitemedia, for DNS compatibility.
      Tip: Create two BLOB storage accounts: one for development and one for production, and switch between them using just the connection string.
      Create_storage_account.png
    3. Adjust other settings as necessary. 
    4. Click Review + create and then Create again after you have reviewed your settings
  4. Create a service bus.

    To scale the site to run on several instances, set up a Service Bus in Azure to handle messages among the site instances.

    1. Select Create a resource in the top left corner, and then Integration > Service Bus.
    2. Select a name, a pricing tier, a resource group and a region. 
      Tip: Create two Service Bus accounts: one for development and one for production, and switch between them using just the connection string.
      Create_service_bus.png
    3. +Click Create.

3. Updating the configuration

Next you need to change some configurations for the website to work with Azure. 

Warning: Do not skip this step! If you do, assets are stored locally, and will not deploy properly to the Azure Blob storage.

There are two ways of configuring Azure resources, one way is by using the EPiServer.Azure package directly and map BLOB and event providers in the appsettings.json, and the other is by using the EPiServer.CloudPlatform.Cms NuGet package.

  1. Choose one of these options.

    • Using the EPiServer.Azure package NuGet directly: Open appsettings.json and add the following configuration under the episerver.framework section to map BLOB and event providers to Azure.

      {
          "EPiServer": {
              "Cms": {
                  "BlobProviders": {
                      "DefaultProvider": "azure",
                      "Providers": {
                          "azure": "EPiServer.Azure.Blobs.AzureBlobProvider, EPiServer.Azure"
                      }
                  },
                  "AzureBlobProvider": {
                      "ConnectionString": "The contention string",
                      "ContainerName": "The container name"
                  },
                  "EventProvider": {
                      "Provider": "EPiServer.Azure.Events.AzureEventProvider,EPiServer.Azure"
                  },
                  "AzureEventProvider": {
                      "ConnectionString": "The contention string",
                      "TopicName": "The topic name "
                  }
              }
          }
      }
    • Using the EPiServer.CloudPlatform.Cms NuGet package: If you have a reference to the NuGet package, you only need to add this code in ConfigureServices method in the startup.cs file.
      public class Startup
      {
              private readonly IConfiguration _configuration { get;}
              public Startup(IWebHostEnvironment webHostingEnvironment, IConfiguration configuration)
              {
                  . . .
                  _configuration = configuration;
              }
      
              public void ConfigureServices(IServiceCollection services)
              {
                  . . .
                  services.AddCmsCloudPlatformSupport(_configuration);
              }
      }​
      This way, the Azure BLOB, event provider, and other Azure cloud-specific components are added. Default options like containername and topicname ("mysitemedia", "MySiteEvents", "EPiServerAzureBlobs", and "EPiServerAzureEvents") are picked up from the connectionstrings section (see next step).
  2. Update connection strings.
    In the appsettings.json file, configure the following three connection strings:
    1. Change the connection string for EPiServerDB to the SQL database connection string from Azure portal. Remember to keep the setting MultipleActiveResultSets=true.
      You can find the connection string to your Azure SQL database in the Azure portal under your SQL database > Overview > Show database connection strings.
      Database_connection_strings.png
    2. Add a connection string named EPiServerAzureBlobs (it should match the BLOB provider name in episerver.framework). The connection string to the BLOB storage should be in the format:
      connectionString="DefaultEndpointsProtocol=https;AccountName=<name>;AccountKey=<key>"
      You can find the connection string to your Azure BLOB provider in the Azure portal under your storage account > Settings > Access keys
    3. Add a connection string named EPiServerAzureEvents (it should match the event provider name in episerver.framework).
      You can find the connection string to the event provider in the Azure portal under your service bus account > Settings Shared access policies. Select the policy RootManagedSharedAccessKey. In a new pane you will see the connection strings and access keys. 
      The following example shows the three database connection strings in web.config, defined for Azure:
      {
          "ConnectionStrings": {
              "EPiServerDB": "Server=tcp:abcdefgh.database.windows.net,1433;Database=mySiteDB;User ID=dbadmin@abcdefgh;Password={password};Trusted_Connection=False;Encrypt=True;Connection Timeout=30;MultipleActiveResultSets=True",
              "EPiServerAzureBlobs": "DefaultEndpointsProtocol=https;AccountName=mystorageccount;AccountKey=abcdefghijklmnoabcdefghijklmnoabcdefghijklmno",
              "EPiServerAzureEvents": "Endpoint=sb://myservicebus.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=abcdefghijklmnoabcdefghijklmnoabcdefghijklmno="
          }
      }

4. Deploying to Azure

The application or site needs to be pushed to a container registry, Azure provider, or such resource. There are many ways to to push applications to the container registry in Azure;  one way is by using Visual Studio, see external-link.png Microsoft: Container Tools in Visual Studio.

    Deploying through source control

    Deploying content

    From version 7.7 of CMS, there is a Bootstrap feature for content. It works so that if there is an export package located at [SolutionDir]\App_Data\DefaultSiteContent.episerverdata, that package is imported during initialization and a site is created. The Bootstrap happens only if the site does not have any previous content. For cloud deployment, you may want to first publish the project to the cloud environment before starting a local site configured against the cloud database. In that case, the Bootstrap happens in the cloud environment, which is much faster (because the site and database are likely in same datacenter) and also sets the SiteUrl to the cloud URL for the created site.

    You can also transfer data to an Optimizely site running on Azure Web Apps using the Optimizely CMS export/import functionality. Export the start page from your local site and database and import on the site running in Azure before continuing to the next step. See Exporting and importing in the Optimizely User Guide.

    5. Creating an admin/edit user

    To log in to the site on Azure, create a user with access to the edit/admin view, start the local site while connected to SQL Database, and perform the following steps. You must allow the source IP address to access the Azure database server. You can enable this in the Azure Portal on the specific SQL Database server (select the SQL server > Firewall/Virtual Networks > Add client IP). How to create the first user depends on which identity provider has been configured; membership or AspNet Identity provider.

    Membership Identity Provider

    1. Start the site (Debug/F5).
    2. Go to the CMS admin view > Administer Groups (http://site:port/EPiServer/Cms/Admin).
    3. Log in with a local Windows administrator account.
    4. Create the two groups WebAdmins and WebEditors, these are default Optimizely groups providing access to the edit/admin user interface.
    5. Go to Create User and create a user that is a member of both WebAdmins and WebEditors. You will need this user later when logging in to the Azure website after deployment. 

    AspNet Identity Provider

    1. Start the site (Debug/F5).
    2. You are redirected to a register page where you can register the first user belonging to the WebAdmins group.
    3. Go to the CMS admin view > Administer Groups (http://site:port/EPiServer/Cms/Admin).
    4. Create another group WebEditors. The WebAdmins and WebEditors are default Optimizely groups providing access to the edit/admin user interface.
    5. Go to Create User and create a user that is a member of both WebAdmins and WebEditors. You will need this user later when logging in to the Azure website after deployment. 

    6. Activate the license

    Go to the CMS admin view and activate your cloud license on both test and production environments. The running instances will be counted towards the total number of instances allowed by the license. See also: Managing cloud licenses. OBS: Should be new picture. It is not finished yet.

    CloudLicense-2.png

    7. Changing the site URL

    Depending on how the site was created (see Deploying content), you might need to update the site definition for the CMS website created in the first steps after deployment. If so, log in to the website and go to the CMS admin view > Config > Manage Websites, and change the Site URL to the URL in Azure. This will also map a host name to the correct site in CMS. The URL can be found in the Azure portal. Select your web app > Overview, the site URL is given in the right column.

    Site_URL.png

    Activate logging

    Optimizely CMS supports writing to the diagnostics log using BLOB storage. 

    Follow these steps to activate the logging:

    1. Open your app service and go to Diagnostic settings (preview).
    2. Click add Add diagnostic setting.
    3. Select desired Category, destination and click Save when done. Note: This functionality is under preview and it maybe be changed.

    Note: The web app will restart when activating the logging. Note that Id do not know if it is valid for new Azure app service.

    SQL database automatic tuning

    The Azure SQL Database Automatic tuning is a feature that provides improved performance and automatic tuning of the database, based on AI and machine learning. It is recommended to leave the settings as default, and in particular leave CREATE INDEX as Off, as turning it on might cause problems with the Optimizely Dynamic Data Store (DDS) and sub-optimal indexes.

    Autotuning.png

    Search in Azure

    You should use a scalable search solution when you host in Azure. It is not recommended to use the Optimizely Search package in Azure Web Apps, as data corruption can occur in the Lucene index used by the built-in search, when scaling up to multiple instances. 

    If you need scaling, use Optimizely Search & Navigation instead. This is a hosted service that you connect to, and that works the same way as when your site runs on-premise. Optimizely Search & Navigation is included when running your solution in Optimizely Digital Experience Platform (DXP).

    Staged deployment

    Azure Web Apps supports deployment slots, so you can deploy new code into a staging environment before moving it to production. To make sure deployment slots do not interfere with the production environment, make sure you define the EPiServerDB, EPiServerAzureEvents and EPiServerAzureBlobs connection strings in the Azure portal as "sticky" (session affinity) to each slot. If a deployment slot re-uses the production connection strings, it is treated as a load-balanced server, part of the production environment, including licensing restrictions. See Microsoft documentation for details about using staging with Azure Web Apps.

    imagehyh4.png

    Note: Defining the EPiServerDB, EPiServerAzureEvents and EPiServerAzureBlobs as connection strings in the Azure Portal requires at least EPiServer.CMS.Core 8.3.0.

    image37a4.png 

    The core parts of Optimizely CMS do not use Session State but some functionality does, such as some Visitor Groups criteria. There are two approaches to enabling session state, depending on the sticky session feature (also known as session affinity) provided by Azure App Service which makes sure a user is reaching the same server combined with the default in-memory session state provider.

    imageirhq.png

    Another approach to enable better scaling is using an optimized provider for Azure, such as the session provider for Azure Web Apps.

    Related topics

    Do you find this information helpful? Please log in to provide feedback.

    Last updated: Jul 02, 2021

    Recommended reading