Creating an Azure IoT Edge project with 2 communicating modules
When working with the Internet of Things, Azure is a valid choice! Offering IoT Hub and IoT Edge to help you create Edge modules for your devices. However, what is promised to be easy is currently quite "hard" to get working with.
Through this post I want to shed some light on how I was able to develop and push my modules today!
⚠️ Currently the state of today does not allow for easy local development as everything works through Docker compose which is orchestrated through the iotedgedev simulator
tool. Just give up on this and go straight for a remote device (it will make your life much easier).
Tl;dr
Feel free to check out my latest repository to get the modules that can communicate with each other
Goal
The goal of this post is to get acquainted with the latest development process of the Azure IoT Edge ecosystem and help deploy 2 modules (1 in Python and 1 in Typescript) that can send messages to each other.
Prerequisites
Let's start by installing our prerequisites and configuring Python correctly
💡 Currently only <= Python 3.9 is supported
# Add local bin to path
echo 'export PATH="/home/$USER/.local/bin:$PATH"' >> ~/.bashrc
# Install Python
sudo apt-update
sudo apt install -y python3.9
sudo ln -s /usr/bin/python3.9 /usr/bin/python
sudo ln -s /usr/bin/python3.9 /usr/bin/python3
sudo apt install -y python3-distutils
curl -s https://bootstrap.pypa.io/get-pip.py | python
# Install Docker
# ...
# Install Azure CLI - https://learn.microsoft.com/en-us/cli/azure/install-azure-cli
# curl -L https://aka.ms/InstallAzureCli | bash # Note: this had the error that the path should start with /usr
pip install -U azure-cli; az upgrade
# Install IoT Edge Dev
# (v3.3.6 -> see https://pypi.org/project/iotedgedev/)
pip install -U iotedgedev
# Create a `iotedgehubdev` folder with correct permissions
sudo mkdir /var/lib/iotedgehubdev
sudo chmod -R 777 /var/lib/iotedgehubdev
sudo chmod -R 777 /etc/iotedgehubdev
# Install Cookiecutter
python -m pip install --user cookiecutter
# Install Yeoman and Azure IoT Edge Node.js
npm i -g yo generator-azure-iot-edge-module
# Try running `iotedgedev`
iotedgedev --help
Creating an IoT Edge Device in IoT Hub
Creating a Device
The first thing to do is to create an Azure IoT Edge device in the Azure Portal. So navigate to the IoT Hub and create a device with an identifier.
Connect the device to IoT Hub
Next up is to grab a device and connect it to IoT Hub
The below was executed for a Raspberry Pi
# Install IoT Edge
curl https://packages.microsoft.com/config/debian/11/packages-microsoft-prod.deb > ./packages-microsoft-prod.deb
sudo apt install ./packages-microsoft-prod.deb
sudo apt update
# Install Moby Container Engine
sudo apt install -y moby-engine
# Configure Moby for local logging
# Install IoT Edge Runtime
sudo apt -y install aziot-edge
# Provision with its cloud identity and check the status
sudo iotedge config mp --connection-string "CONNECTION_STRING"
sudo iotedge config apply
sudo iotedge system status
Creating an IoT Edge Solution
Creating the modules
For our solution we wanted to have 2 modules in a solution that communicate to each other. One node.js and one Python
# Create the solution
iotedgedev solution init --template python iot-edge
# Add a module
iotedgedev solution add --template python AudioRecording
# Add a module
iotedgedev solution add --template nodejs AudioInferencing
Build and push your modules
The device is connected to our IoT Hub and we can start deploying modules to it. So let's configure our Template to include our containers and push the modules.
To configure the template, open the .env
file and ensure that your CONTAINER_REGISTRY_SERVER, CONTAINER_REGISTRY_USERNAME and CONTAINER_REGISTRY_PASSWORD
variables are set
We are up and running now, we can publish our modules by running:
PLATFORM=arm32v7
ACR_REPO=YOUR_ACR_NAME
# Initialize qemu
docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
# Generate the config from the deployment template
# More info: https://learn.microsoft.com/en-us/azure/iot-edge/module-composition?view=iotedge-1.4
iotedgedev solution genconfig --file deployment.template.json \
--platform $PLATFORM
# Build and push your modules for the target architecture
for d in modules/*; do
MODULE_DIR=$d
MODULE_NAME=$(echo $d | cut -d "/" -f 2)
MODULE_NAME_LOWER=$(echo $MODULE_NAME | tr '[:upper:]' '[:lower:]')
echo "building $ACR_REPO.azurecr.io/$MODULE_NAME_LOWER"
docker buildx build --push --platform linux/$PLATFORM \
-t $ACR_REPO.azurecr.io/$MODULE_NAME_LOWER:0.0.1-arm32v7 \
-f $MODULE_DIR/Dockerfile.$PLATFORM \
$MODULE_DIR
done
# Push to the device
# similar to: az iot edge set-modules --hub-name my-iot-hub --device-id my-device --content ./deployment.debug.template.json --login "HostName=my-iot-hub.azure-devices.net;SharedAccessKeyName=iothubowner;SharedAccessKey=<SharedAccessKey>"
iotedgedev solution deploy --file config/deployment.arm32v7.json
💡 If you get "standard_init_linux.go:219: exec user process caused: exec format error" run docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
The script above will deploy everything automatically to the devices.
Checking our deployment
When everything is deployed, we can log in on our device and check if everything is working. If correctly done so, you should see the following output
Summary
Personally, the iotedgedev
tool is going the right way helping us create and deploy iot edge solutions more quickly. I just wish there was a way to develop locally more easily than what it offers now, but let's see what future will bring!
Member discussion