Quickstart: Deploy an Azure IoT hub and a storage account using an ARM template
In this quickstart, you use an Azure Resource Manager template (ARM template) to create an IoT hub that will route messages to Azure Storage, and a storage account to hold the messages. After manually adding a virtual IoT device to the hub to submit the messages, you configure that connection information in an application called arm-read-write to submit messages from the device to the hub. The hub is configured so the messages sent to the hub are automatically routed to the storage account. At the end of this quickstart, you can open the storage account and see the messages sent.
A resource manager template is a JavaScript Object Notation (JSON) file that defines the infrastructure and configuration for your project. The template uses declarative syntax. In declarative syntax, you describe your intended deployment without writing the sequence of programming commands to create the deployment.
If your environment meets the prerequisites and you're familiar with using ARM templates, select the Deploy to Azure button. The template will open in the Azure portal.
Prerequisites
If you don't have an Azure subscription, create a free Azure account before you begin.
The sample application you run in this quickstart is written using C#. You need the .NET SDK 6.0 or greater on your development machine.
You can download the .NET Core SDK for multiple platforms from .NET.
You can verify the current version of C# on your development machine using the following command:
dotnet --version
Download and unzip the IoT C# SDK.
Review the template
The template used in this quickstart is called 101-iothub-auto-route-messages
from Azure Quickstart Templates.
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"metadata": {
"_generator": {
"name": "bicep",
"version": "0.6.18.56646",
"templateHash": "9942060226287533039"
}
},
"parameters": {
"projectName": {
"type": "string",
"defaultValue": "contoso",
"maxLength": 11,
"minLength": 1,
"metadata": {
"description": "Define the project name or prefix for all objects."
}
},
"location": {
"type": "string",
"defaultValue": "[resourceGroup().location]",
"metadata": {
"description": "The datacenter to use for the deployment."
}
},
"skuName": {
"type": "string",
"defaultValue": "S1",
"metadata": {
"description": "The SKU to use for the IoT Hub."
}
},
"skuUnits": {
"type": "int",
"defaultValue": 1,
"metadata": {
"description": "The number of IoT Hub units."
}
},
"d2cPartitions": {
"type": "int",
"defaultValue": 4,
"metadata": {
"description": "Partitions used for the event stream."
}
}
},
"variables": {
"iotHubName": "[format('{0}Hub{1}', parameters('projectName'), uniqueString(resourceGroup().id))]",
"storageAccountName": "[format('{0}{1}', toLower(parameters('projectName')), uniqueString(resourceGroup().id))]",
"storageEndpoint": "[format('{0}StorageEndpont', parameters('projectName'))]",
"storageContainerName": "[format('{0}results', toLower(parameters('projectName')))]"
},
"resources": [
{
"type": "Microsoft.Storage/storageAccounts",
"apiVersion": "2021-08-01",
"name": "[variables('storageAccountName')]",
"location": "[parameters('location')]",
"sku": {
"name": "Standard_LRS"
},
"kind": "Storage"
},
{
"type": "Microsoft.Storage/storageAccounts/blobServices/containers",
"apiVersion": "2021-08-01",
"name": "[format('{0}/default/{1}', variables('storageAccountName'), variables('storageContainerName'))]",
"properties": {
"publicAccess": "None"
},
"dependsOn": [
"[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName'))]"
]
},
{
"type": "Microsoft.Devices/IotHubs",
"apiVersion": "2021-07-02",
"name": "[variables('iotHubName')]",
"location": "[parameters('location')]",
"sku": {
"name": "[parameters('skuName')]",
"capacity": "[parameters('skuUnits')]"
},
"properties": {
"eventHubEndpoints": {
"events": {
"retentionTimeInDays": 1,
"partitionCount": "[parameters('d2cPartitions')]"
}
},
"routing": {
"endpoints": {
"storageContainers": [
{
"connectionString": "[format('DefaultEndpointsProtocol=https;AccountName={0};EndpointSuffix={1};AccountKey={2}', variables('storageAccountName'), environment().suffixes.storage, listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName')), '2021-08-01').keys[0].value)]",
"containerName": "[variables('storageContainerName')]",
"fileNameFormat": "{iothub}/{partition}/{YYYY}/{MM}/{DD}/{HH}/{mm}",
"batchFrequencyInSeconds": 100,
"maxChunkSizeInBytes": 104857600,
"encoding": "JSON",
"name": "[variables('storageEndpoint')]"
}
]
},
"routes": [
{
"name": "ContosoStorageRoute",
"source": "DeviceMessages",
"condition": "level=\"storage\"",
"endpointNames": [
"[variables('storageEndpoint')]"
],
"isEnabled": true
}
],
"fallbackRoute": {
"name": "$fallback",
"source": "DeviceMessages",
"condition": "true",
"endpointNames": [
"events"
],
"isEnabled": true
}
},
"messagingEndpoints": {
"fileNotifications": {
"lockDurationAsIso8601": "PT1M",
"ttlAsIso8601": "PT1H",
"maxDeliveryCount": 10
}
},
"enableFileUploadNotifications": false,
"cloudToDevice": {
"maxDeliveryCount": 10,
"defaultTtlAsIso8601": "PT1H",
"feedback": {
"lockDurationAsIso8601": "PT1M",
"ttlAsIso8601": "PT1H",
"maxDeliveryCount": 10
}
}
},
"dependsOn": [
"[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName'))]"
]
}
]
}
Two Azure resources are defined in the template:
Deploy the template and run the sample app
This section provides the steps to deploy the template, create a virtual device, and run the arm-read-write application to send the messages.
Create the resources by deploying the ARM template.
Tip
Select the button below to start the deployment of the template. While it's running, set up the arm-read-write application to run.
Open a command window and go to the folder where you unzipped the IoT C# SDK. Find the folder with the arm-read-write.csproj file. You create the environment variables in this command window. Sign in to the Azure portal to get the keys. Select Resource Groups then select the resource group used for this quickstart.
You see the IoT Hub and storage account that were created when you deployed the ARM template. Wait until the template is fully deployed before continuing. Then select your resource group to see your resources.
You need the hub name. Select the hub in the list of resources. Copy the name of the hub from the top of the IoT Hub section to the Windows clipboard.
Substitute the hub name in this command where noted, and execute this command in the command window:
SET IOT_HUB_URI=<hub name goes here>.azure-devices-net;
which will look this example:
SET IOT_HUB_URI=ContosoTestHubdlxlud5h.azure-devices-net;
The next environment variable is the IoT Device Key. Add a new device to the hub by selecting Devices from the IoT Hub menu for the hub.
On the right side of the screen, select + Add Device to add a new device.
Fill in the new device name. This quickstart uses a name starting with Contoso-Test-Device. Save the device and then open that screen again to retrieve the device key. (The key is generated for you when you close the pane.) Select either the primary or secondary key and copy it to the Windows clipboard. In the command window, set the command to execute and then press Enter. The command should look like this one but with the device key pasted in:
SET IOT_DEVICE_KEY=<device-key-goes-here>
The last environment variable is the Device ID. In the command window, set up the command and execute it.
SET IOT_DEVICE_ID=<device-id-goes-here>
which will look like this example:
SET IOT_DEVICE_ID=Contoso-Test-Device
To see the environment variables you've defined, type SET on the command line and press Enter, then look for the ones starting with IoT.
Now the environment variables are set, run the application from the same command window. Because you're using the same window, the variables will be accessible in memory when you run the application.
To run the application, type the following command in the command window and press Enter.
dotnet run arm-read-write
The application generates and displays messages on the console as it sends each message to the IoT hub. The hub was configured in the ARM template to have automated routing. Messages containing the text
level = storage
are automatically routed to the storage account. Let the app run for 10 to 15 minutes, then press Enter once or twice until it stops running.
Review deployed resources
Sign in to the Azure portal and select the Resource Group, then select the storage account.
Drill down into the storage account until you find files.
Select one of the files and select Download and download the file to a location you can find later. It will have a name that's numeric, like 47. Add .txt to the end and then double-click on the file to open it.
When you open the file, each row is for a different message; the body of each message is also encrypted. It must be in order for you to perform queries against the body of the message.
Note
These messages are encoded in UTF-32 and base64. If you read the message back, you have to decode it from base64 and utf-32 in order to read it as ASCII. If you're interested, you can use the method ReadOneRowFromFile in the Routing Tutorial to read one for from one of these message files and decode it into ASCII. ReadOneRowFromFile is in the IoT C# SDK repository that you unzipped for this quickstart. Here is the path from the top of that folder: ./iothub/device/samples/getting started/RoutingTutorial/SimulatedDevice/Program.cs. Set the boolean
readTheFile
to true, and hardcode the path to the file on disk, and it will open and translate the first row in the file.
You have deployed an ARM template to create an IoT hub and a storage account, and run a program to send messages to the hub. The messages are then automatically stored in the storage account where they can be viewed.
Clean up resources
To remove the resources added during this quickstart, sign in to the Azure portal. Select Resource Groups, then find the resource group you used for this quickstart. Select the resource group and then select Delete. It will delete all of the resources in the group.
Next steps
Feedback
Submit and view feedback for