Connect Azure IoT MQ Preview MQTT bridge cloud connector to other MQTT brokers
Important
Azure IoT Operations Preview – enabled by Azure Arc is currently in PREVIEW. You shouldn't use this preview software in production environments.
See the Supplemental Terms of Use for Microsoft Azure Previews for legal terms that apply to Azure features that are in beta, preview, or otherwise not yet released into general availability.
You can use the Azure IoT MQ Preview MQTT bridge to connect to Azure Event Grid or other MQTT brokers. MQTT bridging is the process of connecting two MQTT brokers together so that they can exchange messages.
- When two brokers are bridged, messages published on one broker are automatically forwarded to the other and vice versa.
- MQTT bridging helps to create a network of MQTT brokers that communicate with each other, and expand MQTT infrastructure by adding additional brokers as needed.
- MQTT bridging is useful for multiple physical locations, sharing MQTT messages and topics between edge and cloud, or when you want to integrate MQTT with other messaging systems.
To bridge to another broker, Azure IoT MQ must know the remote broker endpoint URL, what MQTT version, how to authenticate, and what topics to map. To maximize composability and flexibility in a Kubernetes-native fashion, these values are configured as custom Kubernetes resources (CRDs) called MqttBridgeConnector and MqttBridgeTopicMap. This guide walks through how to create the MQTT bridge connector using these resources.
Create a YAML file that defines MqttBridgeConnector resource. You can use the example YAML, but make sure to change the
namespace
to match the one that has Azure IoT MQ deployed, and theremoteBrokerConnection.endpoint
to match your remote broker endpoint URL.Create a YAML file that defines MqttBridgeTopicMap resource. You can use example YAML, but make sure to change the
namespace
to match the one that has Azure IoT MQ deployed, and themqttBridgeConnectorRef
to match the name of the MqttBridgeConnector resource you created in the earlier step.Deploy the MQTT bridge connector and topic map with
kubectl apply -f <filename>
.$ kubectl apply -f my-mqtt-bridge.yaml mqttbridgeconnectors.mq.iotoperations.azure.com my-mqtt-bridge created $ kubectl apply -f my-topic-map.yaml mqttbridgetopicmaps.mq.iotoperations.azure.com my-topic-map created
Once deployed, use kubectl get pods
to verify messages start flowing to and from your endpoint.
Configure MqttBridgeConnector
The MqttBridgeConnector resource defines the MQTT bridge connector that can communicate with a remote broker. It includes the following components:
- One or more MQTT bridge connector instances. Each instance is a container running the MQTT bridge connector.
- A remote broker connection.
- An optional local broker connection.
The following example shows an example configuration for bridging to an Azure Event Grid MQTT broker. It uses system-assigned managed identity for authentication and TLS encryption.
apiVersion: mq.iotoperations.azure.com/v1beta1
kind: MqttBridgeConnector
metadata:
name: my-mqtt-bridge
namespace: azure-iot-operations
spec:
image:
repository: mcr.microsoft.com/azureiotoperations/mqttbridge
tag: 0.4.0-preview
pullPolicy: IfNotPresent
protocol: v5
bridgeInstances: 1
clientIdPrefix: factory-gateway-
logLevel: debug
remoteBrokerConnection:
endpoint: example.westeurope-1.ts.eventgrid.azure.net:8883
tls:
tlsEnabled: true
authentication:
systemAssignedManagedIdentity:
audience: https://eventgrid.azure.net
localBrokerConnection:
endpoint: aio-mq-dmqtt-frontend:8883
tls:
tlsEnabled: true
trustedCaCertificateConfigMap: aio-ca-trust-bundle-test-only
authentication:
kubernetes: {}
The following table describes the fields in the MqttBridgeConnector resource:
Field | Required | Description |
---|---|---|
image | Yes | The image of the Kafka connector. You can specify the pullPolicy , repository , and tag of the image. Proper values are shown in the preceding example. |
protocol | Yes | MQTT protocol version. Can be v5 or v3 . See MQTT v3.1.1 support. |
bridgeInstances | No | Number of instances for the bridge connector. Default is 1. See Number of instances. |
clientIdPrefix | No | The prefix for the dynamically generated client ID. Default is no prefix. See Client ID configuration. |
logLevel | No | Log level. Can be debug or info . Default is info . |
remoteBrokerConnection | Yes | Connection details of the remote broker to bridge to. See Remote broker connection. |
localBrokerConnection | No | Connection details of the local broker to bridge to. Defaults to shown value. See Local broker connection. |
MQTT v3.1.1 support
The bridge connector can be configured to use MQTT v3.1.1 with both the local broker connection for Azure IoT MQ and remote broker connection. However, this breaks shared subscriptions if the remote broker doesn't support it. If you plan to use shared subscriptions, leave it as default v5.
Number of instances
For high availability and scale, configure the MQTT bridge connector to use multiple instances. Message flow and routes are automatically balanced between different instances.
spec:
bridgeInstances: 2
Client ID configuration
Azure IoT MQ generates a client ID for each MqttBridgeConnector client, using a prefix that you specify, in the format of {clientIdPrefix}-{routeName}
. This client ID is important for Azure IoT MQ to mitigate message loss and avoid conflicts or collisions with existing client IDs since MQTT specification allows only one connection per client ID.
For example, if clientIdPrefix: "client-"
, and there are two routes
in the topic map, the client IDs are: client-route1 and client-route2.
Remote broker connection
The remoteBrokerConnection
field defines the connection details to bridge to the remote broker. It includes the following fields:
Field | Required | Description |
---|---|---|
endpoint | Yes | Remote broker endpoint URL with port. For example, example.westeurope-1.ts.eventgrid.azure.net:8883 . |
tls | Yes | Specifies if connection is encrypted with TLS and trusted CA certificate. See TLS support |
authentication | Yes | Authentication details for Azure IoT MQ to use with the broker. Must be one of the following values: system-assigned managed identity or X.509. See Authentication. |
protocol | No | String value defining to use MQTT or MQTT over WebSockets. Can be mqtt or webSocket . Default is mqtt . |
Authentication
The authentication field defines the authentication method for Azure IoT MQ to use with the remote broker. It includes the following fields:
Field | Required | Description |
---|---|---|
systemAssignedManagedIdentity | No | Authenticate with system-assigned managed identity. See Managed identity. |
x509 | No | Authentication details using X.509 certificates. See X.509. |
Managed identity
The systemAssignedManagedIdentity field includes the following fields:
Field | Required | Description |
---|---|---|
audience | Yes | The audience for the token. Required if using managed identity. For Event Grid, it's https://eventgrid.azure.net . |
If Azure IoT MQ is deployed as an Azure Arc extension, it gets a system-assignment managed identity by default. You should use a managed identity for Azure IoT MQ to interact with Azure resources, including Event Grid MQTT broker, because it allows you to avoid credential management and retain high availability.
To use managed identity for authentication with Azure resources, first assign an appropriate Azure RBAC role like EventGrid TopicSpaces Publisher to Azure IoT MQ's managed identity provided by Arc.
Then, specify and MQTTBridgeConnector with managed identity as the authentication method:
spec:
remoteBrokerConnection:
authentication:
systemAssignedManagedIdentity:
audience: https://eventgrid.azure.net
When you use managed identity, the client ID isn't configurable, and equates to the Azure IoT MQ Azure Arc extension Azure Resource Manager resource ID within Azure.
The system-assigned managed identity is provided by Azure Arc. The certificate associated with the managed identity must be renewed at least every 90 days to avoid a manual recovery process. To learn more, see How do I address expired Azure Arc-enabled Kubernetes resources?
X.509
The x509
field includes the following fields:
Field | Required | Description |
---|---|---|
secretName | Yes | The Kubernetes secret containing the client certificate and private key. You can use Azure Key Vault to manage secrets for Azure IoT MQ instead of Kubernetes secrets. To learn more, see Manage secrets using Azure Key Vault or Kubernetes secrets. |
Many MQTT brokers, like Event Grid, support X.509 authentication. Azure IoT MQ's MQTT bridge can present a client X.509 certificate and negotiate the TLS communication. Use a Kubernetes secret to store the X.509 client certificate, private key and intermediate CA.
kubectl create secret generic bridge-client-secret \
--from-file=client_cert.pem=mqttbridge.pem \
--from-file=client_key.pem=mqttbridge.key \
--from-file=client_intermediate_certs.pem=intermediate.pem
And reference it with secretName
:
spec:
remoteBrokerConnection:
authentication:
x509:
secretName: bridge-client-cert
Local broker connection
The localBrokerConnection
field defines the connection details to bridge to the local broker.
Field | Required | Description |
---|---|---|
endpoint | Yes | Remote broker endpoint URL with port. |
tls | Yes | Specifies if connection is encrypted with TLS and trusted CA certificate. See TLS support |
authentication | Yes | Authentication details for Azure IoT MQ to use with the broker. The only supported method is Kubernetes service account token (SAT). To use SAT, specify kubernetes: {} . |
By default, IoT MQ is deployed in the namespace azure-iot-operations
with TLS enabled and SAT authentication.
Then MqttBridgeConnector local broker connection setting must be configured to match. The deployment YAML for the MqttBridgeConnector must have localBrokerConnection
at the same level as remoteBrokerConnection
. For example, to use TLS with SAT authentication in order to match the default IoT MQ deployment:
spec:
localBrokerConnection:
endpoint: aio-mq-dmqtt-frontend:8883
tls:
tlsEnabled: true
trustedCaCertificateConfigMap: aio-ca-trust-bundle-test-only
authentication:
kubernetes: {}
Here, trustedCaCertifcateName
is the ConfigMap for the root CA of Azure IoT MQ, like the ConfigMap for the root ca of the remote broker. The default root CA is stored in a ConfigMap named aio-ca-trust-bundle-test-only
.
For more information on obtaining the root CA, see Configure TLS with automatic certificate management to secure MQTT communication.
TLS support
The tls
field defines the TLS configuration for the remote or local broker connection. It includes the following fields:
Field | Required | Description |
---|---|---|
tlsEnabled | Yes | Whether TLS is enabled or not. |
trustedCaCertificateConfigMap | No | The CA certificate to trust when connecting to the broker. Required if TLS is enabled. |
TLS encryption support is available for both remote and local broker connections.
- For remote broker connection: if TLS is enabled, a trusted CA certificate should be specified as a Kubernetes ConfigMap reference. If not, the TLS handshake is likely to fail unless the remote endpoint is widely trusted A trusted CA certificate is already in the OS certificate store. For example, Event Grid uses widely trusted CA root so specifying isn't required.
- For local (Azure IoT MQ) broker connection: if TLS is enabled for Azure IoT MQ broker listener, CA certificate that issued the listener server certificate should be specified as a Kubernetes ConfigMap reference.
When specifying a trusted CA is required, create a ConfigMap containing the public potion of the CA and specify the configmap name in the trustedCaCertificateConfigMap
property. For example:
kubectl create configmap client-ca-configmap --from-file ~/.step/certs/root_ca.crt
Configure MqttBridgeTopicMap
The MqttBridgeTopicMap resource defines the topic mapping between the local and remote brokers. It must be used along with a MqttBridgeConnector resource. It includes the following components:
- The name of the MqttBridgeConnector resource to link to.
- A list of routes for bridging.
- An optional shared subscription configuration.
A MqttBridgeConnector can use multiple MqttBridgeTopicMaps linked with it. When a MqttBridgeConnector resource is deployed, Azure IoT MQ operator starts scanning the namespace for any MqttBridgeTopicMaps linked with it and automatically manage message flow among the MqttBridgeConnector instances. Then, once deployed, the MqttBridgeTopicMap is linked with the MqttBridgeConnector. Each MqttBridgeTopicMap can be linked with only one MqttBridgeConnector.
The following example shows a MqttBridgeTopicMap configuration for bridging messages from the remote topic remote-topic
to the local topic local-topic
:
apiVersion: mq.iotoperations.azure.com/v1beta1
kind: MqttBridgeTopicMap
metadata:
name: my-topic-map
namespace: azure-iot-operations
spec:
mqttBridgeConnectorRef: my-mqtt-bridge
routes:
- direction: remote-to-local
name: first-route
qos: 0
source: remote-topic
target: local-topic
sharedSubscription:
groupMinimumShareNumber: 3
groupName: group1
- direction: local-to-remote
name: second-route
qos: 1
source: local-topic
target: remote-topic
The following table describes the fields in the MqttBridgeTopicMap resource:
Fields | Required | Description |
---|---|---|
mqttBridgeConnectorRef | Yes | Name of the MqttBridgeConnector resource to link to. |
routes | Yes | A list of routes for bridging. For more information, see Routes. |
Routes
A MqttBridgeTopicMap can have multiple routes. The routes
field defines the list of routes. It includes the following fields:
Fields | Required | Description |
---|---|---|
direction | Yes | Direction of message flow. It can be remote-to-local or local-to-remote . For more information, see Direction. |
name | Yes | Name of the route. |
qos | No | MQTT quality of service (QoS). Defaults to 1. |
source | Yes | Source MQTT topic. Can have wildcards like # and + . See Wildcards in the source topic. |
target | No | Target MQTT topic. Can't have wildcards. If not specified, it would be the same as the source. See Reference source topic in target. |
sharedSubscription | No | Shared subscription configuration. Activates a configured number of clients for additional scale. For more information, see Shared subscriptions. |
Direction
For example, if the direction is local-to-remote, Azure IoT MQ publishes all messages on the specified local topic to the remote topic:
routes:
- direction: local-to-remote
name: "send-alerts"
source: "alerts"
target: "factory/alerts"
If the direction is reversed, Azure IoT MQ receives messages from a remote broker. Here, the target is omitted and all messages from the commands/factory
topic on the remote broker is published on the same topic locally.
routes:
- direction: remote-to-local
name: "receive-commands"
source: "commands/factory"
Wildcards in the source topic
To bridge from nonstatic topics, use wildcards to define how the topic patterns should be matched and the rule of the topic name translation. For example, to bridge all messages in all subtopics under telemetry
, use the multi-level #
wildcard:
routes:
- direction: local-to-remote
name: "wildcard-source"
source: "telemetry/#"
target: "factory/telemetry"
In the example, if a message is published to any topic under telemetry
, like telemetry/furnace/temperature
, Azure IoT MQ publishes it to the remote bridged broker under the static factory/telemetry
topic.
For single-level topic wildcard, use +
instead, like telemetry/+/temperature
.
The MQTT bridge connector must know the exact topic in the target broker either remote or Azure IoT MQ without any ambiguity. Wildcards are only available as part of source
topic.
Reference source topic in target
To reference the entire source topic, omit the target topic configuration in the route completely. Wildcards are supported.
For example, any message published under topic my-topic/#
, like my-topic/foo
or my-topic/bar
, are bridged to the remote broker under the same topic:
routes:
- direction: local-to-remote
name: "target-same-as-source"
source: "my-topic/#"
# No target
Other methods of source topic reference aren't supported.
Shared subscriptions
The sharedSubscription
field defines the shared subscription configuration for the route. It includes the following fields:
Fields | Required | Description |
---|---|---|
groupMinimumShareNumber | Yes | Number of clients to use for shared subscription. |
groupName | Yes | Shared subscription group name. |
Shared subscriptions help Azure IoT MQ create more clients for the MQTT bridge. You can set up a different shared subscription for each route. Azure IoT MQ subscribes to messages from the source topic and sends them to one client at a time using round robin. Then, the client publishes the messages to the bridged broker.
For example, if you set up a route with shared subscription and set the groupMinimumShareNumber
as 3:
routes:
- direction: local-to-remote
qos: 1
source: "shared-sub-topic"
target: "remote/topic"
sharedSubscription:
groupMinimumShareNumber: 3
groupName: "sub-group"
Azure IoT MQ's MQTT bridge creates three subscriber clients no matter how many instances. Only one client gets each message from $share/sub-group/shared-sub-topic
. Then, the same client publishes the message to the bridged remote broker under topic remote/topic
. The next message goes to a next client.
This helps you balance the message traffic for the bridge between multiple clients with different IDs. This is useful if your bridged broker limits how many messages each client can send.
Azure Event Grid MQTT broker support
To minimize credential management, using the system-assigned managed identity and Azure RBAC is the recommended way to bridge Azure IoT MQ with Azure Event Grid's MQTT broker feature.
For an end-to-end tutorial, see Tutorial: Configure MQTT bridge between Azure IoT MQ Preview and Azure Event Grid.
Connect to Event Grid MQTT broker with managed identity
First, using az k8s-extension show
, find the principal ID for the Azure IoT MQ Arc extension. Take note of the output value for identity.principalId
, which should look like abcd1234-5678-90ab-cdef-1234567890ab
.
az k8s-extension show --resource-group <RESOURCE_GROUP> --cluster-name <CLUSTER_NAME> --name mq --cluster-type connectedClusters --query identity.principalId -o tsv
Then, use Azure CLI to assign the roles to the Azure IoT MQ Arc extension managed identity. Replace <MQ_ID>
with the principal ID you found in the previous step. For example, to assign the EventGrid TopicSpaces Publisher role:
az role assignment create --assignee <MQ_ID> --role 'EventGrid TopicSpaces Publisher' --scope /subscriptions/<SUBSCRIPTION_ID>/resourceGroups/<RESOURCE_GROUP>/providers/Microsoft.EventGrid/namespaces/<EVENT_GRID_NAMESPACE>
Tip
To optimize for principle of least privilege, you can assign the role to a topic space instead of the entire Event Grid namespace. To learn more, see Event Grid RBAC and Topic spaces.
Finally, create an MQTTBridgeConnector and choose managed identity as the authentication method. Create MqttBridgeTopicMaps and deploy the MQTT bridge with kubectl
.
Maximum client sessions per authentication name
If bridgeInstances
is set higher than 1
, configure the Event Grid MQTT broker Configuration > Maximum client sessions per authentication name to match the number of instances. This configuration prevents issues like error 151 quota exceeded.
Per-connection limit
If using managed identity isn't possible, keep the per-connection limits for Event Grid MQTT broker in mind when designing your setup. At the time of publishing, the limit is 100 messages/second each direction for a connection. To increase the MQTT bridge throughput, use shared subscriptions to increase the number of clients serving each route.
Bridge from another broker to Azure IoT MQ Preview
Azure IoT MQ is a compliant MQTT broker and other brokers can bridge to it with the appropriate authentication and authorization credentials. For example, see MQTT bridge documentation for HiveMQ, VerneMQ, EMQX, and Mosquitto.
Related content
Feedback
https://aka.ms/ContentUserFeedback.
Coming soon: Throughout 2024 we will be phasing out GitHub Issues as the feedback mechanism for content and replacing it with a new feedback system. For more information see:Submit and view feedback for