Device Fleet provisioning in Azure IoT Central

It is easy to provision an individual IoT device in Azure IoT Central. All you need is to create a Device Template, to register a new device, and connect it using chosen authorization mechanism. But what to do if you need to provision hundreds or thousands of IoT devices? I will show you how to do that.

We will implement the following architectural pattern:

Devices will be registered in Azure IoT Central automatically by Device Provisioning Service (DPS). No need to create devices in the AIC explicitly, all the more so because there could be thousands of such devices. But, to make it work, we’ll need to fulfill some prerequisites:

  • Create a device template, which will be used by device twins
  • Generate a root certificate used in a group enrollment
  • Create a group enrollment
  • Generate device certificates.

Let’s start with the first point.

Create a device template

First, we need a device template, which will be automatically associated with our devices, when they connect to the IoT Central.

Open Azure IoT Central and select your AIC application (or create a new one). Select “Device templates” tab in “App settings” of the application, and create a custom template for IoT device. I created a simple “WindSpeed” template with one property:

WindSpeed device template

Save the template and publish it.

Later, we’ll need a model ID, which is used by Azure IoT Central to associate a device with the correct device template. Click on the “View identity” button to open a template identity panel:


“Interface @id” field contains model ID (dtmi:jpTelemetry002:WindSpeed6f2;1). Copy and save this value in a text file for future use.

Generate a root certificate

In order to provide a group enrollment of our devices, we’ll be using X.509 certificates as the recommended device authentication mechanism for IoT Central. Thus, we need to generate an X.509 root certificate for our enrollment group. The process is described in the Generate root and device cert article. But I would suggest to make some changes in this process. First steps are the same: clone the GitHub repository for the certificate generation scripts and install the required packages:

git clone
cd azure-iot-sdk-node/provisioning/tools
npm install

But then, I would recommend to open the create_test_cert.js script in an editor, and change the number of days before expiration to 365 in line 70:

  days: 365,

And then, you can create a root certificate:

node create_test_cert.js root mytestrootcert

Create a group enrollment

Open “Administration” -> “Device connection” panel. Copy and save ID scope for future use:

Press the “Create enrollment group” button to create a new enrollment group with an attestation type of Certificates (X.509):

Open the enrollment group you created and press the “Manage Primary” button. Upload the root certificate mytestrootcert_cert.pem you generated previously:

To complete the verification, generate the verification code and use it to create a verification certificate. Run the script:

node create_test_cert.js verification --ca mytestrootcert_cert.pem --key mytestrootcert_key.pem --nonce {verification-code}

Upload the verification certificate verification_cert.pem to complete the verification process. Now your primary root certificate is verified, and can be used to generate derived device certificates.

Generate device certificates

Each device needs its own leaf certificate, which is derived from the root or intermediate certificate. Run the script to generate a device certificate:

node create_test_cert.js device device-01 mytestrootcert

The script will create three files:


Pay attention to that device-01 is a unique device identifier, which can contain letters, numbers, and the ‘-‘ character. Upon successful enrollment, this X.509 device will appear as device-01 in the “Devices” panel.

To check a device ID of an existing leaf certificate, you can copy the certificate and give the “.crt” extension. For example, copy the device01_cert.pem to device01_cert.crt and open it to see its CNAME value, containing device id:

The code

Clone the azure-iot-blog GitHub repository:

git clone

Change current working directory to iot-central/device-fleet. Copy device certificate files, you created, to this directory.

Open the set_env.bat (or if you are working on Linux) in an editor, and replace values of PROVISIONING_IDSCOPE, DPS_X509_REGISTRATION_ID, MODEL_ID, X509_CERT_FILE, X509_KEY_FILE with the values you saved before.

Run the set_env.bat (or script to set environment variables.

Run the program, provisioning the device-01 and sending simulated telemetry to the IoT Central:


Program output will look like so:

Open your Azure IoT Central application, and select “Devices” tab. You should see your device:

Click on the device name to see its telemetry:


Now you’ve learned how to provision a large number of devices in your IoT Central application without need to register each device manually.

Making a Digital Twin in Azure IoT Central

Perhaps you heard about Internet of Things (IoT). The “Things” can be whatever: vehicles, machines, even fridges, assuming they are connected to the internet. But what is on another end of this connection? In some cases – Digital Twins of the “things”. They are kind of virtual twins of real devices. If some characteristics of a device are changed – they are immediately changed in the twin. And vice versa.

Today we will create a digital twin of a device, measuring temperature and humidity, which I described in my previous article How to make a thermometer. We’ll connect it to the Azure IoT Central and link it with its twin.

Digital Twin

We will implement the following architecture:

Azure IoT Central Application

First what we need to do is to create an application in Azure IoT Central. Open Azure IoT Central site, select “My apps” tab, and click on the “New application” button. Fill in required fields, following the prompts, appearing on the screen, and create an application.

Device Template

When the application is created, select “Device templates” tab in “App settings” of the application, and create a new template. Select “IoT device” type of the template. You will need to give a name of the template:

Now you need to create a model of your twin. If you are creating a new model from scratch, you will choose a Custom model:

Then, select your model in the list of models, and press the “Add capability” button. We will add two capabilities:

  • Temperature with measurement unit “Degree Celsius”
  • Humidity with measurement unit “Percent”.

Add OptimalTemperature property with measurement unit “Degree Celsius”, and make it “Writable” because we need to be able to change this property in a twin.

Let’s add a command just to demonstrate how to send a command (with some parameters) from a twin to a device. Add Reset command with “delay” parameter in its request:

Do not forget to save your changes.

Now we can create a dashboard, visualizing twin’s properties and telemetry. Select “Views” tab and choose “Visualizing the device” as a new view. Give a name of the view, and add tiles for Temperature and Humidity telemetry, and a tile for the Optimal Temperature property.

You can add (optionally) a view called “Editing device and cloud data”. Try to add a section for the Optimal Temperature property.


Select “Devices” tab on the left side menu and press the “New” button. Enter a device name, a unique device id, and choose a device template you created on the previous step:

Now select “Administration” tab on the left side menu, and select “Device connection” tab. You will see a page with device connection parameters:

Save the ID scope in the same text file.

Find a “SAS-IoT_Devices” link on the same page and click on it.

Copy and save a “Primary key” in your text file.

You have three pieces of the puzzle. Now you need to generate a Device Key. To do that, you shall login to the Azure Portal, and click on the “Cloud Shell” button in the upper navigation menu.

Check that you have azure-iot extension installed, and give the command:

az extension add --name azure-iot

Next, generate a Device Key, using Device ID and Primary Key you saved before:

az iot central device compute-device-key --device-id <device_id> --pk <primary_key>

Write down the generated Device Key (without quotes).

IoT device

Now we are ready to assemble our IoT device. We’ll be using a Raspberry Pi 4, a DHT22 temperature sensor, and a LCD display. Read my article How to make a thermometer, and wire up the sensor and the LCD display to the Pi as described there.

Turn on power of the Raspberry Pi and log in to it using your favorite client. You will need to install some libraries:

pip3 install adafruit-circuitpython-dht
sudo apt-get install libgpiod2
sudo apt-get install i2c-tools
sudo apt-get install python-smbus
pip3 install azure-iot-device
pip3 install asyncio

The code

Clone the azure-iot-blog GitHub repository into a folder in your Raspberry Pi:

git clone

Change current working directory to iot-central/digital-twin. There are three files:

First, we will need to check the I2C address of your LCD using the i2cdetect command, as described in the article How to make a thermometer. If needed, update the LDC address in the file.

Second, open the in your favorite editor. It looks like this:

export ID_SCOPE=00000000000
export DEVICE_ID=0000000000
export DEVICE_KEY=00000000000000000000000000000000000000000000

Replace zeroes in this file with the values of the ID scope, Device ID and Device Key you saved before. Save the file and run the command to export variables:


And, finally, you can run the program, collecting telemetry, and sending it to the digital twin:


Program output will look like this, if everything is done right:

If you open your Azure IoT Central application, you can see the telemetry, reflected in the digital twin of your device:

Select “Desired properties” and change the Optimal Temperature value (don’t forget to press Enter in the input field):

If your program is still running, the LCD display will show you updated “Desired” value:

Select “Command”, specify some delay in the input field and press the Run button:

A “Reset” command with delay = 10.5 as an input parameter will be sent from the twin to your IoT device and displayed on the LCD:


There are many thing we can do with the digital twin: we can browse raw data, export it to a storage for future analysis, create rules, triggering some actions based on the data, and much more…

I do not want to explain each line in the code – that would take too much time and make the article even more boring 🙂 But I can suggest you to take a look at the Microsoft tutorial, explaining similar code: Tutorial: Create and connect a client application to your Azure IoT Central application.