Connecting Sitecore PaaS to Azure Cosmos DB

Sitecore’s new PaaS offering in Azure is now available. When you’re creating an instance of Sitecore Experience Platform, you’re required to provide a MongoDB connection string for XDB. There are a few options in Azure for a Mongo service, but I decided to try to set it up with Microsoft’s Cosmos DB (formerly DocumentDB). Unfortunately, it didn’t work immediately, so I had to dig in a little bit to get my new PAAS Sitecore instance up and running. This post will walk through setting up Cosmos DB in Azure, attaching it to a new Sitecore PAAS instance, and deploying some custom code to our Sitecore instance to resolve the error connecting to Cosmos DB.

Setup Azure Cosmos DB

The first thing you want to do is set up Cosmos DB in Azure. Log into your portal, and select New Resource on the left. Select Database, then “Database as a Service for MongoDB”. You’ll need to provide a resource ID, as well as a Resource Group and select a Location. Fill out the fields and click create. After a few moments your new Cosmos DB instance will be available.

If you didn’t click Pin to Dashboard before creating, you can find it in the Resouces list. Click on the new database and open up the resouce viewer. You’ll see some general information in the Overview tab. On the left, find and click Connection String under Settings. Here you’ll see the connection strings, port number, username and password you’ll need to connect Sitecore to CosmosDB.

Notice at the bottom of this page the disclaimer, “Azure Cosmos DB has strict security requirements and standards. Azure Cosmos DB accounts require authentication and secure communication via SSL.” This is a problem for Sitecore out of the box, and where we’ll need to do some customization to support secure connections to Mongo.

Setup Sitecore PaaS

Next we’ll set up Sitecore PAAS. This is quite easy with the latest release of Sitecore 8.2, update 3. If you click the New Resource button and search for Sitecore, you’ll see two offerings. Sitecore Experience Platform 8.2, and Sitecore Web Experience Manager 8.2. Since we’re setting up Mongo, that means we need Sitecore XP, so choose that. You’ll need to configure a few things. For the SQL, a username and password. For Sitecore, you’ll need to provide the admin password and your license file. Make a note of these.

Under Sitecore XP Settings, you’ll need to provide connection strings to MongoDb. These will be available in the resource view for the CosmosDB instance we set up, if you didn’t make a note of them previously. You’ll need to edit that connection string to add the XDB table name that Sitecore expects. For example, for the analytics connection string,

mongodb://your-resource-name:12345yourResourceToken12345==@your-resource-name.documents.azure.com:12345/sitecore_analytics?ssl=true&replicaSet=globaldb

It will take some time for your new Sitecore environment to be provisioned. Once it’s ready, open up the resource viewer. In the Essentials view, you’ll see the url of your new instance. Go ahead and open that up, and you’ll see the familiar Sitecore welcome page. You can even log into Sitecore. In Azure, open up Application Insights and view the Log Stream (you may need to turn on Application Logs in the Diagnostic Logging tab first). You’re probably seeing errors related to MongoDb, in particular an error about the transport stream.
“Unable to connect to a member of the replica set matching the read preference Primary: Authentication failed because the remote party has closed the transport stream.”

This is because Cosmos DB requires an SSL connection, and out of the box, Sitecore does not support that. So, we’ll need to deploy a fix for this. Fortunately, Sitecore provides us a pipeline to hook into to override the MongoDB Connection behavior. To correct this issue, we’ll need to enable secure connections to MongoDB.

Deploying a change to Sitecore PaaS

We’ll need to create a class to insert into the updateMongoDriverSettings pipeline. Our processor is going to explicitly set the connection mode to be secure and tell it to use TLS 1.2 in order to connect to Cosmos DB. Here’s the code:


using System.Security.Authentication;
using MongoDB.Driver;
using Sitecore.Analytics.Pipelines.UpdateMongoDriverSettings;

namespace Sitecore.SharedSource.CustomMongo
{
  public class CustomMongoDbClientProcessor : UpdateMongoDriverSettingsProcessor
  {
    public override void UpdateSettings(UpdateMongoDriverSettingsArgs args)
    {
    args.MongoSettings.SslSettings = new SslSettings();
    args.MongoSettings.SslSettings.EnabledSslProtocols = SslProtocols.Tls12;
    }
  }
}

And here’s the config file we need to insert the processor:


<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <sitecore>
    <pipelines>
      <updateMongoDriverSettings>
        <processor type="Sitecore.SharedSource.CustomMongo.CustomMongoDbClientProcessor, Sitecore.SharedSource.CustomMongo" />
      </updateMongoDriverSettings>
    </pipelines>
  </sitecore>
</configuration>

Finally we need to deploy this to our Azure app. Azure offers a lot of options for deployment, but for this example we’ll settle for FTP. You’ll need to set up credentials for the FTP connection, you can do that under Deployment credentials.

 

Once you’ve done that, take a look at the overview page, and you’ll see your FTP information.

Connect with your FTP client of choice, and upload our new DLL with our processor to the /bin folder and our new config to App_Config/Include/zzz.

With this processor in place, Sitecore should now be connected to Cosmos DB.