6

I am about to script the deployment of our Azure solution. For that reason I create an Azure IoTHub with a Resource Manager Template. This works very well. But the problem is, I need the Event Hub-compatible endpoint string for further deployments.

See: https://picload.org/image/rrdopcia/untitled.png

I think, the solution would be, to output it in the template, but I cant get it to work.

The output-section of my template.json actually looks like this:

    "outputs": {
    "clusterProperties": {
        "value": "[reference(parameters('clusterName'))]",
        "type": "object"
    },
    "iotHubHostName": {
        "type": "string",
        "value": "[reference(variables('iotHubResourceId')).hostName]"
    },
    "iotHubConnectionString": {
        "type": "string",
        "value": "[concat('HostName=', reference(variables('iotHubResourceId')).hostName, ';SharedAccessKeyName=', variables('iotHubKeyName'), ';SharedAccessKey=', listkeys(variables('iotHubKeyResource'), variables('iotHubVersion')).primaryKey)]"
    }
   }

And here are the variables I used:

    "variables": {
    "iotHubVersion": "2016-02-03",
    "iotHubResourceId": "[resourceId('Microsoft.Devices/Iothubs', parameters('iothubname'))]",
    "iotHubKeyName": "iothubowner",
    "iotHubKeyResource": "[resourceId('Microsoft.Devices/Iothubs/Iothubkeys', parameters('iothubname'), variables('iotHubKeyName'))]",
},
ErBeEn
  • 175
  • 2
  • 11
  • You are creating the Azure IoTHub with the ARM template, right? So, instead of using `variables('iotHubResourceId')`, you should use `parameters('iotHubName')`, because "resource id" should be use for resources outside the template while "resource name" should be use for resources inside the template. Take a look at [this article](https://azure.microsoft.com/en-us/documentation/articles/resource-group-template-functions/#_reference) – Jack Zeng Jul 11 '16 at 06:40
  • What are you deploying later that needs the Event Hub-compatible connection information? For example, if you are connecting Azure Stream Analytics to an IoT Hub, you can do so without using the Event Hub-compatible connection information. – Dominic Betts Jul 11 '16 at 13:46
  • Thanks for the answer @DominicBetts. We have a Service Fabric actor which sends data to the endpoint. I will definitely check, if there is another possibility to connect to the IoT Hub. Is it possible to generate the connection string on my own? `sb://iothubname-xxxxx-xxxxxxxxxx.servicebus.windows.net/` I can not figure out, how the number is generated (the x'es). – ErBeEn Jul 14 '16 at 10:53
  • I'm not sure what you mean when you say "We have a Service Fabric actor which sends data to the endpoint". The Event Hub-compatible endpoint on an IoT Hub is a read-only endpoint for reading messages that a device sent to the hub. There's no way to generate the connection string yourself - IoT Hub generates the name with x'es. – Dominic Betts Jul 14 '16 at 13:19
  • I am using the EventHubProcessorHost nuget package to process events from the IoTHub, which requires the Event Hub-compatible connection string. I tried defining the endpoint in my ARM template but it is ignored and Azure is just auto-generating it - big bummer! Really need an answer to the question of how to read the EventHub endpoint out of the ARM template. – bojingo Oct 12 '16 at 17:08

1 Answers1

4

You can read the endpoint from the provisioned IoT Hub within the ARM template and build a connection string like this:

"EventHubConnectionString": "[concat('Endpoint=',reference(resourceId('Microsoft.Devices/IoTHubs',parameters('iothub_name'))).eventHubEndpoints.events.endpoint,';SharedAccessKeyName=iothubowner;SharedAccessKey=',listKeys(resourceId('Microsoft.Devices/IotHubs',parameters('iothub_name')),variables('devices_provider_apiversion')).value[0].primaryKey)]"

The important bit to get the EventHub-compatible endpoint was: resourceId('Microsoft.Devices/IoTHubs', parameters('iothub_name'))).eventHubEndpoints.events.endpoint

That was ripped out of my working ARM template. For clarity, here are some details about the variables/parameters in the above:

  1. variables('devices_provider_apiversion') is "2016-02-03"
  2. parameters('iothub_name') is the name of the IoT Hub that same ARM template is provisioning elsewhere in the template
  3. The output of "listKeys" returns a array of key objects, where in my case the first item was "iothubowner". (... I like the approach to get this described in the question better. :)

One helpful trick that helped me learn what is available for me to read from the resources during execution of the ARM template is to output the entire resource and then find the property I am interested in. Here is how I output all details of the IoT Hub from running the ARM template:

"outputs": {
    "iotHub": {
        "value": "[reference(resourceId('Microsoft.Devices/IoTHubs',parameters('iothub_name')))]",
        "type": "object"
    }
}

You can also use this method to output the endpoint (among other things) to be used as input to other templates.

bojingo
  • 572
  • 1
  • 6
  • 12