Configure Azure IoT Operations Broker Listeners

The azure-native:iotoperations:BrokerListener resource, part of the Pulumi Azure Native provider, defines network listeners for Azure IoT Operations MQTT brokers: their ports, protocols, TLS configuration, and Kubernetes service exposure. This guide focuses on three capabilities: port and protocol configuration, TLS certificate management (automatic with cert-manager and manual), and multi-port listener setup.

Listeners belong to an IoT Operations broker instance and reference authentication resources, cert-manager issuers, and Kubernetes secrets. The examples are intentionally small. Combine them with your own broker instances, authentication policies, and certificate infrastructure.

Expose MQTT on the default port

Most IoT deployments start with a basic MQTT listener on port 1883, providing a minimal entry point for device connections.

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

const brokerListener = new azure_native.iotoperations.BrokerListener("brokerListener", {
    brokerName: "resource-name123",
    extendedLocation: {
        name: "qmbrfwcpwwhggszhrdjv",
        type: azure_native.iotoperations.ExtendedLocationType.CustomLocation,
    },
    instanceName: "resource-name123",
    listenerName: "resource-name123",
    properties: {
        ports: [{
            port: 1883,
        }],
    },
    resourceGroupName: "rgiotoperations",
});
import pulumi
import pulumi_azure_native as azure_native

broker_listener = azure_native.iotoperations.BrokerListener("brokerListener",
    broker_name="resource-name123",
    extended_location={
        "name": "qmbrfwcpwwhggszhrdjv",
        "type": azure_native.iotoperations.ExtendedLocationType.CUSTOM_LOCATION,
    },
    instance_name="resource-name123",
    listener_name="resource-name123",
    properties={
        "ports": [{
            "port": 1883,
        }],
    },
    resource_group_name="rgiotoperations")
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := iotoperations.NewBrokerListener(ctx, "brokerListener", &iotoperations.BrokerListenerArgs{
			BrokerName: pulumi.String("resource-name123"),
			ExtendedLocation: &iotoperations.ExtendedLocationArgs{
				Name: pulumi.String("qmbrfwcpwwhggszhrdjv"),
				Type: pulumi.String(iotoperations.ExtendedLocationTypeCustomLocation),
			},
			InstanceName: pulumi.String("resource-name123"),
			ListenerName: pulumi.String("resource-name123"),
			Properties: &iotoperations.BrokerListenerPropertiesArgs{
				Ports: iotoperations.ListenerPortArray{
					&iotoperations.ListenerPortArgs{
						Port: pulumi.Int(1883),
					},
				},
			},
			ResourceGroupName: pulumi.String("rgiotoperations"),
		})
		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 brokerListener = new AzureNative.IoTOperations.BrokerListener("brokerListener", new()
    {
        BrokerName = "resource-name123",
        ExtendedLocation = new AzureNative.IoTOperations.Inputs.ExtendedLocationArgs
        {
            Name = "qmbrfwcpwwhggszhrdjv",
            Type = AzureNative.IoTOperations.ExtendedLocationType.CustomLocation,
        },
        InstanceName = "resource-name123",
        ListenerName = "resource-name123",
        Properties = new AzureNative.IoTOperations.Inputs.BrokerListenerPropertiesArgs
        {
            Ports = new[]
            {
                new AzureNative.IoTOperations.Inputs.ListenerPortArgs
                {
                    Port = 1883,
                },
            },
        },
        ResourceGroupName = "rgiotoperations",
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.iotoperations.BrokerListener;
import com.pulumi.azurenative.iotoperations.BrokerListenerArgs;
import com.pulumi.azurenative.iotoperations.inputs.ExtendedLocationArgs;
import com.pulumi.azurenative.iotoperations.inputs.BrokerListenerPropertiesArgs;
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 brokerListener = new BrokerListener("brokerListener", BrokerListenerArgs.builder()
            .brokerName("resource-name123")
            .extendedLocation(ExtendedLocationArgs.builder()
                .name("qmbrfwcpwwhggszhrdjv")
                .type("CustomLocation")
                .build())
            .instanceName("resource-name123")
            .listenerName("resource-name123")
            .properties(BrokerListenerPropertiesArgs.builder()
                .ports(ListenerPortArgs.builder()
                    .port(1883)
                    .build())
                .build())
            .resourceGroupName("rgiotoperations")
            .build());

    }
}
resources:
  brokerListener:
    type: azure-native:iotoperations:BrokerListener
    properties:
      brokerName: resource-name123
      extendedLocation:
        name: qmbrfwcpwwhggszhrdjv
        type: CustomLocation
      instanceName: resource-name123
      listenerName: resource-name123
      properties:
        ports:
          - port: 1883
      resourceGroupName: rgiotoperations

The ports array defines which ports the listener exposes. Each port entry specifies the port number; protocol defaults to MQTT when omitted. The extendedLocation ties the listener to an Azure Arc custom location, while brokerName and instanceName reference the parent broker resource.

Configure multiple ports with TLS variants

Production deployments typically expose multiple protocols and ports, mixing encrypted and unencrypted endpoints for different client capabilities.

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

const brokerListener = new azure_native.iotoperations.BrokerListener("brokerListener", {
    brokerName: "resource-name123",
    extendedLocation: {
        name: "qmbrfwcpwwhggszhrdjv",
        type: azure_native.iotoperations.ExtendedLocationType.CustomLocation,
    },
    instanceName: "resource-name123",
    listenerName: "resource-name123",
    properties: {
        ports: [
            {
                authenticationRef: "example-authentication",
                port: 8080,
                protocol: azure_native.iotoperations.BrokerProtocolType.WebSockets,
            },
            {
                authenticationRef: "example-authentication",
                port: 8443,
                protocol: azure_native.iotoperations.BrokerProtocolType.WebSockets,
                tls: {
                    certManagerCertificateSpec: {
                        issuerRef: {
                            group: "jtmuladdkpasfpoyvewekmiy",
                            kind: azure_native.iotoperations.CertManagerIssuerKind.Issuer,
                            name: "example-issuer",
                        },
                    },
                    mode: azure_native.iotoperations.TlsCertMethodMode.Automatic,
                },
            },
            {
                authenticationRef: "example-authentication",
                port: 1883,
            },
            {
                authenticationRef: "example-authentication",
                port: 8883,
                tls: {
                    manual: {
                        secretRef: "example-secret",
                    },
                    mode: azure_native.iotoperations.TlsCertMethodMode.Manual,
                },
            },
        ],
        serviceType: azure_native.iotoperations.ServiceType.LoadBalancer,
    },
    resourceGroupName: "rgiotoperations",
});
import pulumi
import pulumi_azure_native as azure_native

broker_listener = azure_native.iotoperations.BrokerListener("brokerListener",
    broker_name="resource-name123",
    extended_location={
        "name": "qmbrfwcpwwhggszhrdjv",
        "type": azure_native.iotoperations.ExtendedLocationType.CUSTOM_LOCATION,
    },
    instance_name="resource-name123",
    listener_name="resource-name123",
    properties={
        "ports": [
            {
                "authentication_ref": "example-authentication",
                "port": 8080,
                "protocol": azure_native.iotoperations.BrokerProtocolType.WEB_SOCKETS,
            },
            {
                "authentication_ref": "example-authentication",
                "port": 8443,
                "protocol": azure_native.iotoperations.BrokerProtocolType.WEB_SOCKETS,
                "tls": {
                    "cert_manager_certificate_spec": {
                        "issuer_ref": {
                            "group": "jtmuladdkpasfpoyvewekmiy",
                            "kind": azure_native.iotoperations.CertManagerIssuerKind.ISSUER,
                            "name": "example-issuer",
                        },
                    },
                    "mode": azure_native.iotoperations.TlsCertMethodMode.AUTOMATIC,
                },
            },
            {
                "authentication_ref": "example-authentication",
                "port": 1883,
            },
            {
                "authentication_ref": "example-authentication",
                "port": 8883,
                "tls": {
                    "manual": {
                        "secret_ref": "example-secret",
                    },
                    "mode": azure_native.iotoperations.TlsCertMethodMode.MANUAL,
                },
            },
        ],
        "service_type": azure_native.iotoperations.ServiceType.LOAD_BALANCER,
    },
    resource_group_name="rgiotoperations")
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := iotoperations.NewBrokerListener(ctx, "brokerListener", &iotoperations.BrokerListenerArgs{
			BrokerName: pulumi.String("resource-name123"),
			ExtendedLocation: &iotoperations.ExtendedLocationArgs{
				Name: pulumi.String("qmbrfwcpwwhggszhrdjv"),
				Type: pulumi.String(iotoperations.ExtendedLocationTypeCustomLocation),
			},
			InstanceName: pulumi.String("resource-name123"),
			ListenerName: pulumi.String("resource-name123"),
			Properties: &iotoperations.BrokerListenerPropertiesArgs{
				Ports: iotoperations.ListenerPortArray{
					&iotoperations.ListenerPortArgs{
						AuthenticationRef: pulumi.String("example-authentication"),
						Port:              pulumi.Int(8080),
						Protocol:          pulumi.String(iotoperations.BrokerProtocolTypeWebSockets),
					},
					&iotoperations.ListenerPortArgs{
						AuthenticationRef: pulumi.String("example-authentication"),
						Port:              pulumi.Int(8443),
						Protocol:          pulumi.String(iotoperations.BrokerProtocolTypeWebSockets),
						Tls: &iotoperations.TlsCertMethodArgs{
							CertManagerCertificateSpec: &iotoperations.CertManagerCertificateSpecArgs{
								IssuerRef: &iotoperations.CertManagerIssuerRefArgs{
									Group: pulumi.String("jtmuladdkpasfpoyvewekmiy"),
									Kind:  pulumi.String(iotoperations.CertManagerIssuerKindIssuer),
									Name:  pulumi.String("example-issuer"),
								},
							},
							Mode: pulumi.String(iotoperations.TlsCertMethodModeAutomatic),
						},
					},
					&iotoperations.ListenerPortArgs{
						AuthenticationRef: pulumi.String("example-authentication"),
						Port:              pulumi.Int(1883),
					},
					&iotoperations.ListenerPortArgs{
						AuthenticationRef: pulumi.String("example-authentication"),
						Port:              pulumi.Int(8883),
						Tls: &iotoperations.TlsCertMethodArgs{
							Manual: &iotoperations.X509ManualCertificateArgs{
								SecretRef: pulumi.String("example-secret"),
							},
							Mode: pulumi.String(iotoperations.TlsCertMethodModeManual),
						},
					},
				},
				ServiceType: pulumi.String(iotoperations.ServiceTypeLoadBalancer),
			},
			ResourceGroupName: pulumi.String("rgiotoperations"),
		})
		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 brokerListener = new AzureNative.IoTOperations.BrokerListener("brokerListener", new()
    {
        BrokerName = "resource-name123",
        ExtendedLocation = new AzureNative.IoTOperations.Inputs.ExtendedLocationArgs
        {
            Name = "qmbrfwcpwwhggszhrdjv",
            Type = AzureNative.IoTOperations.ExtendedLocationType.CustomLocation,
        },
        InstanceName = "resource-name123",
        ListenerName = "resource-name123",
        Properties = new AzureNative.IoTOperations.Inputs.BrokerListenerPropertiesArgs
        {
            Ports = new[]
            {
                new AzureNative.IoTOperations.Inputs.ListenerPortArgs
                {
                    AuthenticationRef = "example-authentication",
                    Port = 8080,
                    Protocol = AzureNative.IoTOperations.BrokerProtocolType.WebSockets,
                },
                new AzureNative.IoTOperations.Inputs.ListenerPortArgs
                {
                    AuthenticationRef = "example-authentication",
                    Port = 8443,
                    Protocol = AzureNative.IoTOperations.BrokerProtocolType.WebSockets,
                    Tls = new AzureNative.IoTOperations.Inputs.TlsCertMethodArgs
                    {
                        CertManagerCertificateSpec = new AzureNative.IoTOperations.Inputs.CertManagerCertificateSpecArgs
                        {
                            IssuerRef = new AzureNative.IoTOperations.Inputs.CertManagerIssuerRefArgs
                            {
                                Group = "jtmuladdkpasfpoyvewekmiy",
                                Kind = AzureNative.IoTOperations.CertManagerIssuerKind.Issuer,
                                Name = "example-issuer",
                            },
                        },
                        Mode = AzureNative.IoTOperations.TlsCertMethodMode.Automatic,
                    },
                },
                new AzureNative.IoTOperations.Inputs.ListenerPortArgs
                {
                    AuthenticationRef = "example-authentication",
                    Port = 1883,
                },
                new AzureNative.IoTOperations.Inputs.ListenerPortArgs
                {
                    AuthenticationRef = "example-authentication",
                    Port = 8883,
                    Tls = new AzureNative.IoTOperations.Inputs.TlsCertMethodArgs
                    {
                        Manual = new AzureNative.IoTOperations.Inputs.X509ManualCertificateArgs
                        {
                            SecretRef = "example-secret",
                        },
                        Mode = AzureNative.IoTOperations.TlsCertMethodMode.Manual,
                    },
                },
            },
            ServiceType = AzureNative.IoTOperations.ServiceType.LoadBalancer,
        },
        ResourceGroupName = "rgiotoperations",
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.iotoperations.BrokerListener;
import com.pulumi.azurenative.iotoperations.BrokerListenerArgs;
import com.pulumi.azurenative.iotoperations.inputs.ExtendedLocationArgs;
import com.pulumi.azurenative.iotoperations.inputs.BrokerListenerPropertiesArgs;
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 brokerListener = new BrokerListener("brokerListener", BrokerListenerArgs.builder()
            .brokerName("resource-name123")
            .extendedLocation(ExtendedLocationArgs.builder()
                .name("qmbrfwcpwwhggszhrdjv")
                .type("CustomLocation")
                .build())
            .instanceName("resource-name123")
            .listenerName("resource-name123")
            .properties(BrokerListenerPropertiesArgs.builder()
                .ports(                
                    ListenerPortArgs.builder()
                        .authenticationRef("example-authentication")
                        .port(8080)
                        .protocol("WebSockets")
                        .build(),
                    ListenerPortArgs.builder()
                        .authenticationRef("example-authentication")
                        .port(8443)
                        .protocol("WebSockets")
                        .tls(TlsCertMethodArgs.builder()
                            .certManagerCertificateSpec(CertManagerCertificateSpecArgs.builder()
                                .issuerRef(CertManagerIssuerRefArgs.builder()
                                    .group("jtmuladdkpasfpoyvewekmiy")
                                    .kind("Issuer")
                                    .name("example-issuer")
                                    .build())
                                .build())
                            .mode("Automatic")
                            .build())
                        .build(),
                    ListenerPortArgs.builder()
                        .authenticationRef("example-authentication")
                        .port(1883)
                        .build(),
                    ListenerPortArgs.builder()
                        .authenticationRef("example-authentication")
                        .port(8883)
                        .tls(TlsCertMethodArgs.builder()
                            .manual(X509ManualCertificateArgs.builder()
                                .secretRef("example-secret")
                                .build())
                            .mode("Manual")
                            .build())
                        .build())
                .serviceType("LoadBalancer")
                .build())
            .resourceGroupName("rgiotoperations")
            .build());

    }
}
resources:
  brokerListener:
    type: azure-native:iotoperations:BrokerListener
    properties:
      brokerName: resource-name123
      extendedLocation:
        name: qmbrfwcpwwhggszhrdjv
        type: CustomLocation
      instanceName: resource-name123
      listenerName: resource-name123
      properties:
        ports:
          - authenticationRef: example-authentication
            port: 8080
            protocol: WebSockets
          - authenticationRef: example-authentication
            port: 8443
            protocol: WebSockets
            tls:
              certManagerCertificateSpec:
                issuerRef:
                  group: jtmuladdkpasfpoyvewekmiy
                  kind: Issuer
                  name: example-issuer
              mode: Automatic
          - authenticationRef: example-authentication
            port: 1883
          - authenticationRef: example-authentication
            port: 8883
            tls:
              manual:
                secretRef: example-secret
              mode: Manual
        serviceType: LoadBalancer
      resourceGroupName: rgiotoperations

Each port in the ports array can specify a different protocol (MQTT or WebSockets) and optional TLS configuration. The tls property controls encryption: mode determines whether certificates are managed automatically via cert-manager or manually via Kubernetes secrets. The authenticationRef links each port to an authentication policy. The serviceType property controls Kubernetes service exposure; LoadBalancer makes the listener accessible outside the cluster.

Configure automatic TLS with cert-manager

When cert-manager is available in the cluster, listeners can automatically provision and rotate TLS certificates using issuer references.

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

const brokerListener = new azure_native.iotoperations.BrokerListener("brokerListener", {
    brokerName: "resource-name123",
    extendedLocation: {
        name: "qmbrfwcpwwhggszhrdjv",
        type: azure_native.iotoperations.ExtendedLocationType.CustomLocation,
    },
    instanceName: "resource-name123",
    listenerName: "resource-name123",
    properties: {
        ports: [{
            authenticationRef: "tjvdroaqqy",
            authorizationRef: "inxhvxnwswyrvt",
            nodePort: 7281,
            port: 1268,
            protocol: azure_native.iotoperations.BrokerProtocolType.Mqtt,
            tls: {
                certManagerCertificateSpec: {
                    duration: "qmpeffoksron",
                    issuerRef: {
                        group: "jtmuladdkpasfpoyvewekmiy",
                        kind: azure_native.iotoperations.CertManagerIssuerKind.Issuer,
                        name: "ocwoqpgucvjrsuudtjhb",
                    },
                    privateKey: {
                        algorithm: azure_native.iotoperations.PrivateKeyAlgorithm.Ec256,
                        rotationPolicy: azure_native.iotoperations.PrivateKeyRotationPolicy.Always,
                    },
                    renewBefore: "hutno",
                    san: {
                        dns: ["xhvmhrrhgfsapocjeebqtnzarlj"],
                        ip: ["zbgugfzcgsmegevzktsnibyuyp"],
                    },
                    secretName: "oagi",
                },
                manual: {
                    secretRef: "secret-name",
                },
                mode: azure_native.iotoperations.TlsCertMethodMode.Automatic,
            },
        }],
        serviceName: "tpfiszlapdpxktx",
        serviceType: azure_native.iotoperations.ServiceType.ClusterIp,
    },
    resourceGroupName: "rgiotoperations",
});
import pulumi
import pulumi_azure_native as azure_native

broker_listener = azure_native.iotoperations.BrokerListener("brokerListener",
    broker_name="resource-name123",
    extended_location={
        "name": "qmbrfwcpwwhggszhrdjv",
        "type": azure_native.iotoperations.ExtendedLocationType.CUSTOM_LOCATION,
    },
    instance_name="resource-name123",
    listener_name="resource-name123",
    properties={
        "ports": [{
            "authentication_ref": "tjvdroaqqy",
            "authorization_ref": "inxhvxnwswyrvt",
            "node_port": 7281,
            "port": 1268,
            "protocol": azure_native.iotoperations.BrokerProtocolType.MQTT,
            "tls": {
                "cert_manager_certificate_spec": {
                    "duration": "qmpeffoksron",
                    "issuer_ref": {
                        "group": "jtmuladdkpasfpoyvewekmiy",
                        "kind": azure_native.iotoperations.CertManagerIssuerKind.ISSUER,
                        "name": "ocwoqpgucvjrsuudtjhb",
                    },
                    "private_key": {
                        "algorithm": azure_native.iotoperations.PrivateKeyAlgorithm.EC256,
                        "rotation_policy": azure_native.iotoperations.PrivateKeyRotationPolicy.ALWAYS,
                    },
                    "renew_before": "hutno",
                    "san": {
                        "dns": ["xhvmhrrhgfsapocjeebqtnzarlj"],
                        "ip": ["zbgugfzcgsmegevzktsnibyuyp"],
                    },
                    "secret_name": "oagi",
                },
                "manual": {
                    "secret_ref": "secret-name",
                },
                "mode": azure_native.iotoperations.TlsCertMethodMode.AUTOMATIC,
            },
        }],
        "service_name": "tpfiszlapdpxktx",
        "service_type": azure_native.iotoperations.ServiceType.CLUSTER_IP,
    },
    resource_group_name="rgiotoperations")
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := iotoperations.NewBrokerListener(ctx, "brokerListener", &iotoperations.BrokerListenerArgs{
			BrokerName: pulumi.String("resource-name123"),
			ExtendedLocation: &iotoperations.ExtendedLocationArgs{
				Name: pulumi.String("qmbrfwcpwwhggszhrdjv"),
				Type: pulumi.String(iotoperations.ExtendedLocationTypeCustomLocation),
			},
			InstanceName: pulumi.String("resource-name123"),
			ListenerName: pulumi.String("resource-name123"),
			Properties: &iotoperations.BrokerListenerPropertiesArgs{
				Ports: iotoperations.ListenerPortArray{
					&iotoperations.ListenerPortArgs{
						AuthenticationRef: pulumi.String("tjvdroaqqy"),
						AuthorizationRef:  pulumi.String("inxhvxnwswyrvt"),
						NodePort:          pulumi.Int(7281),
						Port:              pulumi.Int(1268),
						Protocol:          pulumi.String(iotoperations.BrokerProtocolTypeMqtt),
						Tls: &iotoperations.TlsCertMethodArgs{
							CertManagerCertificateSpec: &iotoperations.CertManagerCertificateSpecArgs{
								Duration: pulumi.String("qmpeffoksron"),
								IssuerRef: &iotoperations.CertManagerIssuerRefArgs{
									Group: pulumi.String("jtmuladdkpasfpoyvewekmiy"),
									Kind:  pulumi.String(iotoperations.CertManagerIssuerKindIssuer),
									Name:  pulumi.String("ocwoqpgucvjrsuudtjhb"),
								},
								PrivateKey: &iotoperations.CertManagerPrivateKeyArgs{
									Algorithm:      pulumi.String(iotoperations.PrivateKeyAlgorithmEc256),
									RotationPolicy: pulumi.String(iotoperations.PrivateKeyRotationPolicyAlways),
								},
								RenewBefore: pulumi.String("hutno"),
								San: &iotoperations.SanForCertArgs{
									Dns: pulumi.StringArray{
										pulumi.String("xhvmhrrhgfsapocjeebqtnzarlj"),
									},
									Ip: pulumi.StringArray{
										pulumi.String("zbgugfzcgsmegevzktsnibyuyp"),
									},
								},
								SecretName: pulumi.String("oagi"),
							},
							Manual: &iotoperations.X509ManualCertificateArgs{
								SecretRef: pulumi.String("secret-name"),
							},
							Mode: pulumi.String(iotoperations.TlsCertMethodModeAutomatic),
						},
					},
				},
				ServiceName: pulumi.String("tpfiszlapdpxktx"),
				ServiceType: pulumi.String(iotoperations.ServiceTypeClusterIp),
			},
			ResourceGroupName: pulumi.String("rgiotoperations"),
		})
		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 brokerListener = new AzureNative.IoTOperations.BrokerListener("brokerListener", new()
    {
        BrokerName = "resource-name123",
        ExtendedLocation = new AzureNative.IoTOperations.Inputs.ExtendedLocationArgs
        {
            Name = "qmbrfwcpwwhggszhrdjv",
            Type = AzureNative.IoTOperations.ExtendedLocationType.CustomLocation,
        },
        InstanceName = "resource-name123",
        ListenerName = "resource-name123",
        Properties = new AzureNative.IoTOperations.Inputs.BrokerListenerPropertiesArgs
        {
            Ports = new[]
            {
                new AzureNative.IoTOperations.Inputs.ListenerPortArgs
                {
                    AuthenticationRef = "tjvdroaqqy",
                    AuthorizationRef = "inxhvxnwswyrvt",
                    NodePort = 7281,
                    Port = 1268,
                    Protocol = AzureNative.IoTOperations.BrokerProtocolType.Mqtt,
                    Tls = new AzureNative.IoTOperations.Inputs.TlsCertMethodArgs
                    {
                        CertManagerCertificateSpec = new AzureNative.IoTOperations.Inputs.CertManagerCertificateSpecArgs
                        {
                            Duration = "qmpeffoksron",
                            IssuerRef = new AzureNative.IoTOperations.Inputs.CertManagerIssuerRefArgs
                            {
                                Group = "jtmuladdkpasfpoyvewekmiy",
                                Kind = AzureNative.IoTOperations.CertManagerIssuerKind.Issuer,
                                Name = "ocwoqpgucvjrsuudtjhb",
                            },
                            PrivateKey = new AzureNative.IoTOperations.Inputs.CertManagerPrivateKeyArgs
                            {
                                Algorithm = AzureNative.IoTOperations.PrivateKeyAlgorithm.Ec256,
                                RotationPolicy = AzureNative.IoTOperations.PrivateKeyRotationPolicy.Always,
                            },
                            RenewBefore = "hutno",
                            San = new AzureNative.IoTOperations.Inputs.SanForCertArgs
                            {
                                Dns = new[]
                                {
                                    "xhvmhrrhgfsapocjeebqtnzarlj",
                                },
                                Ip = new[]
                                {
                                    "zbgugfzcgsmegevzktsnibyuyp",
                                },
                            },
                            SecretName = "oagi",
                        },
                        Manual = new AzureNative.IoTOperations.Inputs.X509ManualCertificateArgs
                        {
                            SecretRef = "secret-name",
                        },
                        Mode = AzureNative.IoTOperations.TlsCertMethodMode.Automatic,
                    },
                },
            },
            ServiceName = "tpfiszlapdpxktx",
            ServiceType = AzureNative.IoTOperations.ServiceType.ClusterIp,
        },
        ResourceGroupName = "rgiotoperations",
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.iotoperations.BrokerListener;
import com.pulumi.azurenative.iotoperations.BrokerListenerArgs;
import com.pulumi.azurenative.iotoperations.inputs.ExtendedLocationArgs;
import com.pulumi.azurenative.iotoperations.inputs.BrokerListenerPropertiesArgs;
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 brokerListener = new BrokerListener("brokerListener", BrokerListenerArgs.builder()
            .brokerName("resource-name123")
            .extendedLocation(ExtendedLocationArgs.builder()
                .name("qmbrfwcpwwhggszhrdjv")
                .type("CustomLocation")
                .build())
            .instanceName("resource-name123")
            .listenerName("resource-name123")
            .properties(BrokerListenerPropertiesArgs.builder()
                .ports(ListenerPortArgs.builder()
                    .authenticationRef("tjvdroaqqy")
                    .authorizationRef("inxhvxnwswyrvt")
                    .nodePort(7281)
                    .port(1268)
                    .protocol("Mqtt")
                    .tls(TlsCertMethodArgs.builder()
                        .certManagerCertificateSpec(CertManagerCertificateSpecArgs.builder()
                            .duration("qmpeffoksron")
                            .issuerRef(CertManagerIssuerRefArgs.builder()
                                .group("jtmuladdkpasfpoyvewekmiy")
                                .kind("Issuer")
                                .name("ocwoqpgucvjrsuudtjhb")
                                .build())
                            .privateKey(CertManagerPrivateKeyArgs.builder()
                                .algorithm("Ec256")
                                .rotationPolicy("Always")
                                .build())
                            .renewBefore("hutno")
                            .san(SanForCertArgs.builder()
                                .dns("xhvmhrrhgfsapocjeebqtnzarlj")
                                .ip("zbgugfzcgsmegevzktsnibyuyp")
                                .build())
                            .secretName("oagi")
                            .build())
                        .manual(X509ManualCertificateArgs.builder()
                            .secretRef("secret-name")
                            .build())
                        .mode("Automatic")
                        .build())
                    .build())
                .serviceName("tpfiszlapdpxktx")
                .serviceType("ClusterIp")
                .build())
            .resourceGroupName("rgiotoperations")
            .build());

    }
}
resources:
  brokerListener:
    type: azure-native:iotoperations:BrokerListener
    properties:
      brokerName: resource-name123
      extendedLocation:
        name: qmbrfwcpwwhggszhrdjv
        type: CustomLocation
      instanceName: resource-name123
      listenerName: resource-name123
      properties:
        ports:
          - authenticationRef: tjvdroaqqy
            authorizationRef: inxhvxnwswyrvt
            nodePort: 7281
            port: 1268
            protocol: Mqtt
            tls:
              certManagerCertificateSpec:
                duration: qmpeffoksron
                issuerRef:
                  group: jtmuladdkpasfpoyvewekmiy
                  kind: Issuer
                  name: ocwoqpgucvjrsuudtjhb
                privateKey:
                  algorithm: Ec256
                  rotationPolicy: Always
                renewBefore: hutno
                san:
                  dns:
                    - xhvmhrrhgfsapocjeebqtnzarlj
                  ip:
                    - zbgugfzcgsmegevzktsnibyuyp
                secretName: oagi
              manual:
                secretRef: secret-name
              mode: Automatic
        serviceName: tpfiszlapdpxktx
        serviceType: ClusterIp
      resourceGroupName: rgiotoperations

The certManagerCertificateSpec block defines how cert-manager generates certificates. The issuerRef points to a cert-manager issuer resource by name and kind. The privateKey section controls key algorithm and rotation behavior. The san (Subject Alternative Name) block specifies DNS names and IP addresses for the certificate. Setting mode to Automatic tells the listener to use cert-manager; Manual mode uses a pre-existing Kubernetes secret instead.

Beyond these examples

These snippets focus on specific listener-level features: port and protocol configuration, TLS certificate management (automatic and manual), and Kubernetes service exposure. They’re intentionally minimal rather than full IoT broker deployments.

The examples reference pre-existing infrastructure such as Azure IoT Operations broker and instance resources, Azure Arc custom location, authentication and authorization resources, and cert-manager issuers and Kubernetes secrets (for TLS examples). They focus on configuring the listener rather than provisioning the entire IoT Operations stack.

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

  • Authorization policies (authorizationRef)
  • NodePort configuration for direct node access
  • Service naming and custom DNS
  • Certificate renewal and rotation policies

These omissions are intentional: the goal is to illustrate how each listener feature is wired, not provide drop-in IoT broker modules. See the BrokerListener resource reference for all available configuration options.

Let's configure Azure IoT Operations Broker Listeners

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

Try Pulumi Cloud for FREE

Frequently Asked Questions

Resource Configuration & Immutability
What properties can't I change after creating a broker listener?
The following properties are immutable and require resource replacement to change: extendedLocation, brokerName, instanceName, listenerName, and resourceGroupName. Plan your naming and location carefully during initial creation.
What's the minimal configuration needed for a broker listener?
You need brokerName, instanceName, listenerName, resourceGroupName, extendedLocation (with name and type), and at least one port in the properties.ports array. The simple example shows a minimal setup with just port 1883.
TLS & Security Configuration
How do I configure TLS for my broker listener?

Configure the tls property on each port with one of two modes:

  1. Automatic mode - Use certManagerCertificateSpec with an issuerRef for cert-manager integration
  2. Manual mode - Use manual with a secretRef pointing to an existing Kubernetes secret
What's the difference between Automatic and Manual TLS modes?
Automatic mode uses cert-manager to generate and manage certificates, requiring an issuerRef configuration. Manual mode uses pre-existing certificates stored in Kubernetes secrets via secretRef. Choose Automatic for dynamic certificate management or Manual for existing certificates.
How do I configure authentication and authorization for ports?
Use authenticationRef and authorizationRef properties on each port to reference existing authentication and authorization resources. The complex example shows authenticationRef: "example-authentication" on all ports.
Ports & Protocols
Can I configure multiple ports on a single broker listener?
Yes, the ports property accepts an array of port configurations. You can define multiple ports with different protocols and TLS settings. The complex example demonstrates four ports (8080, 8443, 1883, 8883) with varying configurations.
What protocols are supported for broker listeners?
Two protocols are available: Mqtt and WebSockets. The examples show standard MQTT ports (1883, 8883) and WebSocket ports (8080, 8443).
What's the difference between port and nodePort?
The port property specifies the service port, while nodePort (optional) specifies the node port for NodePort or LoadBalancer service types. The basic example shows port: 1268 with nodePort: 7281.
Service Configuration
When should I use ClusterIp vs LoadBalancer service type?
Use ClusterIp for internal cluster access only, or LoadBalancer for external access. The simple and basic examples use ClusterIp, while the complex example uses LoadBalancer for external connectivity.
How do I specify a custom service name for my listener?
Use the serviceName property in the listener properties. The basic example shows serviceName: "tpfiszlapdpxktx".
API Versions & Compatibility
What API versions are available for BrokerListener?
Multiple API versions are available: 2024-07-01-preview, 2024-08-15-preview, 2024-09-15-preview, 2024-11-01 (default), 2025-04-01, 2025-07-01-preview, 2025-10-01, and 2026-03-01. Access non-default versions using the CLI command pulumi package add azure-native iotoperations [ApiVersion].

Using a different cloud?

Explore messaging guides for other cloud providers: