Microsoft Azure Fundamentals #4: Azure Service Bus Topics and Subscriptions for multi-system CRM workflows in Microsoft Dataverse / Dynamics 365

๐Ÿš€ 1. Scenario Overview

In modern enterprise environments, a single business event in Microsoft Dataverse (CRM) can trigger workflows across multiple systems โ€” ERP, marketing automation, data lakes, or custom line-of-business (LOB) apps.

To avoid tight coupling between these systems, Azure Service Bus Topics & Subscriptions provide a robust message-based pub/sub architecture that guarantees delivery, order, and scalability.

Goal:
Design an integration that ensures when data changes in CRM (Dataverse), multiple downstream systems react independently and reliably โ€” without CRM knowing who the consumers are.


๐Ÿงฉ 2. Core Concepts

ConceptDescription
TopicA message queue that supports publishโ€“subscribe pattern. Producers send messages here.
SubscriptionLogical endpoints attached to a topic. Each subscriber gets its own copy of the message.
Filter RulesConditions applied at the subscription level to control which messages are delivered.
SessionEnables ordered message processing per customer, case, or entity.
Dead Letter Queue (DLQ)Holds undeliverable messages for later investigation.

โš™๏ธ 3. Architecture Overview

Flow:

  1. Dataverse triggers a custom Azure Function or Webhook Plugin upon record changes.
  2. The Function publishes a message (event) to Azure Service Bus Topic.
  3. Multiple subscriptions deliver that message to specific systems:
    • ERP System Subscriber
    • Marketing Automation Subscriber
    • Analytics/Data Lake Subscriber
    • Notification/Power Automate Subscriber
  4. Each subscriber processes its copy of the message independently.

๐Ÿง  4. Step-by-Step Implementation

๐Ÿ”น Step 1: Enable Change Tracking or Register Plugin in Dataverse

Use Change Tracking or Post-Operation Plugin to capture CRUD events in real-time.

๐Ÿ“˜ Example:

public class AccountUpdatedPlugin : IPlugin
{
    public void Execute(IServiceProvider serviceProvider)
    {
        var context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
        var account = (Entity)context.InputParameters["Target"];
        
        // Prepare message payload
        var message = new {
            EntityName = "account",
            Id = account.Id,
            Operation = context.MessageName,
            Timestamp = DateTime.UtcNow,
            Data = account.Attributes
        };

        // Send to Azure Function endpoint
        HttpClient client = new HttpClient();
        client.PostAsJsonAsync(Environment.GetEnvironmentVariable("AzureFunctionUrl"), message).Wait();
    }
}


๐Ÿ”น Step 2: Publish Message to Azure Service Bus Topic

In the Azure Function, push incoming messages to Service Bus Topic:

๐Ÿ“˜ Example (C#):

[FunctionName("PublishToServiceBus")]
public static async Task Run([HttpTrigger("post")] HttpRequest req, ILogger log)
{
    var messageBody = await new StreamReader(req.Body).ReadToEndAsync();
    var topicClient = new ServiceBusClient(Environment.GetEnvironmentVariable("ServiceBusConnection"));
    var sender = topicClient.CreateSender("crm-events-topic");
    
    ServiceBusMessage message = new(messageBody)
    {
        Subject = "Dataverse.Account.Updated",
        ContentType = "application/json",
        CorrelationId = Guid.NewGuid().ToString()
    };

    await sender.SendMessageAsync(message);
    log.LogInformation($"Published Dataverse event to topic.");
}


๐Ÿ”น Step 3: Create Subscriptions for Each Consumer

In the Azure Portal or via PowerShell:

๐Ÿ“˜ Example:

New-AzServiceBusSubscription -ResourceGroup "rg-crm" `
  -NamespaceName "crmservicebusns" `
  -TopicName "crm-events-topic" `
  -Name "ERPSyncSubscriber"

New-AzServiceBusRule -ResourceGroup "rg-crm" `
  -NamespaceName "crmservicebusns" `
  -TopicName "crm-events-topic" `
  -SubscriptionName "ERPSyncSubscriber" `
  -Name "AccountFilterRule" `
  -FilterType SqlFilter `
  -SqlExpression "Subject LIKE '%Account%'"

Each system (ERP, Data Lake, Marketing, etc.) gets its own subscription, optionally filtered by entity type or operation (create/update/delete).


๐Ÿ”น Step 4: Implement Subscriber Logic

Each subscriber can use Azure Functions, Logic Apps, or custom microservices to consume messages.

๐Ÿ“˜ Example (Azure Function Subscriber):

[FunctionName("ERPSyncSubscriber")]
public static void Run([ServiceBusTrigger("crm-events-topic", "ERPSyncSubscriber", Connection = "ServiceBusConnection")] string message, ILogger log)
{
    var crmEvent = JsonConvert.DeserializeObject<CrmEvent>(message);
    log.LogInformation($"Received event for {crmEvent.EntityName} ({crmEvent.Operation})");
    
    // Sync with ERP
    UpdateERPSystem(crmEvent);
}

Each subscriber:

  • Processes messages in isolation.
  • Can retry independently.
  • Has its own DLQ for fault isolation.

๐Ÿ”น Step 5: Implement Monitoring & Retry Policies

  • Enable Auto-Forwarding to DLQ after N retries.
  • Configure Application Insights logging.
  • Add dead-letter reprocessor Function to handle failed messages.

๐Ÿงฑ 5. Advanced Design Patterns

PatternDescription
Competing ConsumersScale-out multiple instances of the same subscriber for throughput.
Message FilteringUse SQL Filters (e.g., EntityName = 'account') for targeted delivery.
Session-Aware ProcessingMaintain ordered processing for the same customer/account.
Correlation ID PropagationTrack business transactions across systems.
Poison Message HandlingDetect and isolate unprocessable messages.
Idempotent ProcessingUse message deduplication (via MessageId) to avoid duplicates.

๐Ÿง  6. Example Use Case

Scenario:
When a new Account is created in Dynamics 365:

  • ERP subscriber creates a corresponding customer record.
  • Marketing subscriber enrolls them into a campaign.
  • Analytics subscriber logs it to Azure Data Lake.
  • Notification subscriber sends an alert to Teams.

All triggered from a single message published once by CRM โ†’ Azure Service Bus Topic.


๐Ÿ” 7. Security & Governance

  • Use Azure Managed Identity for authentication (no connection strings).
  • Enable RBAC roles for topic publishers and subscribers.
  • Encrypt messages in transit (TLS) and at rest (Service Bus encryption).
  • Use Private Endpoints for compliance-sensitive data.

๐Ÿ“ˆ 8. Benefits

โœ… Decoupled and scalable multi-system integrations.
โœ… Guaranteed message delivery and retry handling.
โœ… Supports high-volume, enterprise-grade CRM workloads.
โœ… Enables modular evolution โ€” add/remove systems without CRM changes.
โœ… Built-in resiliency, auditing, and observability.


๐Ÿงฉ 9. Sample Architecture Summary

Flow:
Dataverse (Plugin/Webhook) โ†’ Azure Function (Publisher) โ†’ Service Bus Topic โ†’ Multiple Subscriptions โ†’ ERP / Marketing / Analytics / Notifications

Core Azure Components:

  • Service Bus Topics/Subscriptions
  • Azure Functions / Logic Apps
  • Application Insights
  • Managed Identity


Discover more from Common Man Tips for Power Platform, Dynamics CRM,Azure

Subscribe to get the latest posts sent to your email.

Leave a comment