Easily build and debug IoT Edge modules on your remote device with Azure IoT Edge for VS Code 1.9.0.

Xin Shi

Recently, both Docker and Moby engine support SSH connection, which means you can connect a remote Docker engine more easily than before. In Azure IoT Edge for VS Code 1.9.0, we introduced a new extension setting(azure-iot-edge.executor.env) to inject environment variables into VS Code terminals. By leveraging the new setting and the new SSH connection feature, you can easily complete the tasks below now.

  • Build IoT Edge module images on a remote device.
  • Debug running modules on a remote device.

Since we can rely on the container engine on the remote machine, we can now run VS Code on our amd64 development machine and build images with an arm device. I’d like to use Raspberry Pi as my IoT Edge device and my macOS as the development environment. I will show how easy to build and debug arm32 module images with the new feature in VS Code. Let’s see how it works.


Setup your Raspberry Pi

  • Install Raspbian on your Raspberry Pi by following this tutorial.
  • Setup your Raspberry Pi as an IoT Edge device – Follow the instructions to install Azure IoT Edge runtime on Linux(arm32v7/armhf).
  • Passwordless SSH access to your Raspberry Pi. (Due to this issue, till Feb 2019, you cannot use username/password for your Docker SSH connection)
    • To configure a Pi with TCP-enabled Docker.
      • Edit /lib/systemd/system/docker.service and add -H tcp:// at “ExecStart”
      • run sudo systemctl daemon-reload
      • run sudo systemctl restart docker
  • Manage Docker as a non-root user on your Raspberry Pi, so that you don’t need to preface the docker command with sudo.

Setup your C# module development environment on MacOS

Create a new project and configure the extension setting

  1. Open VS Code user setting, enable environment variables for the command executor and Azure IoT Edge terminals by adding the snippet below. In my case, my Pi’s IP is, you need change that with your IP or you can also use hostname.
    "azure-iot-edge.executor.env": {
        "DOCKER_HOST": "ssh://pi@"

    If you have tcp-enabled Docker, you also do

    "azure-iot-edge.executor.env": {
        "DOCKER_HOST": "tcp://{YourIP}:2375"
  2. Reload VS Code window. Type and run Reload Window in Command Palette.
  3. Create a new Solution with a C# module. (follow the instructions here in case you forgot how to do that) If you want to use your existing C# project, you might need to manually add the Dockerfile.arm32v7.debug, and update the module.json. You can find Dockerfile here on Github.
  4. We will soon use Raspberry Pi to build module images, switch your IoT Edge Default Platform to arm32v7 in the status bar.

Build and run IoT Edge modules on Raspberry Pi

Update both deployment.template.json and deployment.debug.template.json file due to the stability issues on resource constrained devices. Right-click the deployment.template.json file, and select Build and Push IoT Edge Solution. In VS Code terminal, the docker build command will be triggered, and this time, the build context will be sent to my Docker daemon on Raspberry Pi.

After successful build, I use the generated deployment.arm32v7.json to create a deployment to my Raspberry Pi.

After a while, the C# arm32v7 module starts running on the Raspberry Pi.

Debug the modules running on Raspberry Pi

To attach the process in the running container, VSDBG is required for each C# module image, and .netcore app is also need to be built with Debug flag. Right-click the deployment.debug.template.json file, click Build and Push IoT Edge Solution. We can get the debug version of module image with Dockerfile.arm32v7.debug.

Debug the module with IoT Edge runtime

Since I already have IoT Edge security daemon running on my Raspberry Pi, I might just want to debug my module against the IoT Edge runtime with my modules running.

  1. Create a deployment with deployment.debug.arm32v7.json, after a while, the debug version of SampleModule starts running.
  2. Update the pipeArgs in “SampleModule Remote Debug (.NET Core)” in Launch.json. Add “-H <yourSSHconnection>” in PipeArgs, so that VS Code can pick the remote process with remote Docker engine.
  3. Add a breakpoint in Program.cs. Navigate to Debug view, select SampleModule Remote Debug (.NET Core), and press F5. Select the remote dotnet process from the dropdown. It might take a while to hit the breakpoint due to the compute power of Pi and the network between development machine and Pi.

Debug the module with IoT Edge simulator

Iotedgehubdev can also run IoT Edge solution via SSH on Raspberry Pi The tool will start an edgeHubDev, and we can directly run the entire IoT Edge app without doing deployment during development stage.

  1. To avoid port conflicts with edgeHub, I might choose to stop IoT Edge runtime by running sudo systemctl stop iotedge.
  2. Iotedgehubdev tool requires docker-compose to run IoT Edge app from deployment template file. However, the latest stable version of docker-compose doesn’t have the support for connecting to the Docker Engine using the ssh protocol. To work around this for now, I manually installed 1.24.0-rc1 version of docker-compose on my macOS, which exactly contains ssh support.
  3. Right-click deployment.template.json, select Build and Run IoT Edge Solution in Simulator. After a few seconds, you can see all module starts running with the logs as in the screenshot below.
  4. Navigate to debug view. Navigate to Debug view, select SampleModule Remote Debug (.NET Core), and press F5. Select the remote dotnet process from the dropdown. Breakpoint should be hit.
  5. Stop and debug session and stop the simulator. In Comment Palette, type and run Azure IoT Edge: Stop IoT Edge Simulator.


I demonstrated how to use my macOS as the development machine to build, run and debug arm32v7 IoT Edge module images. The steps are similar if you are using Windows, but you might need to spend more time to set up SSH stuff on Windows. This article won’t cover that part. You can also leverage Docker-machine to bridge your docker-cli to remote Docker engine.

If you want to cut down the SSH connection between your VS Code and your remote Docker engine on your remote device, remember to clean up the two items below.

  • azure-iot-edge.executor.env in extension settings.
  • Extra pipeArgs for SSH connections in Launch.json

Azure IoT Edge for VS Code project is open-sourced on Github. If you have any feature request or encounter any issues during your daily usage, don’t hesitate to create issue on our Github repository. We are all ears.


1 comment

Discussion is closed. Login to edit/delete existing comments.

  • Praveen Gupta 0

    What is the best way to test this quickly to gain trust in solution with real IoT devices & Raspberry-Pi? 
    Preferably, using Zigbee (Conbee) or Bluetooth or WiFi devices. 
    No coding to start with. Just integration to test it out… 

Feedback usabilla icon