|
| 1 | +--- |
| 2 | +title: 'Tutorial: Route MQTT messages to Azure Functions - CLI' |
| 3 | +description: 'Tutorial: Use custom topics in Azure Event Grid to route MQTT messages to Azure Functions using the Routing feature. You use the Azure CLI in this tutorial.' |
| 4 | +ms.topic: tutorial |
| 5 | +ms.date: 03/14/2024 |
| 6 | +author: george-guirguis |
| 7 | +ms.author: geguirgu |
| 8 | +ms.subservice: mqtt |
| 9 | +--- |
| 10 | + |
| 11 | +# Tutorial: Route MQTT messages in Azure Event Grid to Azure Functions using custom topics - Azure CLI |
| 12 | + |
| 13 | +In this tutorial, you learn how to route MQTT messages received by an Azure Event Grid namespace to an Azure function via an Event Grid custom topic by following these steps: |
| 14 | + |
| 15 | +If you don't have an Azure subscription, you can sign up for a [free trial](https://azure.microsoft.com/free/dotnet). |
| 16 | + |
| 17 | +## Prerequisites |
| 18 | +Follow instructions from [Create an Azure function using Visual Studio Code](../azure-functions/functions-develop-vs-code.md), but use the **Azure Event Grid Trigger** instead of using the **HTTP Trigger**. You should see code similar to the following example: |
| 19 | + |
| 20 | +```csharp |
| 21 | +using System; |
| 22 | +using Azure.Messaging; |
| 23 | +using Microsoft.Azure.Functions.Worker; |
| 24 | +using Microsoft.Extensions.Logging; |
| 25 | + |
| 26 | +namespace Company.Function |
| 27 | +{ |
| 28 | + public class MyEventGridTriggerFunc |
| 29 | + { |
| 30 | + private readonly ILogger<MyEventGridTriggerFunc> _logger; |
| 31 | + |
| 32 | + public MyEventGridTriggerFunc(ILogger<MyEventGridTriggerFunc> logger) |
| 33 | + { |
| 34 | + _logger = logger; |
| 35 | + } |
| 36 | + |
| 37 | + [Function(nameof(MyEventGridTriggerFunc))] |
| 38 | + public void Run([EventGridTrigger] CloudEvent cloudEvent) |
| 39 | + { |
| 40 | + _logger.LogInformation("Event type: {type}, Event subject: {subject}", cloudEvent.Type, cloudEvent.Subject); |
| 41 | + } |
| 42 | + } |
| 43 | +} |
| 44 | +``` |
| 45 | + |
| 46 | +You use this Azure function as an event handler for a topic's subscription later in this tutorial. |
| 47 | + |
| 48 | +> [!NOTE] |
| 49 | +> - Create all resources in the same region. |
| 50 | +> - This tutorial has been tested with an Azure function that uses .NET 8.0 (isolated) runtime stack. |
| 51 | +
|
| 52 | +## Create an Event Grid topic (custom topic) |
| 53 | + |
| 54 | +In this step, you create an Event Grid topic. |
| 55 | + |
| 56 | +1. Copy and paste the script to an editor. |
| 57 | +1. Replace the following values. |
| 58 | +1. Select **Open Cloud Shell**. |
| 59 | +1. Switch from **PowerShell** to **Bash** (in the upper-left corner of the Cloud Shell window). |
| 60 | +1. Copy and paste the script from the editor to Cloud Shell and run the script. |
| 61 | + |
| 62 | +The script creates an Azure resource group and an Event Grid custom topic in it. Later in this tutorial, you configure routing for an Event Grid namespace so that the events or messages sent to the namespace are routed to the custom topic and then to the Azure function via subscription to the topic. |
| 63 | + |
| 64 | +| Placeholder | Description | |
| 65 | +| ----------- | ----------- | |
| 66 | +|`RESOURCEGROUPNAME` | Name of the resource group to be created. | |
| 67 | +| `REGION` | Region in which you want to create the resource group and the custom topic. | |
| 68 | +| `TOPICNAME` | Name of the custom topic to be created. | |
| 69 | + |
| 70 | +The script uses the [`az eventgrid topic create`](/cli/azure/eventgrid/topic#az-eventgrid-topic-create) command to create an Event Grid topic or custom topic. The schema type is specified as the cloud event schema. |
| 71 | + |
| 72 | +```azurecli-interactive |
| 73 | +rgName="RESOURCEGROUPNAME" |
| 74 | +location="REGION" |
| 75 | +topicName="TOPICNAME" |
| 76 | +
|
| 77 | +az group create -n $rgName -l $location |
| 78 | +
|
| 79 | +az eventgrid topic create --name $topicName -l $location -g $rgName --input-schema cloudeventschemav1_0 |
| 80 | +``` |
| 81 | + |
| 82 | +> [!NOTE] |
| 83 | +> Use **Cloud event schema** everywhere in this tutorial. |
| 84 | +
|
| 85 | +## Add a subscription to the topic using the function |
| 86 | + |
| 87 | +In this step, you create a subscription to the custom topic using the Azure function you created earlier. |
| 88 | + |
| 89 | +Replace the following values and run the script in the Cloud Shell. The script uses the [`az eventgrid event-subscription create`](/cli/azure/eventgrid/event-subscription#az-eventgrid-event-subscription-create) command to create an Azure function subscription to the custom topic. In the command, source ID is the topic's resource ID and endpoint is the function's resource ID. The endpoint type is set to Azure function and event delivery schema is specified as the cloud event schema. |
| 90 | + |
| 91 | +| Placeholder | Description | |
| 92 | +| ----------- | ----------- | |
| 93 | +|`FUNCTIONRESOURCEGROUP` | Name of the resource group that has the Azure Functions app. | |
| 94 | +| `FUNCTIONSAPPNAME` | Name of the Azure Functions app. | |
| 95 | +| `FUNCTIONNAME` | Name of the Azure function. | |
| 96 | + |
| 97 | +```azurecli-interactive |
| 98 | +funcAppRgName="FUNCTIONRESOURCEGROUP" |
| 99 | +funcAppName="FUNCTIONSAPPNAME" |
| 100 | +funcName="FUNCTIONNAME" |
| 101 | +funcResourceId=$(az functionapp function show -g $funcAppRgName -n $funcAppName --function-name $funcName --query "{I:id}" -o tsv) |
| 102 | +
|
| 103 | +topicResourceId=$(az eventgrid topic show --name $topicName -g $rgName --query id --output tsv) |
| 104 | +eventSubscriptionName="EVENTSUBSCRIPTIONNAME" |
| 105 | +az eventgrid event-subscription create --name $eventSubscriptionName --source-resource-id $topicResourceId --endpoint-type azurefunction --endpoint $funcResourceId --event-delivery-schema cloudeventschemav1_0 |
| 106 | +``` |
| 107 | + |
| 108 | + |
| 109 | +## Create namespace, clients, topic spaces, and permission bindings |
| 110 | + |
| 111 | +Follow instructions from [Quickstart: Publish and subscribe to MQTT messages on an Event Grid namespace with the Azure CLI](mqtt-publish-and-subscribe-cli.md) to: |
| 112 | + |
| 113 | +1. Create an Event Grid namespace. |
| 114 | +1. Create two clients. |
| 115 | +1. Create a topic space. |
| 116 | +1. Create publisher and subscriber permission bindings. |
| 117 | +1. Test using [MQTTX app](mqtt-publish-and-subscribe-portal.md#connecting-the-clients-to-the-eg-namespace-using-mqttx-app) to confirm that clients are able to send and receive messages. |
| 118 | + |
| 119 | +## Enable managed identity for the namespace |
| 120 | + |
| 121 | +Replace the following value and run the script to enable system-assigned managed identity for the Event Grid namespace. |
| 122 | + |
| 123 | +| Placeholder | Description | |
| 124 | +| ----------- | ----------- | |
| 125 | +|`EVENTGRIDNAMESPACENAME` | Name of the Event Grid namespace. | |
| 126 | + |
| 127 | +The script uses the [`az eventgrid namespace update`](/cli/azure/eventgrid/namespace#az-eventgrid-namespace-update) command with `identity` set to `SystemAssigned` identity. |
| 128 | + |
| 129 | + |
| 130 | +```azurecli-interactive |
| 131 | +nsName="EVENTGRIDNAMESPACENAME" |
| 132 | +az eventgrid namespace update -g $rgName -n $nsName --topic-spaces-configuration "{state:Enabled}" --identity "{type:SystemAssigned}" |
| 133 | +``` |
| 134 | + |
| 135 | +Then, grant namespace's managed identity the **send** permission on the Event Grid custom topic you created earlier so that the namespace can send or route messages to the custom topic. You do so by adding the managed identity to the **Event Grid Data Sender** role on the custom topic. |
| 136 | + |
| 137 | + |
| 138 | +```azurecli-interactive |
| 139 | +egNamespaceServicePrincipalObjectID=$(az ad sp list --display-name $nsName --query [].id -o tsv) |
| 140 | +topicResourceId=$(az eventgrid topic show --name $topicName -g $rgName --query id --output tsv) |
| 141 | +az role assignment create --assignee $egNamespaceServicePrincipalObjectID --role "EventGrid Data Sender" --scope $topicResourceId |
| 142 | +``` |
| 143 | + |
| 144 | +The script uses the [`az role assignment create`](/cli/azure/role/assignment#az-role-assignment-create) command with the IDs of namespace's managed identity and the custom topic, and assigns **Event Grid Data Sender** role to the namespace's managed identity on the custom topic. |
| 145 | + |
| 146 | + |
| 147 | +## Configure routing messages to Azure function via custom topic |
| 148 | + |
| 149 | +In this step, you configure routing for the Event Grid namespace so that the messages it receives are routed to the custom topic you created. |
| 150 | + |
| 151 | +```azurecli-interactive |
| 152 | +az eventgrid namespace update -g $rgName -n $nsName --topic-spaces-configuration "{state:Enabled,'routeTopicResourceId':$topicResourceId,'routingIdentityInfo':{type:SystemAssigned}}" |
| 153 | +``` |
| 154 | + |
| 155 | +The script uses the [`az eventgrid namespace update`](/cli/azure/eventgrid/namespace#az-eventgrid-namespace-update) command to set the routing topic and the type of managed identity to use to route events to the topic. |
| 156 | + |
| 157 | +## Send test MQTT messages using MQTTX |
| 158 | +Send test MQTT messages to the namespace and confirm that the function receives them. |
| 159 | + |
| 160 | +Follow instructions from the [Publish, subscribe messages using MQTTX app](mqtt-publish-and-subscribe-portal.md#publishsubscribe-using-mqttx-app) article to send a few test messages to the Event Grid namespace. |
| 161 | + |
| 162 | +Here's the flow of the events or messages: |
| 163 | + |
| 164 | +1. MQTTX sends messages to the topic space of the Event Grid namespace. |
| 165 | +1. The messages get routed to the custom topic that you configured. |
| 166 | +1. The messages are forwarded to the event subscription, which is the Azure function. |
| 167 | +1. Use the logging feature to verify that the function has received the event. |
| 168 | + |
| 169 | + :::image type="content" source="./media/mqtt-routing-to-azure-functions-portal/function-log-stream.png" alt-text="Screenshot that shows the Log stream page for an Azure function." lightbox="./media/mqtt-routing-to-azure-functions-portal/function-log-stream.png"::: |
| 170 | + |
| 171 | +## Next step |
| 172 | + |
| 173 | +> [!div class="nextstepaction"] |
| 174 | +> See code samples in [this GitHub repository](https://github.com/Azure-Samples/MqttApplicationSamples/tree/main). |
| 175 | +
|
0 commit comments