⚙️ Installation & Configuration
Best Physical Architecture
📖 Docs

Best Physical Architecture - Optimizely CMS 12

Exam Area: Area 2 – Installation, Operation & Configuration (20%) Reference: https://docs.developers.optimizely.com/content-management-system/docs/deploying-to-production


1. Guiding Principle

Optimizely CMS is a distributed, stateless application. Multiple web servers can serve the same site, provided they share:

  1. SQL Server database (content + configuration)
  2. Blob storage (media files)
  3. Distributed cache (Redis — cache coherency)
  4. Event messaging (Azure Service Bus — cache invalidation)

2. Minimum Production Setup

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)

3. Required Shared Components

ComponentRoleTechnology
SQL ServerAll content, configuration, scheduled job statusAzure SQL / SQL Server
Blob StorageMedia files (images, videos, documents)Azure Blob Storage / File Share
Distributed CacheSecond-level cache (reduces DB load)Azure Redis Cache
Event BusCache invalidation across serversAzure Service Bus / SQL Events
Shared Data ProtectionASP.NET Core encryption keysAzure Key Vault or Blob

4. Development / Local Setup

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)

5. DXP (Azure Paas) Architecture

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                          │
└─────────────────────────────────────────────────────────┘

6. Configuration for Distributed Cache (Redis)

// 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

7. Configuration for Azure Service Bus (Events)

// 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();

8. Blob Storage Configuration

// Program.cs — Azure Blob provider
builder.Services.AddAzureBlobProvider(options =>
{
    options.ConnectionString = configuration["AzureBlobStorage:ConnectionString"];
    options.ContainerName    = "mysitemedia";
});

9. Why Shared State Matters

ProblemWithout shared stateWith shared state
Editor publishes pageOnly Server 1 cache updatedAll servers get cache invalidation via Service Bus
Media uploadedStored on Server 1 disk onlyStored in shared Blob Storage
Session affinityUsers "stuck" to one serverStateless — any server can serve any request

10. Scheduled Jobs in Multi-Server


Review Questions

  1. What 4 components must be shared between CMS web servers? (SQL Server, Blob Storage, Redis Cache, Service Bus)
  2. Why is Azure Service Bus needed in a multi-server setup? (Cache invalidation — when one server publishes content, all others are notified to flush their cache)
  3. Is Redis required for a single-server setup? (No — in-memory cache is sufficient)
  4. What DXP environment should be used for final testing before production? (Preproduction)
  5. How does CMS prevent duplicate scheduled job execution on multiple servers? (SQL-based leader election — only one server runs the job)