Configure Azure Service Bus Rules

The azure-native:servicebus:Rule resource, part of the Pulumi Azure Native provider, defines filtering rules that control which messages a Service Bus subscription receives from its parent topic. This guide focuses on two capabilities: correlation filters for property-based routing and SQL filters for expression-based routing.

Rules belong to a subscription within a topic. The namespace, topic, and subscription must exist before creating rules. The examples are intentionally small. Combine them with your own Service Bus infrastructure and message publishing logic.

Filter messages by custom properties

Service Bus subscriptions often route messages based on application-specific metadata rather than message content. Correlation filters match against message properties without parsing the body.

import * as pulumi from "@pulumi/pulumi";
import * as azure_native from "@pulumi/azure-native";

const rule = new azure_native.servicebus.Rule("rule", {
    correlationFilter: {
        properties: {
            topicHint: "Crop",
        },
    },
    filterType: azure_native.servicebus.FilterType.CorrelationFilter,
    namespaceName: "sdk-Namespace-1319",
    resourceGroupName: "resourceGroupName",
    ruleName: "sdk-Rules-6571",
    subscriptionName: "sdk-Subscriptions-8691",
    topicName: "sdk-Topics-2081",
});
import pulumi
import pulumi_azure_native as azure_native

rule = azure_native.servicebus.Rule("rule",
    correlation_filter={
        "properties": {
            "topicHint": "Crop",
        },
    },
    filter_type=azure_native.servicebus.FilterType.CORRELATION_FILTER,
    namespace_name="sdk-Namespace-1319",
    resource_group_name="resourceGroupName",
    rule_name="sdk-Rules-6571",
    subscription_name="sdk-Subscriptions-8691",
    topic_name="sdk-Topics-2081")
package main

import (
	servicebus "github.com/pulumi/pulumi-azure-native-sdk/servicebus/v3"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := servicebus.NewRule(ctx, "rule", &servicebus.RuleArgs{
			CorrelationFilter: &servicebus.CorrelationFilterArgs{
				Properties: pulumi.StringMap{
					"topicHint": pulumi.String("Crop"),
				},
			},
			FilterType:        servicebus.FilterTypeCorrelationFilter,
			NamespaceName:     pulumi.String("sdk-Namespace-1319"),
			ResourceGroupName: pulumi.String("resourceGroupName"),
			RuleName:          pulumi.String("sdk-Rules-6571"),
			SubscriptionName:  pulumi.String("sdk-Subscriptions-8691"),
			TopicName:         pulumi.String("sdk-Topics-2081"),
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using AzureNative = Pulumi.AzureNative;

return await Deployment.RunAsync(() => 
{
    var rule = new AzureNative.ServiceBus.Rule("rule", new()
    {
        CorrelationFilter = new AzureNative.ServiceBus.Inputs.CorrelationFilterArgs
        {
            Properties = 
            {
                { "topicHint", "Crop" },
            },
        },
        FilterType = AzureNative.ServiceBus.FilterType.CorrelationFilter,
        NamespaceName = "sdk-Namespace-1319",
        ResourceGroupName = "resourceGroupName",
        RuleName = "sdk-Rules-6571",
        SubscriptionName = "sdk-Subscriptions-8691",
        TopicName = "sdk-Topics-2081",
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.servicebus.Rule;
import com.pulumi.azurenative.servicebus.RuleArgs;
import com.pulumi.azurenative.servicebus.inputs.CorrelationFilterArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        var rule = new Rule("rule", RuleArgs.builder()
            .correlationFilter(CorrelationFilterArgs.builder()
                .properties(Map.of("topicHint", "Crop"))
                .build())
            .filterType("CorrelationFilter")
            .namespaceName("sdk-Namespace-1319")
            .resourceGroupName("resourceGroupName")
            .ruleName("sdk-Rules-6571")
            .subscriptionName("sdk-Subscriptions-8691")
            .topicName("sdk-Topics-2081")
            .build());

    }
}
resources:
  rule:
    type: azure-native:servicebus:Rule
    properties:
      correlationFilter:
        properties:
          topicHint: Crop
      filterType: CorrelationFilter
      namespaceName: sdk-Namespace-1319
      resourceGroupName: resourceGroupName
      ruleName: sdk-Rules-6571
      subscriptionName: sdk-Subscriptions-8691
      topicName: sdk-Topics-2081

The correlationFilter property defines key-value pairs to match against message properties. When a message arrives with a property named “topicHint” set to “Crop”, this rule allows it through to the subscription. The filterType must be set to CorrelationFilter to enable this matching behavior.

Filter messages with SQL-like expressions

Complex routing logic often requires evaluating message properties against conditions that go beyond simple equality checks. SQL filters support comparisons, logical operators, and pattern matching.

import * as pulumi from "@pulumi/pulumi";
import * as azure_native from "@pulumi/azure-native";

const rule = new azure_native.servicebus.Rule("rule", {
    filterType: azure_native.servicebus.FilterType.SqlFilter,
    namespaceName: "sdk-Namespace-1319",
    resourceGroupName: "resourceGroupName",
    ruleName: "sdk-Rules-6571",
    sqlFilter: {
        sqlExpression: "myproperty=test",
    },
    subscriptionName: "sdk-Subscriptions-8691",
    topicName: "sdk-Topics-2081",
});
import pulumi
import pulumi_azure_native as azure_native

rule = azure_native.servicebus.Rule("rule",
    filter_type=azure_native.servicebus.FilterType.SQL_FILTER,
    namespace_name="sdk-Namespace-1319",
    resource_group_name="resourceGroupName",
    rule_name="sdk-Rules-6571",
    sql_filter={
        "sql_expression": "myproperty=test",
    },
    subscription_name="sdk-Subscriptions-8691",
    topic_name="sdk-Topics-2081")
package main

import (
	servicebus "github.com/pulumi/pulumi-azure-native-sdk/servicebus/v3"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := servicebus.NewRule(ctx, "rule", &servicebus.RuleArgs{
			FilterType:        servicebus.FilterTypeSqlFilter,
			NamespaceName:     pulumi.String("sdk-Namespace-1319"),
			ResourceGroupName: pulumi.String("resourceGroupName"),
			RuleName:          pulumi.String("sdk-Rules-6571"),
			SqlFilter: &servicebus.SqlFilterArgs{
				SqlExpression: pulumi.String("myproperty=test"),
			},
			SubscriptionName: pulumi.String("sdk-Subscriptions-8691"),
			TopicName:        pulumi.String("sdk-Topics-2081"),
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using AzureNative = Pulumi.AzureNative;

return await Deployment.RunAsync(() => 
{
    var rule = new AzureNative.ServiceBus.Rule("rule", new()
    {
        FilterType = AzureNative.ServiceBus.FilterType.SqlFilter,
        NamespaceName = "sdk-Namespace-1319",
        ResourceGroupName = "resourceGroupName",
        RuleName = "sdk-Rules-6571",
        SqlFilter = new AzureNative.ServiceBus.Inputs.SqlFilterArgs
        {
            SqlExpression = "myproperty=test",
        },
        SubscriptionName = "sdk-Subscriptions-8691",
        TopicName = "sdk-Topics-2081",
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.servicebus.Rule;
import com.pulumi.azurenative.servicebus.RuleArgs;
import com.pulumi.azurenative.servicebus.inputs.SqlFilterArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        var rule = new Rule("rule", RuleArgs.builder()
            .filterType("SqlFilter")
            .namespaceName("sdk-Namespace-1319")
            .resourceGroupName("resourceGroupName")
            .ruleName("sdk-Rules-6571")
            .sqlFilter(SqlFilterArgs.builder()
                .sqlExpression("myproperty=test")
                .build())
            .subscriptionName("sdk-Subscriptions-8691")
            .topicName("sdk-Topics-2081")
            .build());

    }
}
resources:
  rule:
    type: azure-native:servicebus:Rule
    properties:
      filterType: SqlFilter
      namespaceName: sdk-Namespace-1319
      resourceGroupName: resourceGroupName
      ruleName: sdk-Rules-6571
      sqlFilter:
        sqlExpression: myproperty=test
      subscriptionName: sdk-Subscriptions-8691
      topicName: sdk-Topics-2081

The sqlFilter property accepts a SQL-like expression that evaluates against message properties. Here, the expression “myproperty=test” matches messages where the custom property “myproperty” equals “test”. The filterType must be SqlFilter to enable SQL expression evaluation.

Beyond these examples

These snippets focus on specific rule-level features: correlation-based filtering and SQL expression filtering. They’re intentionally minimal rather than full message routing solutions.

The examples reference pre-existing infrastructure such as Service Bus namespace, topic, and subscription. They focus on configuring the rule rather than provisioning the messaging infrastructure around it.

To keep things focused, common rule patterns are omitted, including:

  • Filter actions for message transformation (action property)
  • Default pass-through rules (RulesCreateOrUpdate example)
  • Complex SQL expressions with multiple conditions
  • Correlation filter matching on system properties (messageId, sessionId)

These omissions are intentional: the goal is to illustrate how each filtering mechanism is wired, not provide drop-in routing modules. See the Service Bus Rule resource reference for all available configuration options.

Let's configure Azure Service Bus Rules

Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.

Try Pulumi Cloud for FREE

Frequently Asked Questions

Filter Configuration
What types of filters can I use for Service Bus rules?
You can use two filter types: CorrelationFilter for property-based matching and SqlFilter for SQL expression-based matching. Specify the type using the filterType property.
What's the difference between CorrelationFilter and SqlFilter?
CorrelationFilter matches messages based on properties (like topicHint: "Crop"), while SqlFilter evaluates SQL expressions (like myproperty=test) against message properties.
How do I filter messages by custom properties?
Use correlationFilter with a properties map. For example, set properties: { topicHint: "Crop" } to match messages with that property value.
How do I create a SQL-based message filter?
Set filterType to SqlFilter and provide sqlFilter with a sqlExpression, such as "myproperty=test".
Can I use both correlation and SQL filters in the same rule?
No, each rule uses either correlationFilter or sqlFilter, not both. Choose the filter type that matches your filtering needs.
Resource Hierarchy & Immutability
Which properties can't I change after creating a rule?
Five properties are immutable: namespaceName, resourceGroupName, ruleName, subscriptionName, and topicName. Changing any of these requires replacing the resource.

Using a different cloud?

Explore messaging guides for other cloud providers: