title | description | services | keywords | author | ms.author | ms.date | ms.topic | ms.service | ms.custom |
---|---|---|---|---|---|---|---|---|---|
Develop and debug modules for Azure IoT Edge | Microsoft Docs |
Use Visual Studio Code to develop, build, and debug a module for Azure IoT Edge using C#, Python, Node.js, Java, or C |
iot-edge |
kgremban |
kgremban |
08/07/2019 |
conceptual |
iot-edge |
devx-track-js |
[!INCLUDE iot-edge-version-all-supported]
You can turn your business logic into modules for Azure IoT Edge. This article shows you how to use Visual Studio Code as the main tool to develop and debug modules.
There are two ways to debug modules written in C#, Node.js, or Java in Visual Studio Code: You can either attach a process in a module container or launch the module code in debug mode. To debug modules written in Python or C, you can only attach to a process in Linux amd64 containers.
If you aren't familiar with the debugging capabilities of Visual Studio Code, read about Debugging.
This article provides instructions for developing and debugging modules in multiple languages for multiple architectures. Currently, Visual Studio Code provides support for modules written in C#, C, Python, Node.js, and Java. The supported device architectures are X64 and ARM32. For more information about supported operating systems, languages, and architectures, see Language and architecture support.
Note
Develop and debugging support for Linux ARM64 devices is in public preview. For more information, see Develop and debug ARM64 IoT Edge modules in Visual Studio Code (preview).
You can use a computer or a virtual machine running Windows, macOS, or Linux as your development machine. On Windows computers you can develop either Windows or Linux modules. To develop Windows modules, use a Windows computer running version 1809/build 17763 or newer. To develop Linux modules, use a Windows computer that meets the requirements for Docker Desktop.
Install Visual Studio Code first and then add the following extensions:
- Azure IoT Tools
- Docker extension
- Visual Studio extension(s) specific to the language you're developing in:
- C#, including Azure Functions: C# extension
- Python: Python extension
- Java: Java Extension Pack for Visual Studio Code
- C: C/C++ extension
You'll also need to install some additional, language-specific tools to develop your module:
-
C#, including Azure Functions: .NET Core 2.1 SDK
-
Python: Python and Pip for installing Python packages (typically included with your Python installation).
-
Node.js: Node.js. You'll also want to install Yeoman and the Azure IoT Edge Node.js Module Generator.
-
Java: Java SE Development Kit 10 and Maven. You'll need to set the
JAVA_HOME
environment variable to point to your JDK installation.
To build and deploy your module image, you need Docker to build the module image and a container registry to hold the module image:
-
Docker Community Edition on your development machine.
-
Azure Container Registry or Docker Hub
[!TIP] You can use a local Docker registry for prototype and testing purposes instead of a cloud registry.
Unless you're developing your module in C, you also need the Python-based Azure IoT EdgeHub Dev Tool in order to set up your local development environment to debug, run, and test your IoT Edge solution. If you haven't already done so, install Python (2.7/3.6/3.7) and Pip and then install iotedgehubdev by running this command in your terminal.
pip install --upgrade iotedgehubdev
Note
Currently, iotedgehubdev uses a docker-py library that is not compatible with Python 3.8.
If you have multiple Python including pre-installed python 2.7 (for example, on Ubuntu or macOS), make sure you are using the correct pip
or pip3
to install iotedgehubdev
To test your module on a device, you'll need an active IoT hub with at least one IoT Edge device. To use your computer as an IoT Edge device, follow the steps in the quickstart for Linux or Windows. If you are running IoT Edge daemon on your development machine, you might need to stop EdgeHub and EdgeAgent before you move to next step.
The following steps show you how to create an IoT Edge module in your preferred development language (including Azure Functions, written in C#) using Visual Studio Code and the Azure IoT Tools. You start by creating a solution, and then generating the first module in that solution. Each solution can contain multiple modules.
-
Select View > Command Palette.
-
In the command palette, enter and run the command Azure IoT Edge: New IoT Edge Solution.
-
Browse to the folder where you want to create the new solution and then select Select folder.
-
Enter a name for your solution.
-
Select a module template for your preferred development language to be the first module in the solution.
-
Enter a name for your module. Choose a name that's unique within your container registry.
-
Provide the name of the module's image repository. Visual Studio Code autopopulates the module name with localhost:5000/<your module name>. Replace it with your own registry information. If you use a local Docker registry for testing, then localhost is fine. If you use Azure Container Registry, then use the login server from your registry's settings. The login server looks like <registry name>.azurecr.io. Only replace the localhost:5000 part of the string so that the final result looks like <registry name>.azurecr.io/<your module name>.
Visual Studio Code takes the information you provided, creates an IoT Edge solution, and then loads it in a new window.
There are four items within the solution:
-
A .vscode folder contains debug configurations.
-
A modules folder has subfolders for each module. Within the folder for each module there is a file, module.json, that controls how modules are built and deployed. This file would need to be modified to change the module deployment container registry from localhost to a remote registry. At this point, you only have one module. But you can add more in the command palette with the command Azure IoT Edge: Add IoT Edge Module.
-
An .env file lists your environment variables. If Azure Container Registry is your registry, you'll have an Azure Container Registry username and password in it.
In production scenarios, we recommend using service principals to provide access to your container registry instead of the .env file. For more information, see Manage access to your container registry.
[!NOTE] The environment file is only created if you provide an image repository for the module. If you accepted the localhost defaults to test and debug locally, then you don't need to declare environment variables.
-
A deployment.template.json file lists your new module along with a sample SimulatedTemperatureSensor module that simulates data you can use for testing. For more information about how deployment manifests work, see Learn how to use deployment manifests to deploy modules and establish routes.
To see how the simulated temperature module works, view the SimulatedTemperatureSensor.csproj source code.
To add additional modules to your solution, run the command Azure IoT Edge: Add IoT Edge Module from the command palette. You can also right-click the modules folder or the deployment.template.json
file in the Visual Studio Code Explorer view and then select Add IoT Edge Module.
The default module code that comes with the solution is located at the following location:
- Azure Function (C#): modules > <your module name> > <your module name>.cs
- C#: modules > <your module name> > Program.cs
- Python: modules > <your module name> > main.py
- Node.js: modules > <your module name> > app.js
- Java: modules > <your module name> > src > main > java > com > edgemodulemodules > App.java
- C: modules > <your module name> > main.c
The module and the deployment.template.json file are set up so that you can build the solution, push it to your container registry, and deploy it to a device to start testing without touching any code. The module is built to simply take input from a source (in this case, the SimulatedTemperatureSensor module that simulates data) and pipe it to IoT Hub.
When you're ready to customize the template with your own code, use the Azure IoT Hub SDKs to build modules that address the key needs for IoT solutions such as security, device management, and reliability.
If you're developing in C#, Node.js, or Java, your module requires use of a ModuleClient object in the default module code so that it can start, run, and route messages. You'll also use the default input channel input1 to take action when the module receives messages.
On your development machine, you can start an IoT Edge simulator instead of installing the IoT Edge security daemon so that you can run your IoT Edge solution.
- In the Explorer tab on the left side, expand the Azure IoT Hub section. Right-click on your IoT Edge device ID, and then select Setup IoT Edge Simulator to start the simulator with the device connection string.
- You can see the IoT Edge Simulator has been successfully set up by reading the progress detail in the integrated terminal.
To set up and start the simulator, run the command Azure IoT Edge: Start IoT Edge Hub Simulator for Single Module from the Visual Studio Code command palette. When prompted, use the value input1 from the default module code (or the equivalent value from your code) as the input name for your application. The command triggers the iotedgehubdev CLI and then starts the IoT Edge simulator and a testing utility module container. You can see the outputs below in the integrated terminal if the simulator has been started in single module mode successfully. You can also see a curl
command to help send message through. You will use it later.
You can use the Docker Explorer view in Visual Studio Code to see the module's running status.
The edgeHubDev container is the core of the local IoT Edge simulator. It can run on your development machine without the IoT Edge security daemon and provides environment settings for your native module app or module containers. The input container exposes REST APIs to help bridge messages to the target input channel on your module.
-
Prepare your environment for debugging according to the requirements of your development language, set a breakpoint in your module, and select the debug configuration to use:
-
C#
-
In the Visual Studio Code integrated terminal, change the directory to the <your module name> folder, and then run the following command to build .NET Core application.
dotnet build
-
Open the file
Program.cs
and add a breakpoint. -
Navigate to the Visual Studio Code Debug view by selecting View > Debug. Select the debug configuration <your module name> Local Debug (.NET Core) from the dropdown.
[!NOTE] If your .NET Core
TargetFramework
is not consistent with your program path inlaunch.json
, you'll need to manually update the program path inlaunch.json
to match theTargetFramework
in your .csproj file so that Visual Studio Code can successfully launch this program.
-
-
Node.js
-
In the Visual Studio Code integrated terminal, change the directory to the <your module name> folder, and then run the following command to install Node packages
npm install
-
Open the file
app.js
and add a breakpoint. -
Navigate to the Visual Studio Code Debug view by selecting View > Debug. Select the debug configuration <your module name> Local Debug (Node.js) from the dropdown.
-
-
Java
-
Open the file
App.java
and add a breakpoint. -
Navigate to the Visual Studio Code Debug view by selecting View > Debug. Select the debug configuration <your module name> Local Debug (Java) from the dropdown.
-
-
-
Click Start Debugging or press F5 to start the debug session.
-
In the Visual Studio Code integrated terminal, run the following command to send a Hello World message to your module. This is the command shown in previous steps when you set up IoT Edge simulator.
curl --header "Content-Type: application/json" --request POST --data '{"inputName": "input1","data":"hello world"}' http://localhost:53000/api/v1/messages
[!NOTE] If you are using Windows, making sure the shell of your Visual Studio Code integrated terminal is Git Bash or WSL Bash. You cannot run the
curl
command from a PowerShell or command prompt. [!TIP] You can also use PostMan or other API tools to send messages through instead ofcurl
. -
In the Visual Studio Code Debug view, you'll see the variables in the left panel.
-
To stop your debugging session, select the Stop button or press Shift + F5, and then run Azure IoT Edge: Stop IoT Edge Simulator in the command palette to stop the simulator and clean up.
Your default solution contains two modules, one is a simulated temperature sensor module and the other is the pipe module. The simulated temperature sensor sends messages to the pipe module and then the messages are piped to the IoT Hub. In the module folder you created, there are several Docker files for different container types. Use any of the files that end with the extension .debug to build your module for testing.
Currently, debugging in attach mode is supported only as follows:
- C# modules, including those for Azure Functions, support debugging in Linux amd64 containers
- Node.js modules support debugging in Linux amd64 and arm32v7 containers, and Windows amd64 containers
- Java modules support debugging in Linux amd64 and arm32v7 containers
Tip
You can switch among options for the default platform for your IoT Edge solution by clicking the item in the Visual Studio Code status bar.
In your development machine, you can start an IoT Edge simulator instead of installing the IoT Edge security daemon so that you can run your IoT Edge solution.
-
In the Explorer tab on the left side, expand the Azure IoT Hub section. Right-click on your IoT Edge device ID, and then select Setup IoT Edge Simulator to start the simulator with the device connection string.
-
You can see the IoT Edge Simulator has been successfully set up by reading the progress detail in the integrated terminal.
-
Open your module file (
Program.cs
,app.js
,App.java
, or<your module name>.cs
) and add a breakpoint. -
In the Visual Studio Code Explorer view, right-click the
deployment.debug.template.json
file for your solution and then select Build and Run IoT Edge solution in Simulator. You can watch all the module container logs in the same window. You can also navigate to the Docker view to watch container status. -
Navigate to the Visual Studio Code Debug view and select the debug configuration file for your module. The debug option name should be similar to <your module name> Remote Debug
-
Select Start Debugging or press F5. Select the process to attach to.
-
In Visual Studio Code Debug view, you'll see the variables in the left panel.
-
To stop the debugging session, first select the Stop button or press Shift + F5, and then select Azure IoT Edge: Stop IoT Edge Simulator from the command palette.
Note
The preceding example shows how to debug IoT Edge modules on containers. It added exposed ports to your module's container createOptions
settings. After you finish debugging your modules, we recommend you remove these exposed ports for production-ready IoT Edge modules.
For modules written in C#, including Azure Functions, this example is based on the debug version of Dockerfile.amd64.debug
, which includes the .NET Core command-line debugger (VSDBG) in your container image while building it. After you debug your C# modules, we recommend that you directly use the Dockerfile without VSDBG for production-ready IoT Edge modules.
In each module folder, there are several Docker files for different container types. Use any of the files that end with the extension .debug to build your module for testing.
When debugging modules using this method, your modules are running on top of the IoT Edge runtime. The IoT Edge device and your Visual Studio Code can be on the same machine, or more typically, Visual Studio Code is on the development machine and the IoT Edge runtime and modules are running on another physical machine. In order to debug from Visual Studio Code, you must:
- Set up your IoT Edge device, build your IoT Edge module(s) with the .debug Dockerfile, and then deploy to the IoT Edge device.
- Expose the IP and port of the module so that the debugger can be attached.
- Update the
launch.json
so that Visual Studio Code can attach to the process in the container on the remote machine. This file is located in the.vscode
folder in your workspace and updates each time you add a new module that supports debugging.
-
In Visual Studio Code, open the
deployment.debug.template.json
file, which contains the debug version of your module images with the propercreateOptions
values set. -
If you're developing your module in Python, follow these steps before proceeding:
-
Open the file
main.py
and add this code after the import section:import ptvsd ptvsd.enable_attach(('0.0.0.0', 5678))
-
Add the following single line of code to the callback you want to debug:
ptvsd.break_into_debugger()
For example, if you want to debug the
receive_message_listener
function, you would insert that line of code as shown below:def receive_message_listener(client): ptvsd.break_into_debugger() global RECEIVED_MESSAGES while True: message = client.receive_message_on_input("input1") # blocking call RECEIVED_MESSAGES += 1 print("Message received on input1") print( " Data: <<{}>>".format(message.data) ) print( " Properties: {}".format(message.custom_properties)) print( " Total calls received: {}".format(RECEIVED_MESSAGES)) print("Forwarding message to output1") client.send_message_to_output(message, "output1") print("Message successfully forwarded")
-
-
In the Visual Studio Code command palette:
-
Run the command Azure IoT Edge: Build and Push IoT Edge solution.
-
Select the
deployment.debug.template.json
file for your solution.
-
-
In the Azure IoT Hub Devices section of the Visual Studio Code Explorer view:
-
Right-click an IoT Edge device ID and then select Create Deployment for Single Device.
[!TIP] To confirm that the device you've chosen is an IoT Edge device, select it to expand the list of modules and verify the presence of $edgeHub and $edgeAgent. Every IoT Edge device includes these two modules.
-
Navigate to your solution's config folder, select the
deployment.debug.amd64.json
file, and then select Select Edge Deployment Manifest.
-
You'll see the deployment successfully created with a deployment ID in the integrated terminal.
You can check your container status by running the docker ps
command in the terminal. If your Visual Studio Code and IoT Edge runtime are running on the same machine, you can also check the status in the Visual Studio Code Docker view.
You can skip this section if your modules are running on the same machine as Visual Studio Code, as you are using localhost to attach to the container and already have the correct port settings in the .debug Dockerfile, module's container createOptions
settings, and launch.json
file. If your modules and Visual Studio Code are running on separate machines, follow the steps for your development language.
-
C#, including Azure Functions
Configure the SSH channel on your development machine and IoT Edge device and then edit
launch.json
file to attach. -
Node.js
-
Make sure the module on the machine to be debugged is running and ready for debuggers to attach, and that port 9229 is accessible externally. You can verify this by opening
http://<target-machine-IP>:9229/json
on the debugger machine. This URL should show information about the Node.js module to be debugged. -
On your development machine, open Visual Studio Code and then edit
launch.json
so that the address value of the <your module name> Remote Debug (Node.js) profile (or <your module name> Remote Debug (Node.js in Windows Container) profile if the module is running as a Windows container) is the IP of the machine being debugged.
-
-
Java
-
Build an SSH tunnel to the machine to be debugged by running
ssh -f <username>@<target-machine> -L 5005:127.0.0.1:5005 -N
. -
On your development machine, open Visual Studio Code and edit the <your module name> Remote Debug (Java) profile in
launch.json
so that you can attach to the target machine. To learn more about editinglaunch.json
and debugging Java with Visual Studio Code, see the section on configuring the debugger.
-
-
Python
-
Make sure that port 5678 on the machine to be debugged is open and accessible.
-
In the code
ptvsd.enable_attach(('0.0.0.0', 5678))
that you earlier inserted intomain.py
, change 0.0.0.0 to the IP address of the machine to be debugged. Build, push, and deploy your IoT Edge module again. -
On your development machine, open Visual Studio Code and then edit
launch.json
so that thehost
value of the <your module name> Remote Debug (Python) profile uses the IP address of the target machine instead oflocalhost
.
-
-
In the Visual Studio Code Debug view, select the debug configuration file for your module. The debug option name should be similar to <your module name> Remote Debug
-
Open the module file for your development language and add a breakpoint:
- Azure Function (C#): Add your breakpoint to the file
<your module name>.cs
. - C#: Add your breakpoint to the file
Program.cs
. - Node.js: Add your breakpoint to the file
app.js
. - Java: Add your breakpoint to the file
App.java
. - Python: Add your breakpoint to the file
main.py
in the callback method where you added theptvsd.break_into_debugger()
line. - C: Add your breakpoint to the file
main.c
.
- Azure Function (C#): Add your breakpoint to the file
-
Select Start Debugging or select F5. Select the process to attach to.
-
In the Visual Studio Code Debug view, you'll see the variables in the left panel.
Note
The preceding example shows how to debug IoT Edge modules on containers. It added exposed ports to your module's container createOptions
settings. After you finish debugging your modules, we recommend you remove these exposed ports for production-ready IoT Edge modules.
With recent changes in both the Docker and Moby engines to support SSH connections, and a new setting in Azure IoT Tools that enables injection of environment settings into the Visual Studio Code command palette and Azure IoT Edge terminals, you can now build and debug modules on remote devices.
See this IoT Developer blog entry for more information and step-by-step instructions.
After you've built your module, learn how to deploy Azure IoT Edge modules from Visual Studio Code.
To develop modules for your IoT Edge devices, Understand and use Azure IoT Hub SDKs.