Terraform-provider-azurerm: Azure IoT Hub device-2-cloud messages are not received by cloud, if IoT Hub created by terraform.

Created on 20 Feb 2019  路  13Comments  路  Source: terraform-providers/terraform-provider-azurerm

Community Note

  • Please vote on this issue by adding a 馃憤 reaction to the original issue to help the community and maintainers prioritize this request
  • Please do not leave "+1" or "me too" comments, they generate extra noise for issue followers and do not help prioritize the request
  • If you are interested in working on this issue or have submitted a pull request, please leave a comment

Terraform (and AzureRM Provider) Version

Terraform v0.11.11
+ provider.azurerm v1.22.0

Affected Resource(s)

azurerm_iothub

Terraform Configuration Files

resource "azurerm_iothub" "iot" {
  name                    = "name-your-tf-iot"
  resource_group_name     = "name-you-rg"
  location                = "westeurope"

  sku {
    name     = "S1"
    tier     = "Standard"
    capacity = "1"
  }
}

Expected Behavior

One of Azure IoT hub features is secure communication channel between devices and cloud, that can be done with direct methods:

  1. cloud side invokes direct methods to send commands or query data from devices
  2. devices receive these requests or commands
  3. devices send device-2-cloud messages
  4. cloud _listens_ to the messages from clause 3.

This flow works fine for IoT Hubs created from Azure Portal or with azure-cli

Actual Behavior

The _clause 4_ from "Expected Behavior" does not work for Azure IoT Hubs, created by terraform: Events that are sent from devices are not visible on cloud side.

Steps to Reproduce

  1. terraform apply

Important Factoids

We have already a running support request ticket with Azure Engineer, but no concrete results so far.

References

I created a github repository with samples to reproduce the issue: https://github.com/deepnetworkgmbh/azure-iot-directmethod-sample

enhancement serviciothub

Most helpful comment

Just add the default route for "events" while spinning up the IoT hub using Terraform and D2C events should flow through

route {
    name           = "defaultroute"
    source         = "DeviceMessages"
    condition      = "true"
    endpoint_names = ["events"]
    enabled        = true
  }

All 13 comments

Azure Support engineer gave up. We came to a conclusion that problem might be in:

  1. Terraform Azure provider
  2. Azure SDK for go
  3. Azure Resource Manager, that processes requests from the go sdk.

@tombuildsstuff I'm not sure if I interpreted the tags in a right way, but the issue is more likely to be bug, but not enhancement: this is not a new feature request.

Device-2-cloud channel is provided from the box when you create an IoT Hub. There is no dedicated _enable_ property for it. Even more, if you get IoT Hub description - you wouldn't find any part of it, that says if this communication channel works or not.
It just works... but not for terraform-provisioned IoT Hubs.

Could I help you somehow to investigate it in more details?

I found the reason of this behavior: https://github.com/Azure/azure-sdk-for-go/issues/4125#issuecomment-471355481

In few words: expandIoTHubEndpoints sets empty slices to endpoints, if user specified no custom ones. Unfortunately, it overrides internal built-in routing for device-2-cloud messages.

Does it make any sense to _fix_ tf-provider or better to _ask_ Azure team if they are going to correct it?

@v1r7u that behaviour is intentional, since otherwise there's no way to remove the endpoints - as such I don't think that's something which should be fixed at the API level.

That said - the IoTHubs API is different to other API's in that these have to be defined inline (since it's one API call) verses the other messaging API's which have separate resources/API's for sub-resources; so that we could determine how to proceed here, would it be possible to see an example of the default endpoints you're referring too?

Thanks!

I _guess_ it might be intentional for _user-defined_ endpoints and routes, but not for a built-one. Note, device-2-cloud endpoint itself is not deleted, only routing to it. But according to the same logic, it should - we're passing empty slice for endpoints too.

device-2-cloud messaging is a black box for end-user. I have no API to modify it. The only one way - described here issue, when routing is disappearing as a side-effect of another API call. And again, there is no way to find out, that routing is absent - only try to use it and get no events...

Official documentation is here.

Receive device-to-cloud messages. This endpoint is compatible with Azure Event Hubs. A back-end service can use it to read the device-to-cloud messages sent by your devices. You can create custom endpoints on your IoT hub in addition to this built-in endpoint.

Here is how these endpoints look from Azure Portal. You can see, a built-in one exists at the left part, but is not listed on the right one, which we're modifying using terrafrom
image

@v1r7u Did you have any luck resolving this? We're using Event Hub monitoring to see messages, but we've had to add the built-in message route to use the D2C Message Monitoring.

@mm19nn we embedded ARM template as a TF-resource and it works more or less fine for us. But still, it's workaround...

Any news on this? We are also running into the problem currently.

@midnightrun I think, this issue has very low priority, as it's not widely used and a kind of edge-case.

What can I propose.

  1. Manage IoT Hub with ARM template and make deployment of this ARM template from your terraform. We finally went this direction and it works more or less fine for us. If you want, I can share code-samples

  2. Create another Event Hub, add user-defined endpoint to IoT Hub and route device-2-cloud messages to this Event Hub instead of built-in endpoint. To be honest, I think this is a better way to go, as it gives you more options and flexibility.

If I'd re-do this setup from scratch, I'd go with the second option.

Thanks @v1r7u
The problem with ARM would be that Terraform can't track the state of those resources so it is suggested to wrap another Resource Group around AFAIK.

I will go the whole mile using a Event Hub.

Cheers!

Just add the default route for "events" while spinning up the IoT hub using Terraform and D2C events should flow through

route {
    name           = "defaultroute"
    source         = "DeviceMessages"
    condition      = "true"
    endpoint_names = ["events"]
    enabled        = true
  }

Confirming @hassant solution. Thanks!

I can confirm the same problem, and that the solution from @hassant works !

Was this page helpful?
0 / 5 - 0 ratings