-
Notifications
You must be signed in to change notification settings - Fork 66
ADU CLI Primer
digimaun@host:~$ az iot device-update --help
Group
az iot device-update : Device Update for IoT Hub is a service that enables you to deploy over-
the-air updates (OTA) for your IoT devices.
As organizations look to further enable productivity and operational efficiency, Internet of
Things (IoT) solutions continue to be adopted at increasing rates. This makes it essential
that the devices forming these solutions are built on a foundation of reliability and
security and are easy to connect and manage at scale. Device Update for IoT Hub is an end-
to-end platform that customers can use to publish, distribute, and manage over-the-air
updates for everything from tiny sensors to gateway-level devices.
To learn more about the Device Update for IoT Hub service visit
https://docs.microsoft.com/en-us/azure/iot-hub-device-update/.
This command group is in preview and under development. Reference and support levels:
https://aka.ms/CLI_refstatus
Subgroups:
account : Device Update account management.
device : Device Update device management.
instance : Device Update instance management.
update : Device Update update management.
To search AI knowledge base for examples, use: az find "az iot device-update"
Please let us know how we are doing: https://aka.ms/azureclihats
👉 The ADU CLI is intended & designed to be a complete Device Update experience. Anything the service supports that a user wants to do should be possible through the CLI.
-
Full control plane support.[Available inazure-iot
v0.16.0
+] -
Full data plane support.[Available inazure-iot
v0.17.0
+] -
Import update manifest utilities [Generation, Stage].
Please start by reading the instructions written here. Remember that --help
and --debug
are your friends.
Download the latest in-work preview package encompassing both data-plane and control-plane. You can now install the latest azure-iot
extension to enable the ADU command groups.
Bug bash package KPIs (may include 1 or more entries).
filename: azure_iot-255.200.3-py3-none-any.whl
extension: azure-iot
version: 255.200.3
SHA256: 20D35FAE583D869453F51CB0DC0F8BB6FB5821CD166BB3955ED43672AE26D4DF
MD5: 90BC61887CDEA858DDD51EB9AF89F28E
You can install directly from the above backing link URL or download the .whl
package locally.
- Ensure you have Azure CLI 2.30.0 or greater installed. Use
az --version
to check. - See existing Az CLI extension installations with
az extension list
- Remove any existing
azure-iot
installations if they exist viaaz extension remove --name azure-iot
- Install the in-work preview package provided by these instructions via
az extension add --source <URL or local file path to .whl> -y
- After the install use
az extension list
again to verify the extension name & version.
🤖 If you have not already logged in, do so now by running az login
. If you are using cloudshell
make sure to run az login
again to avoid a known issue.
🤖 Ensure your desired subscription is activated as default by running az account set --subscription '<name or Id of sub>'
🤖 The provided commands are meant as a starting point to get you going faster. In many cases commands include various options, switches and modes to support advanced usage scenarios.
🌟 We will now step through key scenarios of ADU and how to exercise them via CLI. The examples shown will have sample values rather than placeholders which are often seen in the --help
docs.
[Optional] Create a resource group for the account (or use an existing one)
az group create --location westus2 --name MyDeviceUpdateRG
Minimum inputs, using the RG location for account location
az iot device-update account create -n test-adu-35d878a5c16248 -g MyDeviceUpdateRG
Specify a location
az iot device-update account create -n test-adu-35d878a5c16248 -g MyDeviceUpdateRG -l eastus2euap
Once your account is created you can view its properties at anytime
az iot device-update account show -n test-adu-35d878a5c16248
[Optional] Provision a new IoT Hub (or use an existing one)
az iot hub create --name MyDeviceUpdateIoTHub -g MyDeviceUpdateRG
[Optional] Provision a new storage account for diagnostics (or use an existing one)
az storage account create -n deviceupdatestorage -g MyDeviceUpdateRG`
Create an instance on the account. The IoT Hub can exist in any subscription, just provide an explicit --subscription
for the respective show
command if your target hub is in a different subscription compared to the default activated one.
az iot device-update instance create -n test-adu-35d878a5c16248 -i myinstance1 --iothub-ids $(az iot hub show -n MyDeviceUpdateIoTHub --subscription 1c9af29c-c73a-44a9-bbc4-2aafc5c3f1e1 --query id -o tsv)
Create an instance with diagnostics enabled. The storage account can exist in any subscription, just provide an explicit --subscription
for the respective show
command if your target storage account is in a different subscription compared to the default activated one.
az iot device-update instance create -n test-adu-35d878a5c16248 -i myinstance1 --iothub-ids $(az iot hub show -n MyDeviceUpdateIoTHub --subscription 1c9af29c-c73a-44a9-bbc4-2aafc5c3f1e1 --query id -o tsv) --enable-diagnostics --diagnostic-storage-id $(az storage account show -n deviceupdatestorage -o tsv --query id)
Once your instance is created you can view its properties at anytime
az iot device-update instance show -n test-adu-35d878a5c16248 -i myinstance1
The rest of this document will focus on data-plane, but you can checkout the ADU infra/control-plane reference docs at anytime here.
Assigning a privileged role to the target principal needing data-plane access is a requirement.
az role assignment create --role 'Device Update Administrator' --assignee '[email protected]' --scope $(az iot device-update account show -n test-adu-35d878a5c16248 -o tsv --query id)
It will take some time for the role assignment to propagate. Usually less than a couple minutes but it can take longer. You can try running az login
again to force a refresh of your auth token.
Before importing via ADU CLI, the update artifacts need to be staged in a storage container.
-
Create the storage container
az storage container create --name myupdatecontainer --account-name deviceupdatestorage --only-show-errors
-
Upload update artifacts (manifest and related files). Run this step 1 or more times.
az storage blob upload -f 'local/path/to/update/artifact' -c myupdatecontainer --name artifact_blobname --account-name deviceupdatestorage --only-show-errors
-
Generate SAS URI for blob artifacts. Run this step 1 or more times.
az storage blob generate-sas -c myupdatecontainer --name artifact_blobname --account-name deviceupdatestorage --permissions r --expiry 2022-07-24T00:00:00Z --https-only --full-uri -o tsv --only-show-errors
It is highly recommended that the output SAS URI's from the above command get assigned as shell or environment variables. This allows easier escaping and re-use.
Powershell example
$UPDATE_MANIFEST_SAS_URI=$(az storage blob generate-sas -c myupdatecontainer --name artifact_blobname --account-name deviceupdatestorage --permissions r --expiry 2022-07-24T00:00:00Z --https-only --full-uri -o tsv --only-show-errors)
Bash example
UPDATE_MANIFEST_SAS_URI=$(az storage blob generate-sas -c myupdatecontainer --name artifact_blobname --account-name deviceupdatestorage --permissions r --expiry 2022-07-24T00:00:00Z --https-only --full-uri -o tsv --only-show-errors)
For an update with no reference steps like this sample v5 schema one, the az iot device-update update import
command supports importing on a single execution.
{
"updateId": {
"provider": "digimaun",
"name": "adutest",
"version": "1.0.0.0"
},
"compatibility": [{
"deviceManufacturer": "Contoso",
"deviceModel": "Vacuum"
}],
"instructions": {
"steps": [{
"type": "inline",
"handler": "microsoft/swupdate:1",
"files": [
"file1.dat"
]
}]
},
"files": [{
"filename": "file1.dat",
"sizeInBytes": 11,
"hashes": {
"sha256": "TkeCZpi7RjD7RFEBAGL62/hdYUJ8vfrtetDyPyOb7Yk="
},
"mimeType": "application/octet-stream",
"relatedFiles": [{
"filename": "file2.dat",
"sizeInBytes": 8,
"hashes": {
"sha256": "HLeyIbet2hz0xHJLMjaTlFgEgMhKuDV5XWCKxZqhMAI="
},
"properties": {
"microsoft.sourceFileHashAlgorithm": "sha256",
"microsoft.sourceFileHash": "YmFYwnEUddq2nZsBAn5v7gCRKdHx+TUntMz5tLwU+24="
}
}],
"downloadHandler": {
"id": "microsoft/delta:1"
}
}],
"createdDateTime": "2022-04-22T00:02:41.2100526Z",
"manifestVersion": "5.0"
}
Here is an example on importing the above update after preparation steps. These samples assume the SAS URI environment variable guidance was followed. Note --file
can be used 1 or more times.
Powershell
az iot device-update update import -n test-adu-35d878a5c16248 -i myinstance1 --friendly-name digicontosovac --url "`"$UPDATE_MANIFEST_SAS_URI`"" --file filename=file1.dat url="`"$FILE1DAT_SAS_URI`"" --file filename=file2.dat url="`"$FILE2DAT_SAS_URI`""
Bash
az iot device-update update import -n test-adu-35d878a5c16248 -i myinstance1 --friendly-name digicontosovac --url "$UPDATE_MANIFEST_SAS_URI" --file filename=file1.dat url="$FILE1DAT_SAS_URI" --file filename=file2.dat url="$FILE2DAT_SAS_URI"
For an update with reference steps like the following sample, the az iot device-update update import
command supports deferred import until next execution via --defer
. Using --defer
will cache the import request payload that would have gone to Azure then exit. The next usage of the update import command without --defer
will combine all prior cached payloads with the current one before sending to Azure. You are able to view & purge cache content via az cache
commands.
parent.importmanifest.json
{
"updateId": {
"provider": "Microsoft",
"name": "Surface",
"version": "1.5"
},
"isDeployable": true,
"compatibility": [
{
"deviceModel": "Surface",
"deviceManufacturer": "Microsoft"
}
],
"instructions": {
"steps": [
{
"type": "inline",
"description": "Pre-install script",
"handler": "microsoft/script:1",
"files": [ "create-adu-import-manifest.sh" ],
"handlerProperties": { "arguments": "--pre" }
},
{
"type": "reference",
"description": "Microphone Firmware",
"updateId": {
"provider": "Microsoft",
"name": "Microphone",
"version": "1.3"
}
},
{
"type": "reference",
"description": "Speaker Firmware",
"updateId": {
"provider": "Microsoft",
"name": "Speaker",
"version": "1.3"
}
},
{
"type": "inline",
"description": "Post-install script",
"handler": "microsoft/script:1",
"files": [ "create-adu-import-manifest.sh" ],
"handlerProperties": { "arguments": "--post" }
}
]
},
"files": [
{
"filename": "create-adu-import-manifest.sh",
"sizeInBytes": 7,
"hashes": { "sha256": "5S8yHqFy+9gFvedPP7o5CnMOmOUTxcN6PEBeR4CmbRo=" }
}
],
"createdDateTime": "2021-11-10T01:30:04.8978755Z",
"manifestVersion": "4.0"
}
leaf1.importmanifest.json
{
"updateId": {
"provider": "Microsoft",
"name": "Microphone",
"version": "1.3"
},
"isDeployable": false,
"compatibility": [
{
"deviceModel": "Microphone",
"deviceManufacturer": "Microsoft"
}
],
"instructions": {
"steps": [
{
"type": "inline",
"handler": "microsoft/swupdate:1",
"files": [ "README.md" ]
}
]
},
"files": [
{
"filename": "README.md",
"sizeInBytes": 6,
"hashes": { "sha256": "YX6mQiDPV6sXCpihV/5uTxAMinOR/gBwf8m0XTolmJg=" }
}
],
"createdDateTime": "2021-11-10T01:30:04.8795262Z",
"manifestVersion": "4.0"
}
leaf2.importmanifest.json
{
"updateId": {
"provider": "Microsoft",
"name": "Speaker",
"version": "1.3"
},
"isDeployable": false,
"compatibility": [
{
"deviceModel": "Speaker",
"deviceManufacturer": "Microsoft"
}
],
"instructions": {
"steps": [
{
"type": "inline",
"handler": "microsoft/swupdate:1",
"files": [ "README.md" ]
}
]
},
"files": [
{
"filename": "README.md",
"sizeInBytes": 6,
"hashes": { "sha256": "YX6mQiDPV6sXCpihV/5uTxAMinOR/gBwf8m0XTolmJg=" }
}
],
"createdDateTime": "2021-11-10T01:30:04.8847323Z",
"manifestVersion": "4.0"
}
Here is an example on importing the above update after preparation steps. These samples assume the SAS URI environment variable guidance was followed. Note usage of --defer
does not depend on any order or relationship between update nodes.
Powershell
-
Defer import for one update node and store the request payload in local cache
az iot device-update update import -n test-adu-35d878a5c16248 -i myinstance1 --friendly-name surface_parent --url "`"$surface15_root`"" --file filename=create-adu-import-manifest.sh url="`"$script_file`"" --defer
-
Defer import for another update node and store the request payload in local cache
az iot device-update update import -n test-adu-35d878a5c16248 -i myinstance1 --friendly-name surface_leaf1 --url "`"$surface15_leaf1`"" --file filename=README.md url="`"$readme_file`"" --defer
-
Combine cached payloads and submit to Azure (as no --defer is provided)
az iot device-update update import -n test-adu-35d878a5c16248 -i myinstance1 --friendly-name surface_leaf2 --url "`"$surface15_leaf2`"" --file filename=README.md url="`"$readme_file`""
Remember you are able to view and purge local cache entities via az cache
commands.
You can see all your imported updates at a glance with az iot device-update update list
and table output.
az iot device-update update list -n test-adu-35d878a5c16248 -i myinstance1 -o table
UpdateProvider UpdateName UpdateVersion FriendlyName IsDeployable ManifestVersion ImportedDateTime
---------------- ------------ --------------- -------------- -------------- ----------------- --------------------------------
digimaun adutest 2.0.0.0 test_update True 5.0 2022-06-29T23:08:13.534344+00:00
digimaun adutest 1.0.0.2 init_update True 5.0 2022-06-29T02:19:51.396379+00:00
The az iot device-update update list
has a lot of options. Use --help
to see them all. Here are a few variations.
# List only update providers
az iot device-update update list test-adu-35d878a5c16248 -i myinstance1 --by-provider
# List with service side filter
az iot device-update update list test-adu-35d878a5c16248 -i myinstance1 --filter "friendlyName eq 'init_1'"
# List with service side free search expression
az iot device-update update list test-adu-35d878a5c16248 -i myinstance1 --search "libcurl4-doc"
See details of a specific update
az iot device-update update show -n test-adu-35d878a5c16248 -i myinstance1 --update-provider digimaun --update-name adutest --update-version 1.0.0.2
List files of a specific update
az iot device-update update file list -n test-adu-35d878a5c16248 -i myinstance1 --up digimaun --un adutest --uv 1.0.0.2
Show details of a file for a specific update
az iot device-update update file show -n test-adu-35d878a5c16248 -i myinstance1 --up digimaun --un adutest --uv 1.0.0.2 --ufid fc221eb1cea23218c
Delete a specific update
az iot device-update update delete -n test-adu-35d878a5c16248 -i myinstance1 --update-provider digimaun --update-name adutest --update-version 1.0.0.2
To import ADU aware device and module identities from the linked IoT Hub instance run the following
az iot device-update device import -n test-adu-35d878a5c16248 -i myinstance1
After importing, you can list device identities (with an optional filter)
az iot device-update device list -n test-adu-35d878a5c16248 -i myinstance1
az iot device-update device list -n test-adu-35d878a5c16248 -i myinstance1 --filter "groupId eq 'MyGroup'"
To see the details of a device identity (where the identity is d0).
az iot device-update device show -n test-adu-35d878a5c16248 -i myinstance1 -d d0
To see at a glance compliance for the instance
az iot device-update device compliance show -n test-adu-35d878a5c16248 -i myinstance1
To list instance device health you can run the device health list
command. This is a list operation where filter is required by design.
az iot device-update device health list -n test-adu-35d878a5c16248 -i myinstance1 --filter "state eq 'Healthy'"
❗ Make sure you import ADU-enabled devices before exercising this section.
List all instance device groups (with optional --order-by)
az iot device-update device group list -n test-adu-35d878a5c16248 -i myinstance1
az iot device-update device group list -n test-adu-35d878a5c16248 -i myinstance1 --order-by deviceCount
Show details of a target device group. This command supports multiple flags to modify the operation and see different views of a group. The flags include --update-compliance
and --best-updates
.
az iot device-update device group show -n test-adu-35d878a5c16248 -i myinstance1 --group-id MyGroup
az iot device-update device group show -n test-adu-35d878a5c16248 -i myinstance1 --group-id MyGroup --update-compliance
az iot device-update device group show -n test-adu-35d878a5c16248 -i myinstance1 --group-id MyGroup --best-updates
Delete a group via
az iot device-update device group delete -n test-adu-35d878a5c16248 -i myinstance1 --group-id MyGroup
The delete group operation can be used if there is no need for the group or need to retain history for it. If a device is ever connected again for a group after the group was deleted it will be automatically re-created with no history.
The ADU CLI simplifies concepts by combining device class and device class subgroup management into a single command group az iot device-update device class
. When a command exposes an optional --group-id
parameter, not providing it means the operation is against an instance device class. If --group-id
/--gid
is provided the command operates on the device class subgroup.
List device classes. If listing by --group-id
an optional compatProperties --filter
can be provided.
# List instance classes
az iot device-update device class list -n test-adu-35d878a5c16248 -i myinstance1
# List group classes aka device class subgroup
az iot device-update device class list -n test-adu-35d878a5c16248 -i myinstance1 --gid MyGroup
# List group classes with compatProperties filter
az iot device-update device class list -n test-adu-35d878a5c16248 -i myinstance1 --gid MyGroup --filter "compatProperties/manufacturer eq 'Contoso'"
Show the details of a device class or device class subgroup. This command supports multiple flags to modify the operation and see different views of a class. When used in conjunction with --group-id
the flags --update-compliance
and --best-update
can be used.
az iot device-update device class show -n test-adu-35d878a5c16248 -i myinstance1 --class-id cdad9d100395aba0a920525b4fe6ac24c6c7ad44
az iot device-update device class show -n test-adu-35d878a5c16248 -i myinstance1 --class-id cdad9d100395aba0a920525b4fe6ac24c6c7ad44 --installable-updates
az iot device-update device class show -n test-adu-35d878a5c16248 -i myinstance1 --class-id cdad9d100395aba0a920525b4fe6ac24c6c7ad44 --gid MyGroup --best-update
az iot device-update device class show -n test-adu-35d878a5c16248 -i myinstance1 --class-id cdad9d100395aba0a920525b4fe6ac24c6c7ad44 --gid MyGroup --update-compliance
You can patch update a device class, where currently only --friendly-name
is supported.
az iot device-update device class update -n test-adu-35d878a5c16248 -i myinstance1 --class-id cdad9d100395aba0a920525b4fe6ac24c6c7ad44 --friendly-name "EU-region"
Delete a device class or device class subgroup via
az iot device-update device class delete -n test-adu-35d878a5c16248 -i myinstance1 --class-id cdad9d100395aba0a920525b4fe6ac24c6c7ad44
az iot device-update device class delete -n test-adu-35d878a5c16248 -i myinstance1 --class-id cdad9d100395aba0a920525b4fe6ac24c6c7ad44 --group-id MyGroup
If all device class subgroups for a target device class are deleted then the device class itself can also be deleted to remove the records from the system and to stop checking the compatibility of the device class with new updates. If a device is ever reconnected its device class will be re-created if it does not exist.
❗ This section of operations requires imported devices/modules and diagnostic storage enabled at the account level.
Create a diagnostic log collection with the following command. Note --agent-id
can be used 1 or more times where it expects input in the form of key=value pairs where deviceId
is a required key and moduleId
is optional.
az iot device-update device log collect -n test-adu-35d878a5c16248 -i myinstance1 --lcid mycollection --agent-id deviceId=d0 --description "Test collection"
List existing log collections via
az iot device-update device log list -n test-adu-35d878a5c16248 -i myinstance1
Show a basic or detailed view of an existing log collection
az iot device-update device log show -n test-adu-35d878a5c16248 -i myinstance1 --lcid mycollection
az iot device-update device log show -n test-adu-35d878a5c16248 -i myinstance1 --lcid mycollection --detailed
❗ This section of operations requires imported devices and compatible updates.
Basic deployment creation
az iot device-update device deployment create -n test-adu-35d878a5c16248 -i myinstance1 --group-id MyGroup --deployment-id mydeployment1002 --update-provider digimaun --update-name adutest --update-version 1.0.0.2`
Create deployment with a cloud-initiated rollback policy. Requires an update to rollback to.
az iot device-update device deployment create -n test-adu-35d878a5c16248 -i myinstance1 --group-id MyGroup --deployment-id mydeployment1002 --update-provider digimaun --update-name adutest --update-version 1.0.0.2 --failed-count 10 --failed-percentage 20 --rollback-update-provider digimaun --rollback-update-name adutest --rollback-update-version 1.0.0.0`
List instance deployments by device group or class subgroup
az iot device-update device deployment list -n test-adu-35d878a5c16248 -i myinstance1 --group-id MyGroup
az iot device-update device deployment list -n test-adu-35d878a5c16248 -i myinstance1 --group-id MyGroup --class-id cdad9d100395aba0a920525b4fe6ac24c6c7ad44
Show the details of a deployment by device group or class subgroup including status which details a breakdown of how many devices in the deployment are in progress, completed, or failed.
# By group
az iot device-update device deployment show -n test-adu-35d878a5c16248 -i myinstance1 --gid MyGroup --deployment-id mydeployment1002
az iot device-update device deployment show -n test-adu-35d878a5c16248 -i myinstance1 --gid MyGroup --deployment-id mydeployment1002 --status
# By class subgroup
az iot device-update device deployment show -n test-adu-35d878a5c16248 -i myinstance1 --gid MyGroup --cid cdad9d100395aba0a920525b4fe6ac24c6c7ad44 --deployment-id mydeployment1002
az iot device-update device deployment show -n test-adu-35d878a5c16248 -i myinstance1 --gid MyGroup --cid cdad9d100395aba0a920525b4fe6ac24c6c7ad44 --deployment-id mydeployment1002 --status
List devices in a device class subgroup deployment along with their state. Useful for getting a list of failed devices. This command supports an optional filter.
az iot device-update device deployment list-devices -n test-adu-35d878a5c16248 -i myinstance1 --gid MyGroup --class-id cdad9d100395aba0a920525b4fe6ac24c6c7ad44 --deployment-id mydeployment1002
# With filter
az iot device-update device deployment list-devices -n test-adu-35d878a5c16248 -i myinstance1 --gid MyGroup --class-id cdad9d100395aba0a920525b4fe6ac24c6c7ad44 --deployment-id mydeployment1002 --filter "deviceId eq 'd0' and deviceState eq 'InProgress'"
Retry a device class subgroup deployment
az iot device-update device deployment retry -n test-adu-35d878a5c16248 -i myinstance1 --gid MyGroup --deployment-id mydeployment1002 --cid cdad9d100395aba0a920525b4fe6ac24c6c7ad44
Cancel a device class subgroup deployment
az iot device-update device deployment cancel -n test-adu-35d878a5c16248 -i myinstance1 --gid MyGroup --deployment-id mydeployment1002 --cid cdad9d100395aba0a920525b4fe6ac24c6c7ad44
Delete a deployment by device group or class subgroup
az iot device-update device deployment delete -n test-adu-35d878a5c16248 -i myinstance1 --gid MyGroup --deployment-id mydeployment1002
az iot device-update device deployment delete -n test-adu-35d878a5c16248 -i myinstance1 --gid MyGroup --deployment-id mydeployment1002 --cid cdad9d100395aba0a920525b4fe6ac24c6c7ad44
Using data-plane commands on cloudshell without running az login
again will net an MSI provider 400 error. This is because cloudshell needs to explicitly allow the ADU JWT audience Id.