Access service within IoT Edge on Windows (EFLOW)

Introduction

The recommended way to run Azure IoT Edge on Windows (EFLOW) is by installing IoT Edge in a Hyper-V VM. EFLOW

But how are you going to access for example

  • a Blob Storage module from the host?
  • a custom Webservice?

The VM has an IP that might change every time the VM is starting.

[03/04/2022 14:26:17] Successfully created virtual machine
[03/04/2022 14:26:17] Virtual machine hostname: MY-EFLOW
[03/04/2022 14:26:20] Querying IP and MAC addresses from virtual machine (MY-EFLOW)
 - Virtual machine MAC: 00:00:00:00:00:53
 - Virtual machine IP : 172.19.33.153 retrieved directly from virtual machine

Check the current IP of the EFLOW VM

With Connect-EFlowVM you can SSH into the VM via PowerShell and check the IP again.

iotedge-user@MY-EFLOW [ ~ ]$ ifconfig
...
eth0      Link encap:Ethernet  HWaddr 00:00:00:00:00:53
         inet addr:172.19.33.153  Bcast:172.19.47.255  Mask:255.255.240.0
         inet6 addr: fe80::215:5dff:fef8:c753/64 Scope:Link
         UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
         RX packets:129570 errors:0 dropped:0 overruns:0 frame:0
         TX packets:21589 errors:0 dropped:0 overruns:0 carrier:0
         collisions:0 txqueuelen:1000
         RX bytes:192371991 (192.3 MB)  TX bytes:1407654 (1.4 MB)

After a reboot the IP (and MAC) has changed:

Get-EflowVmAddr

[03/04/2022 14:34:11] Querying IP and MAC addresses from virtual machine (MY-EFLOW)

 - Virtual machine MAC: 00:00:00:00:00:63
 - Virtual machine IP : 172.19.36.141 retrieved directly from virtual machine

We need to make sure that the IP doesn’t change on every reboot.

Configuring EFLOW

Assuming your services is exposing an endpoint to the host (in this case the EFLOW VM), the only thing to configure is a static IP for the VM. The IP can be a RFC 1918 adress (192.168.10.99 for example) or any other IP adress.

Steps to perform:

  1. Create a network switch in Hyper-V Management
  2. add a new network to the EFLOW virtual machine
  3. add a new network endpoint with a static IP to the EFLOW virtual machine

Create a new network switch for Hyper-V

For assigning a static IP, the VM Host needs to expose a new IP. This can be an internal or external IP. The doc Create a virtual switch by using Hyper-V Manager also explains when to use an internal and external network.

I’ve created an external switch after I realized that an internal switch was not supported.

 - The virtual switch 'InternalEFLOW' of type 'Internal' is not supported on current host OS

Create virtual switch in Hyper-V

Configure EFLOW

A new network needs to be added to the VM and then configured to have a static IP. The available PowerShell functions are available here.

Create a new network and an endpoint with the optional ip4Address parameter to assign a static IP. The name has to match the previously created Hyper-V virtual switch.

PS C:\> Add-EflowNetwork -vswitchName "ExternalEFLOW" -vswitchType External

[03/04/2022 15:46:52] Checking for virtual switch with name 'ExternalEFLOW'
 - The virtual switch 'ExternalEFLOW' of type 'External' is present
[03/04/2022 15:46:52] Creating vnet (name: ExternalEFLOW)
Name          AllocationMethod Cidr Type
----          ---------------- ---- ----
ExternalEFLOW                       External

After that, an endpoint could be created. By adding the optional ip4Address parameter, a static IP can be assigned. As you can see, I did not add a default Gateway to it. It is not needed, if you want to connect from the host only.

PS C:\> Add-EflowVmEndpoint -vswitchName ExternalEFLOW -vendpointName EFLOWExternalEndpoint -ip4Address 192.168.10.99 -ip4PrefixLength 24

Name               : MY-EFLOW-ExternalEFLOW-EFLOWExternalEndpoint
MacAddress         : 00:00:00:00:00:0e
HealthStatus       : currentState:OK previousState:OK
IpConfiguration    : @{Address=192.168.10.99; PrefixLength=24; Gateway=; AllocationMethod=Static; SubNet=ExternalEFLOW}
GuestInterfaceName : eth1

Now the VM has an additional NIC eth1.

PS C:\Users\rehezser\Downloads> Get-EflowVmEndpoint

Name               : MY-EFLOWInterface
MacAddress         : 00:00:00:00:00:63
HealthStatus       : currentState:OK previousState:OK
IpConfiguration    : @{Address=172.19.36.141; PrefixLength=20; Gateway=; AllocationMethod=Dynamic; SubNet=Default Switch}
GuestInterfaceName : eth0

Name               : MY-EFLOW-ExternalEFLOW-EFLOWExternalEndpoint
MacAddress         : 00:00:00:00:00:0e
HealthStatus       : currentState:OK previousState:OK
IpConfiguration    : @{Address=192.168.10.99; PrefixLength=24; Gateway=; AllocationMethod=Static; SubNet=ExternalEFLOW}
GuestInterfaceName : eth1

And now the exposed services in the VM are accessible from the host.

PS C:\> wget https://192.168.10.99
wget : The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel.
At line:1 char:1

Well, if I had added a valid certificate ¯\(ツ)

Summary

To be able to access a service within an EFLOW VM, you need to set a static IP on a new Hyper-V virtual switch and a network interface in the VM.