CI/CD for Azure IoT Edge using GitHub actions for arm64 and amd64 platforms

anand chugh
Microsoft Azure
Published in
5 min readJun 21, 2022

Are you planning to create CI/CD pipelines for Azure IOT Edge devices using GitHub actions? This article can give you the starting point to create CI/CD pipelines using GitHub Actions.

Prerequisites

  • Basic knowledge of GitHub Actions and workflows
  • Basic knowledge of Azure IOT Edge
  • Basic knowledge of CI/CD
  • An active Azure subscription
  • GitHub account

Azure Resources Required

  • Azure Container Registry
  • Azure IOT Hub
  • Azure IOT Edge Device
  • Log Analytics
  • Azure Application Insights

Overview of CI/CD Flow

CI Process

CD Process

GitHub Sample Overview

Here is the link to the GitHub Sample.

Sample contains two Iot Edge modules.

  1. BackendModule: It is a python module which exposes one rest end point.
  2. FrontEndModule: It is a NodeJs frontend module. It calls backend API and show the response from backend in UI. It can be accessed at http://<IP of IOTHUB device>:3000

Steps to create ci/cd workflows

  1. Create Azure resources as mentioned above.
  2. Create IotEdge device and link it with IotHub. For testing purpose we can create Ubuntu VM and use it as IotEdge device. More details about this can be found here. We also need to add deployment tag for the device which we need to add in device twin settings. Here is sample deployment tag
"tags": {
"environment": "demodevice"
},
IotEdge Device Twin

3. Create following GitHub secrets

GitHub Secrets

ACR_LOGIN_SERVER: This is the azure container registry login server name

ACR_PASSWORD: This is password which can be found under “Access keys” section

ACR_USERNAME: This is acr username which can also be found under “Access Keys” section.

APPINSIGHTS_CONNECTION_STRING: This is Azure App insights instrumentation key. It is used to send any logs to application insights.

IOTHUB_CONN_STRING: It is IoT hub connection's string. It is used to create deployment

IOT_HUB_RESOURCE_ID: It is IoT hub resource id, which is used by IOT Edge metrics collector to send metrics like cpu, memory to IoT hub. More info can be found here.

LOG_ANALYTICS_SHARED_KEY: It is log analytics shared key. It is also used by IoT Edge Metrics collector.

LOG_ANALYTICS_WORKSPACE_ID: It is log analytics workspace id. It is also used by IoT Edge Metrics collector.

4. Environment Variables

To deploy IoT edge module we can use Azure cli command

az iot edge deployment create

More information about cli can be found here. This cli takes input deployment.json as one of the parameters. We can generate deployment json using deployment.template.json by expanding the env variables dynamically during cd process. This template file is present in source code in Iot Edge solution directory.

How can we get the environment variables and replace in deployment.template.json?

To achieve this we first create .env_template file which contains Key=Value pairs of all env variables present in deployment.template.json. This .env_template is copied to .env file during CD process and then env variables are replaced with values stored in Github secrets using sed command

.env_template file

#### Azure Container Registry details
# Username
ACR_USERNAME=""
# Password
ACR_PASSWORD=""
# Address
ACR_ADDRESS=""
#### Azure Log Analytics Workspace details
# Log Analytics Workspace ID
LOG_ANALYTICS_WORKSPACE_ID=""
# Log Analytics Workspace Key
LOG_ANALYTICS_SHARED_KEY=""
# Resource ID
IOT_HUB_RESOURCE_ID=""
#### Azure Application Insights details
APPINSIGHTS_CONNECTION_STRING=""

5. How can we use docker images with specified build number during CD process?

First step here is to do change in module.json for each iotedge module. Here we change the repository with the following. `${ACR_ADDRESS}` is replaced during CD process with actual acr login server by fetching it from GitHub Secrets.

"repository": "${ACR_ADDRESS}/frontendmodule",

Second step is to replace the docker build number in module.json during CD process.

cat module.json | jq '.image.tag.version =  $v' --arg v '1.0.${{env.RUN_NUMBER}}' | sponge module.json

6. Adding ACR credentials in deployment.template.json

Add registryCredentials section. This is required to download IotEdge modules docker images and deploy to the device during CD process.

"registryCredentials": {
"acr": {
"username": "${ACR_USERNAME}",
"password": "${ACR_PASSWORD}",
"address": "${ACR_ADDRESS}"
}
}

7. Once CI process is successful, docker images should be available in ACR.

ACR with docker images for iotedge modules.

8. To execute CD process, we need to provide the CI build number, which is same as the latest docker image version uploaded in ACR. In above scenario CI build number is 20. This is the execution screenshot of CD workflow

We also need to provide deployment tag, which we added in step 2.

To deploy to multiple devices we can add deployment tag to all those devices, and IotEdge runtime will take to deploy to all devices having demodevice deployment tag.

9. Once deployment is successful we can login to device see the status of iotedge modules. In following screenshot we can see two modules which are part of application BackendModule and FrontEndModule. We have also deployed IotEdgeMetricsCollector module which helps in checking metrics for IotEgde modules.

10. We can also check the success of deployment by visiting the Frontend url http://<ip address of iotedge device>:3000

Deployment on Arm64 devices

Above solution assumes that we are building docker images on amd64 machine and deploying these images on amd64 IoTEdge devices.

Now, if we want to deploy IotEdge modules on arm64 devices, then we need to have some mechanism to build arm64 images on amd64 devices. To achieve this we can use qemu emulator and add following steps to ci workflow

sudo apt-get install qemu binfmt-support qemu-user-static
docker run --rm --privileged multiarch/qemu-user-static --reset -p yes

To support arm64 devices we have created two workflow in sample repo it ci_arm64.yaml and cd_arm64.yaml.

Conclusion

Most of important areas which are involved in ci/cd process for IotEdge modules are covered in this document. For more clarification please visit the GitHub sample and try to run it. Also, if you find any issues please raise issue in GitHub sample.

References:

GitHub sample:

Azure CLI to create deployment

IoTEdgeDev tool

Provision IoTEdge Device

Build Arm64 based docker containers on x86 host

CI/CD for IoTEdge Devices using Azure Devops

IotEdgeMetricsCollector

--

--