Setup the local Azure IoT Edge development container

Azure IoT Edge as a product is in principle not just a simple application or a simple container, but is actually more of a runtime for an ecosystem on a device.

For this reason there is not just an Azure IoT Edge Container, but a special container that also offers development runtimes.

At present - February 2020 - these are the following:

  • Docker
  • .NET Core SDK
  • Python
  • Pip
  • Azure CLI
  • Azure CLI IoT extension
  • Cookiecutter
  • Node.js
  • Yeoman
  • Azure IoT Edge Node.js module template
  • OpenJDK
  • Maven
  • Git

To simplify the development you can simply use Docker for Desktop with the Azure IoT Edge development container. The development container contains all other components of the regular IoT Edge, including the IoT Edge Agent for executing your own modules, the IoT Edge Runtime itself and the IoT Edge Demon for starting the entire runtime.

If necessary, you could also create your own images based on this image, but these should only be used for development.

Download Azure IoT Edge Development Image

The Azure IoT Edge development container is publicly available on the Docker Hub and can be downloaded with a simple pull command.

However, please note the current size of almost 4 gigabytes!

C:\Users\Ben> docker images
REPOSITORY                             TAG                 IMAGE ID            CREATED             SIZE
microsoft/iotedgedev                   latest              54eb77dd8859        4 weeks ago         3.84GB

Hint right now there are two different repositories: mcr.microsoft.com/iotedge/iotedgedev and microsoft/iotedgedev. The images are basically identical (including the Image Id), but the recommended repository is microsoft/iotedgedev.

Create Azure IoT Edge Development Container

In principle, the image can be easily downloaded via docker pull or directly when creating the container, if it is not already available locally.
In any case, it is recommended to create the container with a name, so that later handling with starting and stopping is easier.

The first thing to do is to create an extra folder on the local machine. This folder is assigned to the container via Docker Volume Mapping. This folder will later contain the Azure IoT Edge Solution Files, among others.

mkdir C:\temp\iotedge

Now the container can be created together with a name. If the image was already downloaded, this is a matter of less than a second. Otherwise it takes a moment until the 4 gigabytes for the image are downloaded.

docker run --name myiotedgedev -it -v /var/run/docker.sock:/var/run/docker.sock -v C:\temp\iotedge:/home/iotedge microsoft/iotedgedev

C:\Users\Ben> docker run --name myiotedgedev -it -v /var/run/docker.sock:/var/run/docker.sock -v C:\temp\iotedge:/home/iotedge microsoft/iotedgedev                                                                            [email protected]:/home/iotedge$                             

Your container is now started and you have entered the interactive mode of your container. To leave the interactive mode, just use CTRL+D or enter exit. If you leave the interactive mode, your container will shotdown.

To leave the interactive mode without shuting down the container, use CTRL+P and CTRL+Q.

Init

The container is now still unconfigured. However, the container provides a wizard that takes care of the complete initialization of the Azure IoT Edge environment for development.

This requires an Azure Subscription, which must be placed in the container. The wizard then guides you through the creation of the Resource Group, IoT Hub and finally the registration as IoT Edge Device.

The initialization process places various files in the previously created folder. To start the initialization you have to enter the following: iotedgedev init

[email protected]:/home/iotedge$ iotedgedev init

Welcome to iotedgedev!
---------------------
Learn more about .NET Core: https://aka.ms/dotnet-docs
Use 'dotnet --help' to see available commands or visit: https://aka.ms/dotnet-cli-docs

Telemetry
---------
The .NET Core tools collect usage data in order to help us improve your experience. The data is anonymous and doesn't include command-line arguments. The data is collected by Microsoft and shared with the community. You can opt-out of telemetry by setting the DOTNET_CLI_TELEMETRY_OPTOUT environment variable to '1' or 'true' using your favorite shell.

Read more about .NET Core CLI Tools telemetry: https://aka.ms/dotnet-cli-telemetry

ASP.NET Core
------------
Successfully installed the ASP.NET Core HTTPS Development Certificate.
To trust the certificate run 'dotnet dev-certs https --trust' (Windows and macOS only). For establishing trust on other platforms refer to the platform specific documentation.
For more information on configuring HTTPS see https://go.microsoft.com/fwlink/?linkid=848054.
Getting ready...
  Restore completed in 1.56 sec for /home/iotedgedev/.templateengine/dotnetcli/v2.1.803/scratch/restore.csproj.

Usage: new [options]

Options:
  -h, --help          Displays help for this command.
  -l, --list          Lists templates containing the specified name. If no name is specified, lists all templates.
  -n, --name          The name for the output being created. If no name is specified, the name of the current directory is used.
  -o, --output        Location to place the generated output.
  -i, --install       Installs a source or a template pack.
  -u, --uninstall     Uninstalls a source or a template pack.
  --nuget-source      Specifies a NuGet source to use during install.
  --type              Filters templates based on available types. Predefined values are "project", "item" or "other".
  --force             Forces content to be generated even if it would change existing files.
  -lang, --language   Filters templates based on language and specifies the language of the template to create.

Templates                                         Short Name           Language          Tags
------------------------------------------------------------------------------------------------------------------------------
Console Application                               console              [C#], F#, VB      Common/Console
Class library                                     classlib             [C#], F#, VB      Common/Library
Azure IoT Edge Module                             aziotedgemodule      [C#], F#          Console
Unit Test Project                                 mstest               [C#], F#, VB      Test/MSTest
NUnit 3 Test Project                              nunit                [C#], F#, VB      Test/NUnit
NUnit 3 Test Item                                 nunit-test           [C#], F#, VB      Test/NUnit
xUnit Test Project                                xunit                [C#], F#, VB      Test/xUnit
Razor Page                                        page                 [C#]              Web/ASP.NET
MVC ViewImports                                   viewimports          [C#]              Web/ASP.NET
MVC ViewStart                                     viewstart            [C#]              Web/ASP.NET
ASP.NET Core Empty                                web                  [C#], F#          Web/Empty
ASP.NET Core Web App (Model-View-Controller)      mvc                  [C#], F#          Web/MVC
ASP.NET Core Web App                              razor                [C#]              Web/MVC/Razor Pages
ASP.NET Core with Angular                         angular              [C#]              Web/MVC/SPA
ASP.NET Core with React.js                        react                [C#]              Web/MVC/SPA
ASP.NET Core with React.js and Redux              reactredux           [C#]              Web/MVC/SPA
Razor Class Library                               razorclasslib        [C#]              Web/Razor/Library/Razor Class Library
ASP.NET Core Web API                              webapi               [C#], F#          Web/WebAPI
global.json file                                  globaljson                             Config
NuGet Config                                      nugetconfig                            Config
Web Config                                        webconfig                              Config
Solution File                                     sln                                    Solution

Examples:
    dotnet new mvc --auth Individual
    dotnet new webapi
    dotnet new --help

=========================================================================================================
======== DOTNET NEW AZIOTEDGEMODULE -N FILTERMODULE -R ${CONTAINER_REGISTRY_SERVER}/FILTERMODULE ========
=========================================================================================================

The template "Azure IoT Edge Module" was created successfully.

Processing post-creation actions...
Running 'dotnet restore' on filtermodule...
  Restore completed in 3.65 sec for /home/iotedge/modules/filtermodule/filtermodule.csproj.

Restore succeeded.
ADD COMPLETE

AZURE IOT EDGE SOLUTION CREATED

=========================================================
======== IOTEDGEDEV IOTHUB SETUP --UPDATE-DOTENV ========
=========================================================

================================
======== AUTHENTICATION ========
================================

Retrieving Azure CLI credentials from cache...

Azure CLI credentials not found. Please follow instructions below to login to the Azure CLI.
To sign in, use a web browser to open the page https://microsoft.com/devicelogin and enter the code <your personal code> to authenticate.

If you enter your credential like mentioned in the last line, you map your container to your azure subscription:

==============================
======== SUBSCRIPTION ========
==============================

Retrieving Azure Subscriptions...

Subscription Name            Id
---------------------------  ------------------------------------
Microsoft Azure Sponsorship  XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Personal Subscription Abt    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Select an Azure Subscription Name or Id: [XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX]: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

======================================
======== SETTING SUBSCRIPTION ========
======================================

Setting Subscription to 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'...

If you have mapped your subscription to your IoT Edge development container, the init tries to connect to an IoT Hub on Azure.

If you dont have an IoT Hub instance there, the wizard creates one for you. In my case, I already have an existing resource group for my Azure IoT demos, but the wizard will create a new IoT Hub for me.

=========================================
======== RESOURCE GROUP LOCATION ========
=========================================

Enter a Resource Group Location: (australiaeast, australiasoutheast, brazilsouth, canadacentral, canadaeast, centralindia, centralus, eastasia, eastus, eastus2, japanwest, japaneast, northeurope, northcentralus, southindia, uksouth, ukwest, westus, westeurope, southcentralus, westcentralus, westus2) [westus]: westeurope

=================================================
======== SETTING RESOURCE GROUP LOCATION ========
=================================================

Setting Resource Group Location to 'westeurope'...

================================
======== RESOURCE GROUP ========
================================

Retrieving Resource Groups...

Resource Group           Location
-----------------------  ----------
ABT-IOT-DEMOS-RG         westeurope

Enter Resource Group Name (Creates a new Resource Group if not found): [iotedgedev-rg]: ABT-IOT-DEMOS-RG

=============================================
======== SETTING RESOURCE GROUP NAME ========
=============================================

Setting Resource Group Name to 'ABT-IOT-DEMOS-RG'...

Checking if Resource Group 'ABT-IOT-DEMOS-RG' exists...

Retrieving Resource Group 'ABT-IOT-DEMOS-RG' location...

============================
======== IOTHUB SKU ========
============================

Enter IoT Hub SKU (F1|S1|S2|S3): (F1, S1, S2, S3) [F1]: S1

=====================================
======== SETTING IOT HUB SKU ========
=====================================

Setting IoT Hub SKU to 'S1'...

=========================
======== IOT HUB ========
=========================

Retrieving IoT Hubs in 'ABT-IOT-DEMOS-RG'...

Enter the IoT Hub Name (Creates a new IoT Hub if not found): [iotedgedev-iothub-113b2c]: abt-iothub-demo

=================================
======== SETTING IOT HUB ========
=================================

Setting IoT Hub to 'abt-iothub-demo'...

Checking if 'abt-iothub-demo' IoT Hub exists...

Could not locate the abt-iothub-demo in ABT-IOT-DEMOS-RG.
Creating 'abt-iothub-demo' in 'ABT-IOT-DEMOS-RG' with 'S1' sku...

Creating IoT Hub. Please wait as this could take a few minutes to complete...

Now the new IoT Hub is created. The next step is to create a IoT Edge Device to map your development container to the Azure IoT. Each device (or in my case the development container) is a registered device in your IoT Hub.

=============================
======== EDGE DEVICE ========
=============================

Retrieving edge devices in 'abt-iothub-demo'...

Enter the IoT Edge Device Id (Creates a new Edge Device if not found): [iotedgedev-edgedevice]: my-iothub-devcontainer

=====================================
======== SETTING EDGE DEVICE ========
=====================================

Setting Edge Device to 'my-iothub-devcontainer'...

Checking if 'my-iothub-devcontainer' device exists in 'abt-iothub-demo'...

Could not locate the my-iothub-devcontainer device in abt-iothub-demo IoT Hub in ABT-IOT-DEMOS-RG.
Creating 'my-iothub-devcontainer' edge device in 'abt-iothub-demo'...

====================================
======== CONNECTION STRINGS ========
====================================

Retrieving 'abt-iothub-demo' connection string...

Retrieving 'my-iothub-devcontainer' connection string...

IOTHUB_CONNECTION_STRING="XXXXXXXXXXXXX"
DEVICE_CONNECTION_STRING="XXXXXXXXXXXXX"

Successfully backed up /home/iotedge/.env to /home/iotedge/.env.backup
Updated current .env file

Now the initialization is ready and your container is connected to your Azure IoT Hub. If you now look into your created IoT Edge folder (e.g. C:\temp\iotedge) you see the created solution files.

C:\temp\iotedge> dir

    Directory: C:\temp\iotedge

Mode                LastWriteTime         Length Name
----                -------------         ------ ----
d-----       16.02.2020     20:25                .vscode
d-----       16.02.2020     20:25                modules
-a----       16.02.2020     20:38           2803 .env
-a----       16.02.2020     20:38           2538 .env.backup
-a----       16.02.2020     20:25             63 .gitignore
-a----       16.02.2020     20:25           2586 deployment.debug.template.json
-a----       16.02.2020     20:25           2580 deployment.template.json

The overview of the IoT Edge in the Azure Portal also shows all settings made in the wizard:

IoT Edge Device

You can find the source of the Azure IoT Edge development container here: https://aka.ms/iotedgedev