Azure Logic Apps Service Bus Integration
Enterprise Messaging Integration
Introduction
Azure Logic Apps provide deep integration with Azure Service Bus, enabling you to build robust workflows that send, receive, process, and manage messages across enterprise systems. The Service Bus connector supports queues, topics, subscriptions, and sessions, making it ideal for building decoupled, resilient integration solutions.
This comprehensive guide covers:
- Receive triggers — Listening for messages from queues and subscriptions
- Send actions — Publishing messages to queues and topics
- Message handling — Complete, abandon, dead-letter operations
- Sessions — Ordered message processing
- Expressions — Dynamic message content
- Best practices — Reliability and performance
Architecture Overview
Service Bus Integration Flow
┌─────────────────────────────────────────────────────────────────────┐
│ LOGIC APPS + SERVICE BUS INTEGRATION │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ LOGIC APP WORKFLOW │ |
│ │ │ |
│ │ ┌────────────────────────────────────────────────────────┐│ │
│ │ │ TRIGGER: When message arrives ││ │
│ │ │ - Queue: orders-queue ││ │
│ │ │ - Mode: Peek lock ││ │
│ │ └───────────────────────┬────────────────────────────────┘│ │
│ │ │ │ |
│ │ ▼ │ |
│ │ ┌────────────────────────────────────────────────────────┐│ │
│ │ │ PROCESS MESSAGE ││ │
│ │ │ - Parse JSON ││ │
│ │ │ - Validate data ││ │
│ │ │ - Transform if needed ││ │
│ │ └───────────────────────┬────────────────────────────────┘│ │
│ │ │ │ |
│ │ ┌────────────┴───────────┐ │ |
│ │ │ │ │ |
│ │ ▼ ▼ │ |
│ │ ┌──────────────────┐ ┌──────────────────┐ │ |
│ │ │ COMPLETE │ │ ABANDON/DLQ │ │ |
│ │ │ (Success) │ │ (Failure) │ │ |
│ │ └────────┬─────────┘ └─────────┬────────┘ │ |
│ │ │ │ │ |
│ └────────────┼─────────────────────────┼──────────────────────┘ │
│ │ │ │
│ ▼ ▼ │
│ ┌────────────────────────┐ ┌────────────────────────┐ │
│ │ SERVICE BUS QUEUE │ │ SERVICE BUS QUEUE │ │
│ │ orders-queue │ │ orders-queue │ │
│ └────────────────────────┘ └────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────┘
Queue vs Topic Patterns
┌─────────────────────────────────────────────────────────────────────┐
│ QUEUE VS TOPIC PATTERNS │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ QUEUE (Point-to-Point) │
│ ───────────────────────── │
│ │
│ ┌────────┐ ┌────────┐ ┌────────┐ │
│ │ Sender │─────▶│ Queue │─────▶│Receiver│ │
│ └────────┘ └────────┘ └────────┘ │
│ │
│ - One sender → One receiver │
│ - Message processed once │
│ - Use for: Direct processing │
│ │
│ TOPIC (Pub-Sub) │
│ ───────────────── │
│ │
│ ┌────────┐ ┌───────┐ ┌──────────┐ │
│ │ Sender │─────▶│ Topic │─────▶│ Sub 1 │ │
│ └────────┘ └───────┘ └──────────┘ │
│ │ │ ┌──────────┐ │
│ │ │───────────▶│ Sub 2 │ │
│ │ │ └──────────┘ │
│ │ │ ┌──────────┐ │
│ │ └───────────▶│ Sub 3 │ │
│ │ └──────────┘ │
│ │
│ - One sender → Multiple receivers │
│ - Same message to all subscriptions │
│ - Use for: Broadcasting, notifications │
│ │
└─────────────────────────────────────────────────────────────────────┘
Receive Messages (Triggers)
Queue Trigger Configuration
{
"triggers": {
"When_a_message_is_received_in_a_queue": {
"type": "ServiceBusTrigger",
"inputs": {
"subscription": {
"subscriptionName": "orders-queue"
},
"connection": {
"connectionName": "ServiceBusConnection"
},
"queueName": "orders-queue",
"lockDuration": "PT1M",
"maxMessageCount": 10,
"peekLock": true
},
"recurrence": {
"frequency": "Second",
"interval": 3
}
}
}
}
Trigger Parameters
| Parameter | Description | Default | Notes |
|---|---|---|---|
| Queue Name | Name of the queue | Required | Must exist in namespace |
| Connection | Service Bus connection string | Required | Use managed identity in production |
| Peek Lock | Enable peek-lock mode | Enabled | For reliable processing |
| Lock Duration | Message lock duration | 1 minute | Can be extended |
| Max Message Count | Messages per poll | 10 | 1-100 |
| Polling Interval | Check frequency | 3 seconds | Minimum 1 second |
Subscription Trigger (Topic)
{
"triggers": {
"When_a_message_is_received": {
"type": "ServiceBusTrigger",
"inputs": {
"topicName": "orders-topic",
"subscriptionName": "processor-sub",
"connection": {
"connectionName": "ServiceBusConnection"
},
"peekLock": true
}
}
}
}
Process and Complete Messages
Message Completion Flow
┌─────────────────────────────────────────────────────────────────────┐
│ MESSAGE PROCESSING FLOW │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ 1. MESSAGE ARRIVES │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ Message locked (Peek Lock) │ │
│ │ Lock token: abc-123 │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ 2. PROCESS MESSAGE │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ - Parse JSON │ │
│ │ - Validate data │ │
│ │ - Business logic │ │
│ │ - Transform if needed │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │ │
│ ┌───────────────┴───────────────┐ │
│ │ │ │
│ ▼ ▼ │
│ 3. SUCCESS 4. FAILURE │
│ ┌───────────────────┐ ┌───────────────────┐ │
│ │ Complete Message │ │ Abandon Message │ │
│ │ Lock token: abc │ │ Lock token: abc │ │
│ │ → Message removed │ │ → Message returns │ │
│ │ from queue │ │ to queue │ │
│ └───────────────────┘ └───────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────┘
Complete Action
{
"Complete_the_message": {
"type": "ServiceBus",
"inputs": {
"method": "post",
"path": "/subscriptions/default/messages/complete",
"body": {
"lockToken": "@triggerBody()?['LockToken']"
},
"host": {
"connection": {
"referenceName": "ServiceBusConnection"
}
}
}
}
}
Abandon Action
{
"Abandon_the_message": {
"type": "ServiceBus",
"inputs": {
"method": "post",
"path": "/subscriptions/default/messages/abandon",
"body": {
"lockToken": "@triggerBody()?['LockToken']",
"properties": {
"abandonReason": "@triggerBody()?['ErrorMessage']"
}
},
"host": {
"connection": {
"referenceName": "ServiceBusConnection"
}
}
}
}
}
Send Messages (Actions)
Send to Queue
{
"Send_message": {
"type": "ServiceBus",
"inputs": {
"method": "post",
"path": "/queues/notification-queue/messages",
"body": {
"contentData": "@triggerBody()",
"contentType": "application/json",
"properties": {
"CorrelationId": "@triggerBody()?['orderId']",
"Subject": "Order Notification",
"MessageId": "@guid()"
}
},
"host": {
"connection": {
"referenceName": "ServiceBusConnection"
}
}
}
}
}
Send to Topic
{
"Publish_to_topic": {
"type": "ServiceBus",
"inputs": {
"method": "post",
"path": "/topics/orders-topic/messages",
"body": {
"contentData": {
"orderId": "@triggerBody()?['orderId']",
"customerId": "@triggerBody()?['customerId']",
"total": "@triggerBody()?['total']",
"status": "Processed",
"processedAt": "@utcNow()"
},
"contentType": "application/json",
"properties": {
"MessageType": "OrderProcessed",
"Priority": "@if(greater(triggerBody()?['total'], 1000), 'High', 'Normal')"
}
},
"host": {
"connection": {
"referenceName": "ServiceBusConnection"
}
}
}
}
}
Schedule Message
{
"Send_scheduled_message": {
"type": "ServiceBus",
"inputs": {
"method": "post",
"path": "/queues/reminder-queue/messages",
"body": {
"contentData": {
"reminder": "Payment due soon",
"dueDate": "@addDays(utcNow(), 7)"
},
"scheduledEnqueueTimeUtc": "@addMinutes(utcNow(), 30)"
},
"host": {
"connection": {
"referenceName": "ServiceBusConnection"
}
}
}
}
}
Dead-Letter Operations
Send to Dead-Letter Queue
{
"Dead_letter_the_message": {
"type": "ServiceBus",
"inputs": {
"method": "post",
"path": "/subscriptions/default/messages/deadletter",
"body": {
"lockToken": "@triggerBody()?['LockToken']",
"deadLetterReason": "Processing failed after retries",
"deadLetterErrorDetails": "@actionOutputs('Process_Order')?['error']?['message']"
},
"host": {
"connection": {
"referenceName": "ServiceBusConnection"
}
}
}
}
}
Complete Workflow with Error Handling
{
"definition": {
"triggers": {
"When_message_arrives": {
"type": "ServiceBusTrigger",
"inputs": {
"queueName": "orders-queue",
"connection": { "referenceName": "ServiceBusConnection" },
"peekLock": true
}
}
},
"actions": {
"Parse_order": {
"type": "ParseJson",
"inputs": {
"content": "@triggerBody()"
}
},
"Validate_order": {
"type": "Condition",
"expression": "@and(not(empty(body('Parse_order')?['orderId'])), not(empty(body('Parse_order')?['customerId'])))",
"actions": {
"Process_valid": {
"type": "ProcessOrder",
"inputs": { "order": "@body('Parse_order')" }
},
"Complete_message": {
"type": "ServiceBus",
"inputs": {
"method": "post",
"path": "/subscriptions/default/messages/complete",
"body": { "lockToken": "@triggerBody()?['LockToken']" }
}
}
},
"else": {
"Actions": {
"Log_validation_failure": {
"type": "Log",
"inputs": { "message": "Order validation failed" }
},
"Dead_letter": {
"type": "ServiceBus",
"inputs": {
"method": "post",
"path": "/subscriptions/default/messages/deadletter",
"body": {
"lockToken": "@triggerBody()?['LockToken']",
"deadLetterReason": "Invalid order data"
}
}
}
}
}
}
}
}
}
Sessions Support
Enable Session Processing
{
"triggers": {
"When_session_message_arrives": {
"type": "ServiceBusTrigger",
"inputs": {
"queueName": "ordered-queue",
"connection": { "referenceName": "ServiceBusConnection" },
"isSessionsEnabled": true,
"sessionId": "@triggerBody()?['SessionId']"
}
}
}
}
Session-Based Workflow
{
"Process_orders_by_session": {
"triggers": {
"When_message_arrives": {
"type": "ServiceBusTrigger",
"inputs": {
"queueName": "orders-by-customer",
"connection": { "referenceName": "ServiceBusConnection" },
"isSessionsEnabled": true
}
}
},
"actions": {
"Group_by_customer": {
"type": "Switch",
"expression": "@triggerBody()?['SessionId']",
"cases": {
"Customer_A": {
"actions": {
"Process_CustomerA": { "type": "ProcessCustomerA" }
}
},
"Customer_B": {
"actions": {
"Process_CustomerB": { "type": "ProcessCustomerB" }
}
}
}
},
"Complete": {
"type": "ServiceBus",
"inputs": {
"method": "post",
"path": "/subscriptions/default/messages/complete",
"body": { "lockToken": "@triggerBody()?['LockToken']" }
}
}
}
}
}
Dynamic Content and Expressions
Message Property Extraction
{
"Extract_properties": {
"type": "Compose",
"inputs": {
"messageId": "@triggerBody()?['MessageId']",
"correlationId": "@triggerBody()?['CorrelationId']",
"sessionId": "@triggerBody()?['SessionId']",
"contentType": "@triggerBody()?['ContentType']",
"deliveryCount": "@triggerBody()?['DeliveryCount']",
"enqueuedTime": "@triggerBody()?['EnqueuedTimeUtc']",
"lockedUntil": "@triggerBody()?['LockedUntilUtc']"
}
}
}
Dynamic Message Construction
{
"Build_order_notification": {
"type": "Compose",
"inputs": {
"notificationId": "@guid()",
"timestamp": "@utcNow()",
"order": {
"orderId": "@triggerBody()?['orderId']",
"customer": "@triggerBody()?['customerName']",
"items": "@triggerBody()?['items']",
"total": "@triggerBody()?['total']"
},
"metadata": {
"source": "logic-app",
"version": "1.0",
"correlationId": "@triggerBody()?['CorrelationId']"
}
}
}
}
Use Case Examples
Order Processing Pipeline
┌─────────────────────────────────────────────────────────────────────┐
│ ORDER PROCESSING WORKFLOW │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ [Trigger: Service Bus - orders-queue] │
│ │ Mode: Peek lock │
│ │ Max messages: 10 │
│ └──────┬────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ [Parse JSON] │
│ └──────┬────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ [Condition: Valid Order?] │
│ ├─ Yes: │
│ │ ├─ [Call Azure Function: Validate] │
│ │ ├─ [Condition: Inventory Available?] │
│ │ │ ├─ Yes: [Update Database] + [Complete] + [Send Email] │
│ │ │ └─ No: [Reserve Inventory] + [Complete] │
│ │ └─ [Send to fulfillment topic] │
│ │ │
│ └─ No: │
│ ├─ [Log error] │
│ └─ [Dead-letter + Send Alert Email] │
│ │
└─────────────────────────────────────────────────────────────────────┘
Notification Broadcasting
{
"Notify_multiple_systems": {
"triggers": {
"Order_processed": {
"type": "ServiceBusTrigger",
"inputs": {
"topicName": "orders-topic",
"subscriptionName": "notification-processor"
}
}
},
"actions": {
"Send_to_email": {
"type": "ServiceBus",
"inputs": {
"method": "post",
"path": "/queues/email-notifications/messages",
"body": {
"template": "order-confirmation",
"data": "@triggerBody()"
}
}
},
"Send_to_analytics": {
"type": "ServiceBus",
"inputs": {
"method": "post",
"path": "/queues/analytics-events/messages",
"body": {
"event": "order.processed",
"data": "@triggerBody()"
}
}
},
"Send_to_inventory": {
"type": "ServiceBus",
"inputs": {
"method": "post",
"path": "/topics/inventory-update/messages",
"body": {
"orderId": "@triggerBody()?['orderId']",
"items": "@triggerBody()?['items']"
}
}
}
}
}
}
Best Practices
Configuration Checklist
| Practice | Description |
|---|---|
| Use Managed Identity | Configure connection with managed identity |
| Use Peek Lock | Enable reliable message processing |
| Set appropriate lock duration | Allow time for processing + retries |
| Implement error handling | Dead-letter failed messages |
| Use sessions for ordering | When message ordering matters |
Performance Optimization
{
"triggers": {
"optimized_trigger": {
"type": "ServiceBusTrigger",
"inputs": {
"queueName": "high-volume-queue",
"maxMessageCount": 50,
"recurrence": {
"frequency": "Second",
"interval": 1
}
}
}
}
}
Related Topics
- Service Bus Queues — Queue fundamentals
- Service Bus Topics — Pub/sub patterns
- Dead Letter Queues — Handling failed messages
- Managed Identity — Secure authentication
Azure Integration Hub - Intermediate Level