Tutorial: Use the Azure CLI and Azure portal to configure IoT Hub message routing

Message routing enables sending telemetry data from your IoT devices to built-in Event Hub-compatible endpoints or custom endpoints such as blob storage, Service Bus Queues, Service Bus Topics, and Event Hubs. To configure custom message routing, you create routing queries to customize the route that matches a certain condition. Once set up, the incoming data is automatically routed to the endpoints by the IoT Hub. If a message doesn't match any of the defined routing queries, it is routed to the default endpoint.

In this 2-part tutorial, you learn how to set up and use these custom routing queries with IoT Hub. You route messages from an IoT device to one of multiple endpoints, including blob storage and a Service Bus queue. Messages to the Service Bus queue are picked up by a Logic App and sent via e-mail. Messages that do not have custom message routing defined are sent to the default endpoint, then picked up by Azure Stream Analytics and viewed in a Power BI visualization.

To complete parts 1 and 2 of this tutorial, you performed the following tasks:

Part I: Create resources, set up message routing

  • Create the resources -- an IoT hub, a storage account, a Service Bus queue, and a simulated device. This can be done using the portal, the Azure CLI, Azure PowerShell, or an Azure Resource Manager template.
  • Configure the endpoints and message routes in IoT Hub for the storage account and Service Bus queue.

Part II: Send messages to the hub, view routed results

  • Create a Logic App that is triggered and sends e-mail when a message is added to the Service Bus queue.
  • Download and run an app that simulates an IoT Device sending messages to the hub for the different routing options.
  • Create a Power BI visualization for data sent to the default endpoint.
  • View the results ...
  • ...in the Service Bus queue and e-mails.
  • ...in the storage account.
  • ...in the Power BI visualization.

Prerequisites

  • For part 1 of this tutorial:

    • You must have an Azure subscription. If you don't have an Azure subscription, create a free account before you begin.
  • For part 2 of this tutorial:

    • You must have completed Part 1 of this tutorial, and have the resources still available.
    • Install Visual Studio.
    • A Power BI account to analyze the default endpoint's stream analytics. (Try Power BI for free.)
    • An Office 365 account to send notification e-mails.

Open Azure Cloud Shell

Azure Cloud Shell is an interactive shell environment hosted in Azure and used through your browse. Azure Cloud Shell allows you to use either bash or PowerShell shells to run a variety of tools to work with Azure services. Azure Cloud Shell comes pre-installed with the commands to allow you to run the content of this article without having to install anything on your local environment.

To run any code contained in this article on Azure Cloud Shell, open a Cloud Shell session, use the Copy button on a code block to copy the code, and paste it into the Cloud Shell session with Ctrl+Shift+V on Windows and Linux, or Cmd+Shift+V on macOS. Pasted text is not automatically executed, so press Enter to run code.

You can launch Azure Cloud Shell with:

Option Example/Link
Select Try It in the upper-right corner of a code block. This doesn't automatically copy text to Cloud Shell. Example of Try It for Azure Cloud Shell
Open Azure Cloud Shell in your browser.
Select the Cloud Shell button on the menu in the upper-right corner of the Azure portal. Cloud Shell button in the Azure portal

Create base resources

Before you can configure the message routing, you need to create an IoT hub, a storage account, and a Service Bus queue. These resources can be created using one of the four articles that available for part 1 of this tutorial: the Azure CLI, Azure PowerShell, the Azure portal, or an Azure Resource Manager template.

Use the same resource group and location for all of the resources. Then at the end, you can remove all of the resources in one step by deleting the resource group.

The following sections describe the steps to be performed.

  1. Create a resource group.

  2. Create an IoT hub in the S1 tier. Add a consumer group to your IoT hub. The consumer group is used by the Azure Stream Analytics when retrieving data.

    Note

    You must use an Iot hub in a paid tier to complete this tutorial. The free tier only allows you to set up one endpoint, and this tutorial requires multiple endpoints.

  3. Create a standard V1 storage account with Standard_LRS replication.

  4. Create a Service Bus namespace and queue.

  5. Create a device identity for the simulated device that sends messages to your hub. Save the key for the testing phase. (If creating a Resource Manager template, this is done after deploying the template.)

Use the Azure CLI to create the base resources

This tutorial uses the Azure CLI to create the base resources, then uses the Azure portal to show how to configure message routing and set up the virtual device for testing.

There are several resource names that must be globally unique, such as the IoT Hub name and the storage account name. To make this easier, those resource names are appended with a random alphanumeric value called randomValue. The randomValue is generated once at the top of the script and appended to the resource names as needed throughout the script. If you don't want it to be random, you can set it to an empty string or to a specific value.

Copy and paste the script below into Cloud Shell and press Enter. It runs the script one line at a time. This will create the base resources for this tutorial, including the storage account, IoT Hub, Service Bus Namespace, and Service Bus queue.

A note about debugging: this script uses the continuation symbol (the backslash \) to make the script more readable. If you have a problem running the script, make sure there are no spaces after any of the backslashes.

# This retrieves the subscription id of the account 
#   in which you're logged in.
# This field is used to set up the routing rules.
subscriptionID=$(az account show --query id)

# Concatenate this number onto the resources that have to be globally unique.
# You can set this to "" or to a specific value if you don't want it to be random.
# This retrieves a random value.
randomValue=$RANDOM

# Set the values for the resource names that 
#   don't have to be globally unique.
location=westus
resourceGroup=ContosoResources
iotHubConsumerGroup=ContosoConsumers
containerName=contosoresults

# Create the resource group to be used
#   for all the resources for this tutorial.
az group create --name $resourceGroup \
    --location $location

# The IoT hub name must be globally unique, 
#   so add a random value to the end.
iotHubName=ContosoTestHub$randomValue 
echo "IoT hub name = " $iotHubName

# Create the IoT hub.
az iot hub create --name $iotHubName \
    --resource-group $resourceGroup \
    --sku S1 --location $location

# Add a consumer group to the IoT hub for the 'events' endpoint.
az iot hub consumer-group create --hub-name $iotHubName \
    --name $iotHubConsumerGroup

# The storage account name must be globally unique, 
#   so add a random value to the end.
storageAccountName=contosostorage$randomValue
echo "Storage account name = " $storageAccountName

# Create the storage account to be used as a routing destination.
az storage account create --name $storageAccountName \
    --resource-group $resourceGroup \
    --location $location \
    --sku Standard_LRS

# Get the primary storage account key. 
#    You need this to create the container.
storageAccountKey=$(az storage account keys list \
    --resource-group $resourceGroup \
    --account-name $storageAccountName \
    --query "[0].value" | tr -d '"') 

# See the value of the storage account key.
echo "storage account key = " $storageAccountKey

# Create the container in the storage account. 
az storage container create --name $containerName \
    --account-name $storageAccountName \
    --account-key $storageAccountKey \
    --public-access off

# The Service Bus namespace must be globally unique, 
#   so add a random value to the end.
sbNamespace=ContosoSBNamespace$randomValue
echo "Service Bus namespace = " $sbNamespace

# Create the Service Bus namespace.
az servicebus namespace create --resource-group $resourceGroup \
    --name $sbNamespace \
    --location $location

# The Service Bus queue name must be globally unique, 
#   so add a random value to the end.
sbQueueName=ContosoSBQueue$randomValue
echo "Service Bus queue name = " $sbQueueName

# Create the Service Bus queue to be used as a routing destination.
az servicebus queue create --name $sbQueueName \
    --namespace-name $sbNamespace \
    --resource-group $resourceGroup

Now that the base resources are set up, you can configure the message routing in the Azure portal.

Set up message routing

You are going to route messages to different resources based on properties attached to the message by the simulated device. Messages that are not custom routed are sent to the default endpoint (messages/events). In the next tutorial, you send messages to the IoT Hub and see them routed to the different destinations.

value Result
level="storage" Write to Azure Storage.
level="critical" Write to a Service Bus queue. A Logic App retrieves the message from the queue and uses Office 365 to e-mail the message.
default Display this data using Power BI.

The first step is to set up the endpoint to which the data will be routed. The second step is to set up the message route that uses that endpoint. After setting up the routing, you can view the endpoints and message routes in the portal.

Route to a storage account

Now set up the routing for the storage account. You go to the Message Routing pane, then add a route. When adding the route, define a new endpoint for the route. After this routing is set up, messages where the level property is set to storage are written to a storage account automatically.

Note

The data can be written to blob storage in either the Apache Avro format, which is the default, or JSON (preview).

The capability to encode JSON format is in preview in all regions in which IoT Hub is available, except East US, West US and West Europe. The encoding format can be only set at the time the blob storage endpoint is configured. The format cannot be changed for an endpoint that has already been set up. When using JSON encoding, you must set the contentType to JSON and the contentEncoding to UTF-8 in the message system properties.

For more detailed information about using a blob storage endpoint, please see guidance on routing to blob storage.

  1. In the Azure portal, select Resource Groups, then select your resource group. This tutorial uses ContosoResources.

  2. Select the IoT hub under the list of resources. This tutorial uses ContosoTestHub.

  3. Select Message Routing. In the Message Routing pane, select +Add. On the Add a Route pane, select +Add next to the Endpoint field to show the supported endpoints, as displayed in the following picture:

    Start adding an endpoint for a route

  4. Select Blob storage. You see the Add a storage endpoint pane.

    Adding an endpoint

  5. Enter a name for the endpoint. This tutorial uses ContosoStorageEndpoint.

  6. Select Pick a container. This takes you to a list of your storage accounts. Select the one you set up in the preparation steps. This tutorial uses contosostorage. It shows a list of containers in that storage account. Select the container you set up in the preparation steps. This tutorial uses contosoresults. You return to the Add a storage endpoint pane and see the selections you made.

  7. Set the encoding to AVRO or JSON. For the purpose of this tutorial, use the defaults for the rest of the fields. This field will be greyed out if the region selected does not support JSON encoding.,

    Note

    You can set the format of the blob name using the Blob file name format. The default is {iothub}/{partition}/{YYYY}/{MM}/{DD}/{HH}/{mm}. The format must contain {iothub}, {partition}, {YYYY}, {MM}, {DD}, {HH}, and {mm} in any order.

    For example, using the default blob file name format, if the hub name is ContosoTestHub, and the date/time is October 30, 2018 at 10:56 a.m., the blob name will look like this: ContosoTestHub/0/2018/10/30/10/56.

    The blobs are written in the Avro format.

  8. Select Create to create the storage endpoint and add it to the route. You return to the Add a route pane.

  9. Now complete the rest of the routing query information. This query specifies the criteria for sending messages to the storage container you just added as an endpoint. Fill in the fields on the screen.

    Name: Enter a name for your routing query. This tutorial uses ContosoStorageRoute.

    Endpoint: This shows the endpoint you just set up.

    Data source: Select Device Telemetry Messages from the dropdown list.

    Enable route: Be sure this field is set to enabled.

    Routing query: Enter level="storage" as the query string.

    Creating a routing query for the storage account

    Select Save. When it finishes, it returns to the Message Routing pane, where you can see your new routing query for storage. Close the Routes pane, which returns you to the Resource group page.

Route to a Service Bus queue

Now set up the routing for the Service Bus queue. You go to the Message Routing pane, then add a route. When adding the route, define a new endpoint for the route. After this route is set up, messages where the level property is set to critical are written to the Service Bus queue, which triggers a Logic App, which then sends an e-mail with the information.

  1. On the Resource group page, select your IoT hub, then select Message Routing.

  2. In the Message Routing pane, select +Add.

  3. On the Add a Route pane, Select +Add next to the Endpoint field. Select Service Bus Queue. You see the Add Service Bus Endpoint pane.

    Adding a service bus endpoint

  4. Fill in the fields:

    Endpoint Name: Enter a name for the endpoint. This tutorial uses ContosoSBQueueEndpoint.

    Service Bus Namespace: Use the dropdown list to select the service bus namespace you set up in the preparation steps. This tutorial uses ContosoSBNamespace.

    Service Bus queue: Use the dropdown list to select the Service Bus queue. This tutorial uses contososbqueue.

  5. Select Create to add the Service Bus queue endpoint. You return to the Add a route pane.

  6. Now you complete the rest of the routing query information. This query specifies the criteria for sending messages to the Service Bus queue you just added as an endpoint. Fill in the fields on the screen.

    Name: Enter a name for your routing query. This tutorial uses ContosoSBQueueRoute.

    Endpoint: This shows the endpoint you just set up.

    Data source: Select Device Telemetry Messages from the dropdown list.

    Routing query: Enter level="critical" as the query string.

    Create a routing query for the Service Bus queue

  7. Select Save. When it returns to the Routes pane, you see both of your new routes, as displayed here.

    The routes you just set up

  8. You can see the custom endpoints you set up by selecting the Custom Endpoints tab.

    The custom endpoint you just set up

  9. Close the Message Routing pane, which returns you to the Resource group pane.

Create a simulated device

Next, create a device identity and save its key for later use. This device identity is used by the simulation application to send messages to the IoT hub. This capability is not available in PowerShell or when using an Azure Resource Manager template. The following steps tell you how to create the simulated device using the Azure portal.

  1. Open the Azure portal and log into your Azure account.

  2. Select Resource groups and then choose your resource group. This tutorial uses ContosoResources.

  3. In the list of resources, select your IoT hub. This tutorial uses ContosoTestHub. Select IoT Devices from the Hub pane.

  4. Select + Add. On the Add Device pane, fill in the device ID. This tutorial uses Contoso-Test-Device. Leave the keys empty, and check Auto Generate Keys. Make sure Connect device to IoT hub is enabled. Select Save.

    The add-device screen

  5. Now that it's been created, select the device to see the generated keys. Select the Copy icon on the Primary key and save it somewhere such as Notepad for the testing phase of this tutorial.

    The device details, including the keys

Next steps

Now that you have the resources set up and the message routes configured, advance to the next tutorial to learn how to send messages to the IoT hub and see them be routed to the different destinations.