Skip to content

Files

Latest commit

916ce3b · Jun 6, 2022

History

History
200 lines (120 loc) · 14.2 KB

module-development.md

File metadata and controls

200 lines (120 loc) · 14.2 KB
title description author ms.author ms.date ms.topic ms.service services
Develop modules for Azure IoT Edge | Microsoft Docs
Develop custom modules for Azure IoT Edge that can communicate with the runtime and IoT Hub
PatAltimore
patricka
09/03/2021
conceptual
iot-edge
iot-edge

Develop your own IoT Edge modules

[!INCLUDE iot-edge-version-201806-or-202011]

Azure IoT Edge modules can connect with other Azure services and contribute to your larger cloud data pipeline. This article describes how you can develop modules to communicate with the IoT Edge runtime and IoT Hub, and therefore the rest of the Azure cloud.

IoT Edge runtime environment

The IoT Edge runtime provides the infrastructure to integrate the functionality of multiple IoT Edge modules and to deploy them onto IoT Edge devices. Any program can be packaged as an IoT Edge module. To take full advantage of IoT Edge communication and management functionalities, a program running in a module can use the Azure IoT Device SDK to connect to the local IoT Edge hub. ::: moniker range=">=iotedge-2020-11" Modules can also use any MQTT client to connect to the local IoT Edge hub MQTT broker. ::: moniker-end

Packaging your program as an IoT Edge module

To deploy your program on an IoT Edge device, it must first be containerized and run with a Docker-compatible engine. IoT Edge uses Moby, the open-source project behind Docker, as its Docker-compatible engine. The same parameters that you're used to with Docker can be passed to your IoT Edge modules. For more information, see How to configure container create options for IoT Edge modules.

Using the IoT Edge hub

The IoT Edge hub provides two main functionalities: proxy to IoT Hub, and local communications.

Connecting to IoT Edge hub from a module

Connecting to the local IoT Edge hub from a module involves the same connection steps as for any clients. For more information, see Connecting to the IoT Edge hub.

To use IoT Edge routing over AMQP or MQTT, you can use the ModuleClient from the Azure IoT SDK. Create a ModuleClient instance to connect your module to the IoT Edge hub running on the device, similar to how DeviceClient instances connect IoT devices to IoT Hub. For more information about the ModuleClient class and its communication methods, see the API reference for your preferred SDK language: C#, C, Python, Java, or Node.js.

::: moniker range=">=iotedge-2020-11"

To use IoT Edge MQTT broker, you need to bring your own MQTT client and initiate the connection yourself with information that you retrieve from the IoT Edge daemon workload API.

For more information about choosing between routing or publishing/subscribing with the MQTT broker, see Local communication.

MQTT broker primitives

Send a message on a user-defined topic

With the IoT Edge MQTT broker, you can publish messages on any user-defined topics. To do so, authorize your module to publish on specific topics then get a token from the workload API to use as a password when connecting to the MQTT broker, and finally publish messages on the authorized topics with the MQTT client of your choice.

Receive messages on a user-defined topic

With the IoT Edge MQTT broker, receiving messages is similar. First make sure that your module is authorized to subscribe to specific topics, then get a token from the workload API to use as a password when connecting to the MQTT broker, and finally subscribe to messages on the authorized topics with the MQTT client of your choice.

Note

IoT Edge MQTT broker (currently in preview) will not move to general availability and will be removed from the future version of IoT Edge Hub. We appreciate the feedback we received on the preview, and we are continuing to refine our plans for an MQTT broker. In the meantime, if you need a standards-compliant MQTT broker on IoT Edge, consider deploying an open-source broker like Mosquitto as an IoT Edge module.

::: moniker-end

IoT Hub primitives

IoT Hub sees a module instance analogously to a device, in the sense that:

Currently, modules can't receive cloud-to-device messages or use the file upload feature.

When writing a module, you can connect to the IoT Edge hub and use IoT Hub primitives as you would when using IoT Hub with a device application. The only difference between IoT Edge modules and IoT device applications is that you have to refer to the module identity instead of the device identity.

Device-to-cloud messages

An IoT Edge module can send messages to the cloud via the IoT Edge hub that acts as a local broker and propagates messages to the cloud. To enable complex processing of device-to-cloud messages, an IoT Edge module can also intercept and process messages sent by other modules or devices to its local IoT Edge hub and send new messages with processed data. Chains of IoT Edge modules can thus be created to build local processing pipelines.

To send device-to-cloud telemetry messages using routing, use the ModuleClient of the Azure IoT SDK. With the Azure IoT SDK, each module has the concept of module input and output endpoints, which map to special MQTT topics. Use the ModuleClient.sendMessageAsync method and it will send messages on the output endpoint of your module. Then configure a route in edgeHub to send this output endpoint to IoT Hub.

::: moniker range=">=iotedge-2020-11"

Sending device-to-cloud telemetry messages with the MQTT broker is similar to publishing messages on user-defined topics, but using the following IoT Hub special topic for your module: devices/<device_name>/modules/<module_name>/messages/events. Authorizations must be set up appropriately. The MQTT bridge must also be configured to forward the messages on this topic to the cloud.

::: moniker-end

To process messages using routing, first set up a route to send messages coming from another endpoint (module or device) to the input endpoint of your module, then listen for messages on the input endpoint of your module. Each time a new message comes back, a callback function is triggered by the Azure IoT SDK. Process your message with this callback function and optionally send new messages on your module endpoint queue.

::: moniker range=">=iotedge-2020-11"

Processing messages using the MQTT broker is similar to subscribing to messages on user-defined topics, but using the IoT Edge special topics of your module's output queue: devices/<device_name>/modules/<module_name>/messages/events. Authorizations must be set up appropriately. Optionally you can send new messages on the topics of your choice.

::: moniker-end

Twins

Twins are one of the primitives provided by IoT Hub. There are JSON documents that store state information including metadata, configurations, and conditions. Each module or device has its own twin.

To get a module twin with the Azure IoT SDK, call the ModuleClient.getTwin method.

::: moniker range=">=iotedge-2020-11"

To get a module twin with any MQTT client, slightly more work is involved since getting a twin is not a typical MQTT pattern. The module must first subscribe to IoT Hub special topic $iothub/twin/res/#. This topic name is inherited from IoT Hub, and all devices/modules need to subscribe to the same topic. It does not mean that devices receive the twin of each other. IoT Hub and edgeHub know which twin should be delivered where, even if all devices listen to the same topic name. Once the subscription is made, the module needs to ask for the twin by publishing a message to the following IoT Hub special topic with a request ID $iothub/twin/GET/?$rid=1234. This request ID is an arbitrary ID (that is, a GUID), which will be sent back by IoT Hub along with the requested data. This is how a client can pair its requests with the responses. The result code is a HTTP-like status code, where successful is encoded as 200.

::: moniker-end

To receive a module twin patch with the Azure IoT SDK, implement a callback function and register it with the ModuleClient.moduleTwinCallback method from the Azure IoT SDK so that your callback function is triggered each time that a twin patch comes in.

::: moniker range=">=iotedge-2020-11"

To receive a module twin patch with any MQTT client, the process is similar to receiving full twins: a client needs to subscribe to special IoT Hub topic $iothub/twin/PATCH/properties/desired/#. After the subscription is made, when IoT Hub sends a change of the desired section of the twin, the client receives it.

::: moniker-end

Receive direct methods

To receive a direct method with the Azure IoT SDK, implement a callback function and register it with the ModuleClient.methodCallback method from the Azure IoT SDK so that your callback function is triggered each time that a direct method comes in.

::: moniker range=">=iotedge-2020-11"

To receive a direct method with any MQTT client, the process is very similar to receiving twin patches. The client needs to confirm back that it has received the call and can send back some information at the same time. Special IoT Hub topic to subscribe to is $iothub/methods/POST/#.

::: moniker-end

Language and architecture support

IoT Edge supports multiple operating systems, device architectures, and development languages so that you can build the scenario that matches your needs. Use this section to understand your options for developing custom IoT Edge modules. You can learn more about tooling support and requirements for each language in Prepare your development and test environment for IoT Edge.

Linux

For all languages in the following table, IoT Edge supports development for AMD64 and ARM32 Linux containers.

Development language Development tools
C Visual Studio Code
Visual Studio 2017/2019
C# Visual Studio Code
Visual Studio 2017/2019
Java Visual Studio Code
Node.js Visual Studio Code
Python Visual Studio Code

Note

For cross-platform compilation, like compiling an ARM32 IoT Edge module on an AMD64 development machine, you need to configure the development machine to compile code on target device architecture matching the IoT Edge module. For more information, see Build and debug IoT Edge modules on your remote device to configure the development machine to compile code on target device architecture matching the IoT Edge module.

In addition, support for ARM64 Linux containers is in public preview. For more information, see Develop and debug ARM64 IoT Edge modules in Visual Studio Code (preview).

Windows

:::moniker range="iotedge-2018-06" For all languages in the following table, IoT Edge supports development for AMD64 Windows containers.

Development language Development tools
C Visual Studio 2017/2019
C# Visual Studio Code (no debugging capabilities)
Visual Studio 2017/2019
:::moniker-end

:::moniker range=">=iotedge-2020-11"

IoT Edge 1.1 LTS is the last release channel that supports Windows containers. Starting with version 1.2, Windows containers are not supported.

For information about developing with Windows containers, refer to the IoT Edge 1.1 version of this article.

:::moniker-end

Module security

You should develop your modules with security in mind. To learn more about securing your modules, see Docker security.

To help improve module security, IoT Edge disables some container features by default. You can override the defaults to provide privileged capabilities to your modules if necessary.

Allow elevated Docker permissions

In the config file on an IoT Edge device, there's a parameter called allow_elevated_docker_permissions. When set to true, this flag allows the --privileged flag as well as any additional capabilities that you define in the CapAdd field of the Docker HostConfig in the container create options.

Note

Currently, this flag is true by default, which allows deployments to grant privileged permissions to modules. We recommend that you set this flag to false to improve device security. In the future, this flag will be set to false by default.

Enable CAP_CHOWN and CAP_SETUID

The Docker capabilities CAP_CHOWN and CAP_SETUID are disabled by default. These capabilities can be used to write to secure files on the host device and potentially gain root access.

If you need these capabilities, you can manually re-enable them using CapADD in the container create options.

Next steps

Prepare your development and test environment for IoT Edge

Use Visual Studio to develop C# modules for IoT Edge

Use Visual Studio Code to develop modules for IoT Edge

Understand and use Azure IoT Hub SDKs