{"id":2269,"date":"2019-02-16T06:23:36","date_gmt":"2019-02-15T22:23:36","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/iotdev\/?p=2269"},"modified":"2020-03-02T15:01:13","modified_gmt":"2020-03-02T07:01:13","slug":"easily-build-and-debug-iot-edge-modules-on-your-remote-device-with-azure-iot-edge-for-vs-code-1-9-0","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/iotdev\/easily-build-and-debug-iot-edge-modules-on-your-remote-device-with-azure-iot-edge-for-vs-code-1-9-0\/","title":{"rendered":"Easily build and debug IoT Edge modules on your remote device with Azure IoT Edge for VS Code 1.9.0."},"content":{"rendered":"<p>Recently, both Docker and Moby engine support <a href=\"https:\/\/github.com\/docker\/cli\/pull\/1014\">SSH connection<\/a>, which means you can connect a remote Docker engine more easily than before. In <a href=\"https:\/\/github.com\/Microsoft\/vscode-azure-iot-edge\/blob\/master\/CHANGELOG.md#190---2019-01-30\">Azure IoT Edge for VS Code 1.9.0<\/a>, we introduced a new extension setting(<em>azure-iot-edge.executor.env<\/em>) 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.<\/p>\n<ul>\n<li>Build IoT Edge module images on a remote device.<\/li>\n<li>Debug running modules on a remote device.<\/li>\n<\/ul>\n<p>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\u2019d 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\u2019s see how it works.<\/p>\n<h2>Prerequisites<\/h2>\n<p><strong>Setup your Raspberry Pi<\/strong><\/p>\n<ul>\n<li>Install <a href=\"https:\/\/www.raspberrypi.org\/downloads\/raspbian\/\">Raspbian<\/a> on your Raspberry Pi by following this <a href=\"https:\/\/www.raspberrypi.org\/documentation\/installation\/installing-images\/\">tutorial<\/a>.<\/li>\n<li>Setup your Raspberry Pi as an IoT Edge device &#8211; Follow the instructions to install <a href=\"https:\/\/docs.microsoft.com\/en-us\/azure\/iot-edge\/how-to-install-iot-edge-linux-arm\">Azure IoT Edge runtime on Linux(arm32v7\/armhf)<\/a>.<\/li>\n<li><a href=\"https:\/\/www.raspberrypi.org\/documentation\/remote-access\/ssh\/passwordless.md\">Passwordless SSH access<\/a> to your Raspberry Pi. (Due to <a href=\"https:\/\/github.com\/docker\/cli\/issues\/1476\">this issue<\/a>, till Feb 2019, you cannot use username\/password for your Docker SSH connection)\n<ul>\n<li>To configure a Pi with TCP-enabled Docker.\n<ul>\n<li>Edit <em>\/lib\/systemd\/system\/docker.service<\/em> and add <em>-H tcp:\/\/0.0.0.0:2375<\/em> at <em>\u201cExecStart\u201d<\/em><\/li>\n<li>run <em>sudo systemctl daemon-reload<\/em><\/li>\n<li>run <em>sudo systemctl restart docker<\/em><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n<li><a href=\"https:\/\/docs.docker.com\/install\/linux\/linux-postinstall\/#manage-docker-as-a-non-root-user\">Manage Docker as a non-root user<\/a> on your Raspberry Pi, so that you don\u2019t need to preface the docker command with sudo.<\/li>\n<\/ul>\n<p><strong>Setup your C# module development environment on MacOS<\/strong><\/p>\n<ul>\n<li><a href=\"https:\/\/code.visualstudio.com\/\">VS Code<\/a> and necessary extensions including <a href=\"https:\/\/marketplace.visualstudio.com\/items?itemName=vsciot-vscode.azure-iot-tools\">Azure IoT Tools<\/a>, <a href=\"https:\/\/marketplace.visualstudio.com\/items?itemName=ms-vscode.csharp\">C# extension<\/a>.<\/li>\n<li><a href=\"https:\/\/www.microsoft.com\/net\/download\">.NET Core 2.1 SDK<\/a><\/li>\n<li><a href=\"https:\/\/docs.docker.com\/install\/\">Docker Community Edition<\/a> 2.0.0.0-mac78 2018-11-19 or above (which contains the SSH support)<\/li>\n<li>If you are running macOS Sierra (and above), <a href=\"https:\/\/superuser.com\/questions\/1127067\/macos-keeps-asking-my-ssh-passphrase-since-i-updated-to-sierra\">update your ssh config file<\/a> so that you won\u2019t be asked to input SSH passphrase in VS Code terminal each time when trigger docker command.<\/li>\n<\/ul>\n<h2>Create a new project and configure the extension setting<\/h2>\n<ol>\n<li>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\u2019s IP is 192.168.86.74, you need change that with your IP or you can also use hostname.\n<pre class=\"lang:default decode:true\">\"azure-iot-edge.executor.env\": {\r\n    \"DOCKER_HOST\": \"ssh:\/\/pi@192.168.86.74\"\r\n}<\/pre>\n<p>If you have tcp-enabled Docker, you also do<\/p>\n<pre class=\"lang:default decode:true  \">\"azure-iot-edge.executor.env\": {\r\n    \"DOCKER_HOST\": \"tcp:\/\/{YourIP}:2375\"\r\n}<\/pre>\n<\/li>\n<li>Reload VS Code window. Type and run <strong>Reload Window<\/strong> in Command Palette.<\/li>\n<li>Create a new Solution with a C# module. (follow the <a href=\"https:\/\/docs.microsoft.com\/en-us\/azure\/iot-edge\/tutorial-csharp-module\">instructions here<\/a> in case you forgot how to do that) If you want to use your existing C# project, you might need to manually add the <em>Dockerfile.arm32v7.debug<\/em>, and update the <em>module.json<\/em>. You can find Dockerfile <a href=\"https:\/\/github.com\/Azure\/dotnet-template-azure-iot-edge-module\/blob\/master\/content\/dotnet-template-azure-iot-edge-module\/CSharp\/Dockerfile.arm32v7.debug\">here on Github<\/a>.<\/li>\n<li>We will soon use Raspberry Pi to build module images, switch your IoT Edge Default Platform to arm32v7 in the status bar.\n<img decoding=\"async\" class=\"alignnone size-medium wp-image-2270\" src=\"https:\/\/devblogs.microsoft.com\/iotdev\/wp-content\/uploads\/sites\/24\/2019\/02\/image1-300x29.jpeg\" alt=\"\" width=\"300\" height=\"29\" srcset=\"https:\/\/devblogs.microsoft.com\/iotdev\/wp-content\/uploads\/sites\/24\/2019\/02\/image1-300x29.jpeg 300w, https:\/\/devblogs.microsoft.com\/iotdev\/wp-content\/uploads\/sites\/24\/2019\/02\/image1.jpeg 533w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/li>\n<\/ol>\n<h2>Build and run IoT Edge modules on Raspberry Pi<\/h2>\n<p>Update both <em>deployment.template.json<\/em> and <em>deployment.debug.template.json<\/em> file due to the <a href=\"https:\/\/docs.microsoft.com\/en-us\/azure\/iot-edge\/troubleshoot#stability-issues-on-resource-constrained-devices\">stability issues on resource constrained devices<\/a>. Right-click the <em>deployment.template.json<\/em> file, and select <strong>Build and Push IoT Edge Solution<\/strong>. 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.<\/p>\n<p><img decoding=\"async\" class=\"alignnone size-full wp-image-2271\" src=\"https:\/\/devblogs.microsoft.com\/iotdev\/wp-content\/uploads\/sites\/24\/2019\/02\/image2.jpeg\" alt=\"\" width=\"976\" height=\"292\" srcset=\"https:\/\/devblogs.microsoft.com\/iotdev\/wp-content\/uploads\/sites\/24\/2019\/02\/image2.jpeg 976w, https:\/\/devblogs.microsoft.com\/iotdev\/wp-content\/uploads\/sites\/24\/2019\/02\/image2-300x90.jpeg 300w, https:\/\/devblogs.microsoft.com\/iotdev\/wp-content\/uploads\/sites\/24\/2019\/02\/image2-768x230.jpeg 768w\" sizes=\"(max-width: 976px) 100vw, 976px\" \/><\/p>\n<p>After successful build, I use the generated <em>deployment.arm32v7.json<\/em> to create a deployment to my Raspberry Pi.<\/p>\n<p><img decoding=\"async\" class=\"alignnone size-full wp-image-2272\" src=\"https:\/\/devblogs.microsoft.com\/iotdev\/wp-content\/uploads\/sites\/24\/2019\/02\/image3.jpeg\" alt=\"\" width=\"668\" height=\"248\" srcset=\"https:\/\/devblogs.microsoft.com\/iotdev\/wp-content\/uploads\/sites\/24\/2019\/02\/image3.jpeg 668w, https:\/\/devblogs.microsoft.com\/iotdev\/wp-content\/uploads\/sites\/24\/2019\/02\/image3-300x111.jpeg 300w\" sizes=\"(max-width: 668px) 100vw, 668px\" \/><\/p>\n<p>After a while, the C# arm32v7 module starts running on the Raspberry Pi.<\/p>\n<p><img decoding=\"async\" class=\"alignnone size-full wp-image-2273\" src=\"https:\/\/devblogs.microsoft.com\/iotdev\/wp-content\/uploads\/sites\/24\/2019\/02\/image4.jpeg\" alt=\"\" width=\"473\" height=\"221\" srcset=\"https:\/\/devblogs.microsoft.com\/iotdev\/wp-content\/uploads\/sites\/24\/2019\/02\/image4.jpeg 473w, https:\/\/devblogs.microsoft.com\/iotdev\/wp-content\/uploads\/sites\/24\/2019\/02\/image4-300x140.jpeg 300w\" sizes=\"(max-width: 473px) 100vw, 473px\" \/><\/p>\n<h2>Debug the modules running on Raspberry Pi<\/h2>\n<p>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 <em>deployment.debug.template.json<\/em> file, click <strong>Build and Push IoT Edge Solution<\/strong>. We can get the debug version of module image with Dockerfile.arm32v7.debug.<\/p>\n<h3>Debug the module with IoT Edge runtime<\/h3>\n<p>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.<\/p>\n<ol>\n<li>Create a deployment with <em>deployment.debug.arm32v7.json<\/em>, after a while, the debug version of <strong>SampleModule<\/strong> starts running.\n<img decoding=\"async\" class=\"alignnone size-full wp-image-2274\" src=\"https:\/\/devblogs.microsoft.com\/iotdev\/wp-content\/uploads\/sites\/24\/2019\/02\/image5.jpeg\" alt=\"\" width=\"976\" height=\"95\" srcset=\"https:\/\/devblogs.microsoft.com\/iotdev\/wp-content\/uploads\/sites\/24\/2019\/02\/image5.jpeg 976w, https:\/\/devblogs.microsoft.com\/iotdev\/wp-content\/uploads\/sites\/24\/2019\/02\/image5-300x29.jpeg 300w, https:\/\/devblogs.microsoft.com\/iotdev\/wp-content\/uploads\/sites\/24\/2019\/02\/image5-768x75.jpeg 768w\" sizes=\"(max-width: 976px) 100vw, 976px\" \/><\/li>\n<li>Update the <em>pipeArgs<\/em> in &#8220;<em>SampleModule Remote Debug (.NET Core)<\/em>&#8221; in <em>Launch.json<\/em>. Add &#8220;-H &lt;yourSSHconnection&gt;&#8221; in PipeArgs, so that VS Code can pick the remote process with remote Docker engine.\n<img decoding=\"async\" class=\"alignnone wp-image-2275\" src=\"https:\/\/devblogs.microsoft.com\/iotdev\/wp-content\/uploads\/sites\/24\/2019\/02\/image6.jpeg\" alt=\"\" width=\"522\" height=\"247\" srcset=\"https:\/\/devblogs.microsoft.com\/iotdev\/wp-content\/uploads\/sites\/24\/2019\/02\/image6.jpeg 974w, https:\/\/devblogs.microsoft.com\/iotdev\/wp-content\/uploads\/sites\/24\/2019\/02\/image6-300x142.jpeg 300w, https:\/\/devblogs.microsoft.com\/iotdev\/wp-content\/uploads\/sites\/24\/2019\/02\/image6-768x363.jpeg 768w\" sizes=\"(max-width: 522px) 100vw, 522px\" \/><\/li>\n<li>Add a breakpoint in Program.cs. Navigate to Debug view, select <strong>SampleModule Remote Debug (.NET Core)<\/strong>, 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.\n<img decoding=\"async\" class=\"alignnone size-full wp-image-2276\" src=\"https:\/\/devblogs.microsoft.com\/iotdev\/wp-content\/uploads\/sites\/24\/2019\/02\/image7.jpeg\" alt=\"\" width=\"976\" height=\"648\" srcset=\"https:\/\/devblogs.microsoft.com\/iotdev\/wp-content\/uploads\/sites\/24\/2019\/02\/image7.jpeg 976w, https:\/\/devblogs.microsoft.com\/iotdev\/wp-content\/uploads\/sites\/24\/2019\/02\/image7-300x199.jpeg 300w, https:\/\/devblogs.microsoft.com\/iotdev\/wp-content\/uploads\/sites\/24\/2019\/02\/image7-768x510.jpeg 768w\" sizes=\"(max-width: 976px) 100vw, 976px\" \/><\/li>\n<\/ol>\n<h2>Debug the module with IoT Edge simulator<\/h2>\n<p><a href=\"https:\/\/github.com\/Azure\/iotedgehubdev\">Iotedgehubdev<\/a> 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.<\/p>\n<ol>\n<li>To avoid port conflicts with edgeHub, I might choose to stop IoT Edge runtime by running <em>sudo systemctl stop iotedge<\/em>.<\/li>\n<li>Iotedgehubdev tool requires <a href=\"https:\/\/github.com\/docker\/compose\">docker-compose<\/a> to run IoT Edge app from deployment template file. However, the latest stable version of docker-compose doesn\u2019t have the support for connecting to the Docker Engine using the ssh protocol. To work around this for now, I manually installed <a href=\"https:\/\/github.com\/docker\/compose\/releases\/tag\/1.24.0-rc1\">1.24.0-rc1 version of docker-compose<\/a> on my macOS, which exactly contains ssh support.<\/li>\n<li>Right-click deployment.template.json, select <strong>Build and Run IoT Edge Solution in Simulator<\/strong>. After a few seconds, you can see all module starts running with the logs as in the screenshot below.\n<img decoding=\"async\" class=\"alignnone size-full wp-image-2277\" src=\"https:\/\/devblogs.microsoft.com\/iotdev\/wp-content\/uploads\/sites\/24\/2019\/02\/image8.jpeg\" alt=\"\" width=\"976\" height=\"375\" srcset=\"https:\/\/devblogs.microsoft.com\/iotdev\/wp-content\/uploads\/sites\/24\/2019\/02\/image8.jpeg 976w, https:\/\/devblogs.microsoft.com\/iotdev\/wp-content\/uploads\/sites\/24\/2019\/02\/image8-300x115.jpeg 300w, https:\/\/devblogs.microsoft.com\/iotdev\/wp-content\/uploads\/sites\/24\/2019\/02\/image8-768x295.jpeg 768w\" sizes=\"(max-width: 976px) 100vw, 976px\" \/><\/li>\n<li>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.\n<img decoding=\"async\" class=\"alignnone size-full wp-image-2278\" src=\"https:\/\/devblogs.microsoft.com\/iotdev\/wp-content\/uploads\/sites\/24\/2019\/02\/image9.jpeg\" alt=\"\" width=\"976\" height=\"628\" srcset=\"https:\/\/devblogs.microsoft.com\/iotdev\/wp-content\/uploads\/sites\/24\/2019\/02\/image9.jpeg 976w, https:\/\/devblogs.microsoft.com\/iotdev\/wp-content\/uploads\/sites\/24\/2019\/02\/image9-300x193.jpeg 300w, https:\/\/devblogs.microsoft.com\/iotdev\/wp-content\/uploads\/sites\/24\/2019\/02\/image9-768x494.jpeg 768w\" sizes=\"(max-width: 976px) 100vw, 976px\" \/><\/li>\n<li>Stop and debug session and stop the simulator. In Comment Palette, type and run <strong>Azure IoT Edge: Stop IoT Edge Simulator.<\/strong><\/li>\n<\/ol>\n<h2>Summary<\/h2>\n<p>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\u2019t cover that part. You can also leverage <a href=\"https:\/\/docs.docker.com\/machine\/\">Docker-machine<\/a>\u00a0to bridge your docker-cli to remote Docker engine.<\/p>\n<p>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.<\/p>\n<ul>\n<li>azure-iot-edge.executor.env in extension settings.<\/li>\n<li>Extra pipeArgs for SSH connections in Launch.json<\/li>\n<\/ul>\n<p>Azure IoT Edge for VS Code project is open-sourced on <a href=\"https:\/\/github.com\/Microsoft\/vscode-azure-iot-edge\">Github<\/a>. If you have any feature request or encounter any issues during your daily usage, don\u2019t hesitate to <a href=\"https:\/\/github.com\/Microsoft\/vscode-azure-iot-edge\/issues\/new\/choose\">create issue on our Github repository<\/a>. We are all ears.<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>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, [&hellip;]<\/p>\n","protected":false},"author":531,"featured_media":2138,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[288],"tags":[164,20,33,35],"class_list":["post-2269","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-azure-iot-edge-development","tag-azure-iot-edge","tag-iot-edge","tag-visual-studio-code","tag-vs-code"],"acf":[],"blog_post_summary":"<p>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, [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/iotdev\/wp-json\/wp\/v2\/posts\/2269","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/iotdev\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/iotdev\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/iotdev\/wp-json\/wp\/v2\/users\/531"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/iotdev\/wp-json\/wp\/v2\/comments?post=2269"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/iotdev\/wp-json\/wp\/v2\/posts\/2269\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/iotdev\/wp-json\/wp\/v2\/media\/2138"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/iotdev\/wp-json\/wp\/v2\/media?parent=2269"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/iotdev\/wp-json\/wp\/v2\/categories?post=2269"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/iotdev\/wp-json\/wp\/v2\/tags?post=2269"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}