Exam Area: Area 2 – Installation, Operation & Configuration (20%) Reference: https://docs.developers.optimizely.com/content-management-system/docs/deploying-to-production
Optimizely CMS is a distributed, stateless application. Multiple web servers can serve the same site, provided they share:
Internet
│
▼
[ Load Balancer / Azure Front Door ]
│
├──▶ [ Web Server 1 ] (ASP.NET Core, Kestrel/IIS)
└──▶ [ Web Server 2 ] (ASP.NET Core, Kestrel/IIS)
│
├──▶ [ Azure SQL / SQL Server ] (shared)
├──▶ [ Azure Blob Storage ] (shared media)
├──▶ [ Azure Redis Cache ] (shared L2 cache)
└──▶ [ Azure Service Bus ] (cache invalidation events)
| Component | Role | Technology |
|---|---|---|
| SQL Server | All content, configuration, scheduled job status | Azure SQL / SQL Server |
| Blob Storage | Media files (images, videos, documents) | Azure Blob Storage / File Share |
| Distributed Cache | Second-level cache (reduces DB load) | Azure Redis Cache |
| Event Bus | Cache invalidation across servers | Azure Service Bus / SQL Events |
| Shared Data Protection | ASP.NET Core encryption keys | Azure Key Vault or Blob |
Developer Machine:
├── IIS / IIS Express / Kestrel
├── SQL Server LocalDB or SQL Express
├── Local file system (no blob storage needed)
├── In-memory cache (no Redis needed)
└── No Service Bus (single process, no cache sync needed)
The Optimizely Digital Experience Platform (DXP) provides a fully managed Azure infrastructure:
DXP Environments:
┌─────────────────────────────────────────────────────────┐
│ Integration (DEV) │
│ App Service: 1 instance (B2/B3) │
├─────────────────────────────────────────────────────────┤
│ Preproduction (STAGING) │
│ App Service: 1-2 instances │
├─────────────────────────────────────────────────────────┤
│ Production │
│ App Service Plan: 2+ instances (auto-scale) │
│ + Azure SQL Managed Instance │
│ + Azure Blob Storage (private endpoint) │
│ + Azure Redis Cache (private endpoint) │
│ + Azure CDN (Akamai/Azure Front Door) │
│ + Azure Service Bus │
│ + Azure Application Insights │
└─────────────────────────────────────────────────────────┘
// Program.cs — configure Redis as distributed cache
builder.Services.AddStackExchangeRedisCache(options =>
{
options.Configuration = configuration["Redis:ConnectionString"];
options.InstanceName = "MyProject:";
});
// CMS will automatically use the registered IDistributedCache
// Program.cs — use Azure Service Bus for CMS events
builder.Services.Configure<ServiceBusOptions>(options =>
{
options.ConnectionString = configuration["AzureServiceBus:ConnectionString"];
options.TopicName = "episerver-events";
});
builder.Services.AddCmsAzureServiceBusEventProvider();
// Program.cs — Azure Blob provider
builder.Services.AddAzureBlobProvider(options =>
{
options.ConnectionString = configuration["AzureBlobStorage:ConnectionString"];
options.ContainerName = "mysitemedia";
});
| Problem | Without shared state | With shared state |
|---|---|---|
| Editor publishes page | Only Server 1 cache updated | All servers get cache invalidation via Service Bus |
| Media uploaded | Stored on Server 1 disk only | Stored in shared Blob Storage |
| Session affinity | Users "stuck" to one server | Stateless — any server can serve any request |