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.
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:
- Create a network switch in Hyper-V Management
- add a new network to the EFLOW virtual machine
- 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
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.