In this article we will create an ARM template that will deploy an IoT Hub and output the primary connection string along with the Event Hub compatible connection string.

If you are building an IoT solution and need reliable and secure communications between your IoT devices and your cloud-hosted solution backend then you are probably looking at the following Azure product: Azure IoT Hub.

Today we will focus on creating an Azure Resource Manager template to easily setup and deploy an IoT Hub to a resource group. Our ARM template will be created in a new Azure Resource Group deployment project in Visual Studio.

 

Creation

Let's declare the parameters of the ARM template:

{
  "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "iotHubName": {
      "type": "string",
      "defaultValue": "[concat('myIoTHub', uniqueString(resourceGroup().id))]"
    },
    "iotHubSkuName": {
      "type": "string",
      "defaultValue": "F1",
      "allowedValues": [
        "F1",
        "B1",
        "B2",
        "B3",
        "S1",
        "S2",
        "S3"
      ]
    },
    "iotHubSkuCapacity": {
      "type": "int",
      "defaultValue": 1,
      "minValue": 1
    },
    "iotHubMessageRetentionInDays": {
      "type": "int",
      "defaultValue": 1,
      "allowedValues": [ 1, 2, 3, 4, 5, 6, 7 ]
    },
    "iotHubPartitionCount": {
      "type": "int",
      "defaultValue": 2,
      "minValue": 2
    }
  }
  ...
}

 

Now we will declare the resources for the IoT Hub:

{
  ...
  "resources": [
    {
      "apiVersion": "2018-04-01",
      "name": "[parameters('iotHubName')]",
      "type": "Microsoft.Devices/IotHubs",
      "location": "[resourceGroup().location]",
      "sku": {
        "name": "[parameters('iotHubSkuName')]",
        "capacity": "[parameters('iotHubSkuCapacity')]"
      },
      "properties": {
        "eventHubEndpoints": {
          "events": {
            "retentionTimeInDays": "[parameters('iotHubMessageRetentionInDays')]",
            "partitionCount": "[parameters('iotHubPartitionCount')]"
          },
          "operationsMonitoringEvents": {
            "retentionTimeInDays": "[parameters('iotHubMessageRetentionInDays')]",
            "partitionCount": "[parameters('iotHubPartitionCount')]"
          }
        }
      }
    }
  ]
  ...
}

We can pay attention to several things here:

 

And to finish, we will output the connection string and the Event Hub compatible connection string of the IoT hub:

{
  ...
  "outputs": {
    "IoTHubConnectionString": {
      "type": "string",
      "value": "[concat('HostName=', reference(resourceId('Microsoft.Devices/IoTHubs', parameters('iotHubName')), providers('Microsoft.Devices', 'IoTHubs').apiVersions[0]).hostName, ';SharedAccessKeyName=iothubowner;SharedAccessKey=', listKeys(resourceId('Microsoft.Devices/IotHubs', parameters('iotHubName')), providers('Microsoft.Devices', 'IoTHubs').apiVersions[0]).value[0].primaryKey)]"
    },
    "IoTHubEventHubCompatibleConnectionString": {
      "type": "string",
      "value": "[concat('Endpoint=', reference(resourceId('Microsoft.Devices/IoTHubs', parameters('iotHubName')), providers('Microsoft.Devices', 'IoTHubs').apiVersions[0]).eventHubEndpoints.events.endpoint, ';SharedAccessKeyName=iothubowner;SharedAccessKey=', listKeys(resourceId('Microsoft.Devices/IotHubs', parameters('iotHubName')), providers('Microsoft.Devices', 'IoTHubs').apiVersions[0]).value[0].primaryKey, ';EntityPath=', reference(resourceId('Microsoft.Devices/IoTHubs', parameters('iotHubName')), providers('Microsoft.Devices', 'IoTHubs').apiVersions[0]).eventHubEndpoints.events.path)]"
    }
  }
}

As you can notice, we take advantage of the ARM template function listKeys and the ARM template function providers.

The function providers is useful to get the latest API version for a specific namespace, whereas listkeys is the function that will allow us to get the properties for a specific key name.

By default when a new IoT hub is created, five access policies are created: iothubowner, service, device, registryRead and registryReadWrite. In our template we retrieve the primary connection string for the first one.

 

Example of use

The ARM template is now ready, let's open a Windows PowerShell and try it:

.\Deploy-AzureResourceGroup.ps1 -ResourceGroupName 'MyResourceGroupName' -ResourceGroupLocation 'canadaeast' -TemplateFile '.\azuredeploy.json'

...

OutputsString      :
                     Name                                      Type                       Value
                     ===============                           =========================  ==========
                     ioTHubConnectionString  String                     HostName=myIoTHubfkr54oehqy5pa.azure-devices.net;SharedAccessKeyName=iothubowner;SharedAccessKey=Vs38UdjTt5Wj1cV3Wji8e5bOx6nSsYJ/JA6ZrO6WOiA=
                     ioTHubEventHubCompatibleConnectionString  String                     Endpoint=sb://ihsuprodblres036dednamespace.servicebus.windows.net/;SharedAccessKeyName=iothubowner;SharedAccessKey=Vs38UdjTt5Wj1cV3Wji8e5bOx6nSsYJ/JA6ZrO6WOiA=;EntityPath=iothub-ehub-myiothubfk-1163803-9a6e8b6b6c

If everything goes well, you should see the same kind of output as above.

 

To go further

In the template we are outputting the connection string as an example. But in a more advance scenario with Azure Functions you could directly set the Function App application setting that require the connection string like the following:

{
  ...
  "resources": [
    {
      "apiVersion": "2016-08-01",
      "name": "[parameters('functionAppName']",
      "type": "Microsoft.Web/sites",
      "location": "[resourceGroup().location]",
      "kind": "functionapp",
      "dependsOn": [
        ...
        "[concat('Microsoft.Devices/IoTHubs', parameters('iotHubName'))]"
      ],
      "properties": {
        "siteConfig": {
          "appSettings": [
            {
              "name": "IoTHubConnectionString",
              "value": "[concat('Endpoint=', reference(resourceId('Microsoft.Devices/IoTHubs', parameters('iotHubName')), providers('Microsoft.Devices', 'IoTHubs').apiVersions[0]).eventHubEndpoints.events.endpoint, ';SharedAccessKeyName=iothubowner;SharedAccessKey=', listKeys(resourceId('Microsoft.Devices/IotHubs', parameters('iotHubName')), providers('Microsoft.Devices', 'IoTHubs').apiVersions[0]).value[0].primaryKey, ';EntityPath=', reference(resourceId('Microsoft.Devices/IoTHubs', parameters('iotHubName')), providers('Microsoft.Devices', 'IoTHubs').apiVersions[0]).eventHubEndpoints.events.path)]"
            }
          ]
        }
      }
    }
  ]
  ...
}

 

 

Summary

We have seen how to create an ARM template that will deploy an Azure IoT Hub and output the connection string and the Event Hub compatible connection string.

 

You can get the project source code here:

Browse the GitHub repository

 

Please feel free to comment or contact me if you have any question about this article.

Add a comment

(Will not be published)

Back to articles