• 3 min read
  • IoT Hub is a great, scalable way to manage your IoT devices. Did you know you can trigger an Azure Function when receiving a device-to-cloud message the same way you can for an Event Hub message?

    Building the Event Hub connection string

    Every IoT hub offers a read-only Event Hub-compatible endpoint that can be used with normal Event Hub consumers. This includes Azure Functions, which provides an Event Hub trigger.

    You can view your IoT Hub’s Event Hub-compatible by opening your IoT Hub resource in the Azure portal and navigating to the Endpoints blade, then clicking the Events (messages/events) endpoint. You will find the Event Hub-compatible name, and Event Hub-compatible endpoint (in the format of sb://iothub-ns-foo.servicebus.windows.net/) - keep note of these for later.

    IoT Hub - Access Policy

    Next, navigate to the IoT hub’s Shared Access Policies blade. You will need to either use one of the existing policies or add your own, and the policy you choose must have the Service connect permission. Click any policy to view its associated primary key.

    IoT Hub - Access Policy

    Now, we can use these four pieces of information to construct an Event Hub connection string, which follows the format Endpoint=sb://EH_COMPATIBLE_ENDPOINT;EntityPath=EH_COMPATIBLE_NAME;SharedAccessKeyNa‌​me=IOTHUB_POLICY_NAME;Share‌​dAccessKey=IOTHUB_POLICY_KEY.

    Configuring Azure Functions

    We will now setup an Azure Function with a trigger using the Event Hub-compatible information.

    Open the Azure Function resource and switch to the Integrate tab. Add a new trigger and choose Event Hub, which will reveal the following settings page:

    Azure Functions - Trigger configuration

    Enter the Event Hub-compatible name collected from IoT Hub earlier under Event Hub name and then press new to enter the Event Hub connection string derived earlier.

    Azure Functions - Configure connection string

    Lastly, we need to add code under the Develop tab with a parameter that matches the Event parameter name field, so use the following:

    using System;
    
    public static void Run(string myEventHubMessage, TraceWriter log)
    {
        log.Info($"C# Queue trigger function processed: {myEventHubMessage}");
    }

    Testing the connection

    Under the Function’s Develop tab, click the Logs button from the toolbar to open the execution log. Next, send a cloud-to-device message — if you haven’t setup a device, simple_sample_device.js from the IoT Hub Node.js SDK does nicely.

    After sending your message, you should see that your Function triggered successfully.

    What about in ARM templates?

    This manual setup is fine for testing, but what about automation for when moving to production?

    ARM templates provide a reference() function that resolves a resource’s runtime state. It’s perfect for obtaining the Event Hub-compatible name that was provisioned as it was created:

        ...
        "parameters": {
            "iotHubName": {
                "defaultValue": "iothub2functions",
                "type": "String"
            }
        },
        "variables": {
            "iotHubApiVersion": "2016-02-03",
            "iotHubPolicyName": "service"
        },
        "outputs": {
            "eventHubConnectionString": {
                "type": "string",
                "value": "[concat('Endpoint=',reference(resourceId('Microsoft.Devices/IoTHubs',parameters('iotHubName'))).eventHubEndpoints.events.endpoint,';EntityPath=',reference(resourceId('Microsoft.Devices/IoTHubs',parameters('iotHubName'))).eventHubEndpoints.events.path,';SharedAccessKeyName=',variables('iotHubPolicyName'),';SharedAccessKey=',listKeys(resourceId('Microsoft.Devices/IotHubs/Iothubkeys', parameters('iotHubName'),variables('iotHubPolicyName')), variables('iotHubApiVersion')).primaryKey)]"
            }
        },
        ...