Create and provision IoT Edge for Linux on Windows devices at scale using X.509 certificates

Applies to: yes icon IoT Edge 1.1 Other versions: IoT Edge 1.3, IoT Edge 1.4

Applies to: IoT Edge 1.3 checkmark IoT Edge 1.3 IoT Edge 1.4 checkmark IoT Edge 1.4 Other versions: IoT Edge 1.1

This article provides end-to-end instructions for autoprovisioning one or more IoT Edge for Linux on Windows devices using X.509 certificates. You can automatically provision Azure IoT Edge devices with the Azure IoT Hub device provisioning service (DPS). If you're unfamiliar with the process of autoprovisioning, review the provisioning overview before continuing.

Note

The latest version of Azure IoT Edge for Linux on Windows continuous release (EFLOW CR), based on IoT Edge version 1.3, is in public preview. A clean installation may be required for devices going into production use if a general availability (GA) release is available. For more information, see EFLOW versions.

The tasks are as follows:

  1. Generate certificates and keys.
  2. Create either an individual enrollment for a single device or a group enrollment for a set of devices.
  3. Deploy a Linux virtual machine with the IoT Edge runtime installed and connect it to the IoT Hub.

Using X.509 certificates as an attestation mechanism is an excellent way to scale production and simplify device provisioning. Typically, X.509 certificates are arranged in a certificate chain of trust. Starting with a self-signed or trusted root certificate, each certificate in the chain signs the next lower certificate. This pattern creates a delegated chain of trust from the root certificate down through each intermediate certificate to the final "leaf" certificate installed on a device.

Prerequisites

Cloud resources

  • An active IoT hub
  • An instance of the IoT Hub device provisioning service in Azure, linked to your IoT hub

Device requirements

A Windows device with the following minimum requirements:

  • System Requirements

    • Windows 101/11 (Pro, Enterprise, IoT Enterprise)
    • Windows Server 20191/2022
      1 Windows 10 and Windows Server 2019 minimum build 17763 with all current cumulative updates installed.
  • Hardware requirements

    • Minimum Free Memory: 1 GB
    • Minimum Free Disk Space: 10 GB
  • Virtualization support

  • Networking support

    • Windows Server does not come with a default switch. Before you can deploy EFLOW to a Windows Server device, you need to create a virtual switch. For more information, see Create virtual switch for Linux on Windows.
    • Windows Desktop versions come with a default switch that can be used for EFLOW installation. If needed, you can create your own custom virtual switch.

Tip

If you want to use GPU-accelerated Linux modules in your Azure IoT Edge for Linux on Windows deployment, there are several configuration options to consider.

You will need to install the correct drivers depending on your GPU architecture, and you may need access to a Windows Insider Program build. To determine your configuration needs and satisfy these prerequisites, see GPU acceleration for Azure IoT Edge for Linux on Windows.

Make sure you take the time to satisfy the prerequisites for GPU acceleration now. You will need to restart the installation process if you decide you want GPU acceleration during installation.

Developer tools

You can use either PowerShell or Windows Admin Center to manage your IoT Edge devices. Each utility has its own prerequisites:

If you want to use PowerShell, use the following steps to prepare your target device for the installation of Azure IoT Edge for Linux on Windows and the deployment of the Linux virtual machine:

  1. Set the execution policy on the target device to AllSigned. You can check the current execution policy in an elevated PowerShell prompt using the following command:

    Get-ExecutionPolicy -List
    

    If the execution policy of local machine is not AllSigned, you can set the execution policy using:

    Set-ExecutionPolicy -ExecutionPolicy AllSigned -Force
    

For more information on the Azure IoT Edge for Linux on Windows PowerShell module, see the PowerShell functions reference.

Prepare your target device for the installation of Azure IoT Edge for Linux on Windows and the deployment of the Linux virtual machine:

  1. Set the execution policy on the target device to AllSigned. You can check the current execution policy in an elevated PowerShell prompt using the following command:

    Get-ExecutionPolicy -List
    

    If the execution policy of local machine is not AllSigned, you can set the execution policy using:

    Set-ExecutionPolicy -ExecutionPolicy AllSigned -Force
    

For more information on the Azure IoT Edge for Linux on Windows PowerShell module, see the PowerShell functions reference.

Generate device identity certificates

The device identity certificate is a leaf certificate that connects through a certificate chain of trust to the top X.509 certificate authority (CA) certificate. The device identity certificate must have its common name (CN) set to the device ID that you want the device to have in your IoT hub.

Device identity certificates are only used for provisioning the IoT Edge device and authenticating the device with Azure IoT Hub. They aren't signing certificates, unlike the CA certificates that the IoT Edge device presents to modules or leaf devices for verification. For more information, see Azure IoT Edge certificate usage detail.

After you create the device identity certificate, you should have two files: a .cer or .pem file that contains the public portion of the certificate, and a .cer or .pem file with the private key of the certificate. If you plan to use group enrollment in DPS, you also need the public portion of an intermediate or root CA certificate in the same certificate chain of trust.

You need the following files to set up automatic provisioning with X.509:

  • The device identity certificate and its private key certificate. The device identity certificate is uploaded to DPS if you create an individual enrollment. The private key is passed to the IoT Edge runtime.
  • A full chain certificate, which should have at least the device identity and the intermediate certificates in it. The full chain certificate is passed to the IoT Edge runtime.
  • An intermediate or root CA certificate from the certificate chain of trust. This certificate is uploaded to DPS if you create a group enrollment.

Note

Currently, a limitation in libiothsm prevents the use of certificates that expire on or after January 1, 2038.

Use test certificates (optional)

If you don't have a certificate authority available to create new identity certs and want to try out this scenario, the Azure IoT Edge git repository contains scripts that you can use to generate test certificates. These certificates are designed for development testing only, and must not be used in production.

To create test certificates, follow the steps in Create demo certificates to test IoT Edge device features. Complete the two required sections to set up the certificate generation scripts and to create a root CA certificate. Then, follow the steps to create a device identity certificate. When you're finished, you should have the following certificate chain and key pair:

  • <WRKDIR>\certs\iot-edge-device-identity-<name>-full-chain.cert.pem
  • <WRKDIR>\private\iot-edge-device-identity-<name>.key.pem

You need both these certificates on the IoT Edge device. If you're going to use individual enrollment in DPS, then you will upload the .cert.pem file. If you're going to use group enrollment in DPS, then you also need an intermediate or root CA certificate in the same certificate chain of trust to upload. If you're using demo certs, use the <WRKDIR>\certs\azure-iot-test-only.root.ca.cert.pem certificate for group enrollment.

Create a DPS enrollment

Use your generated certificates and keys to create an enrollment in DPS for one or more IoT Edge devices.

If you are looking to provision a single IoT Edge device, create an individual enrollment. If you need multiple devices provisioned, follow the steps for creating a DPS group enrollment.

When you create an enrollment in DPS, you have the opportunity to declare an Initial Device Twin State. In the device twin, you can set tags to group devices by any metric you need in your solution, like region, environment, location, or device type. These tags are used to create automatic deployments.

For more information about enrollments in the device provisioning service, see How to manage device enrollments.

Create a DPS individual enrollment

Individual enrollments take the public portion of a device's identity certificate and match that to the certificate on the device.

Tip

The steps in this article are for the Azure portal, but you can also create individual enrollments using the Azure CLI. For more information, see az iot dps enrollment. As part of the CLI command, use the edge-enabled flag to specify that the enrollment is for an IoT Edge device.

  1. In the Azure portal, navigate to your instance of IoT Hub device provisioning service.

  2. Under Settings, select Manage enrollments.

  3. Select Add individual enrollment then complete the following steps to configure the enrollment:

    • Mechanism: Select X.509.

    • Primary Certificate .pem or .cer file: Upload the public file from the device identity certificate. If you used the scripts to generate a test certificate, choose the following file:

      <WRKDIR>\certs\iot-edge-device-identity-<name>.cert.pem

    • IoT Hub Device ID: Provide an ID for your device if you'd like. You can use device IDs to target an individual device for module deployment. If you don't provide a device ID, the common name (CN) in the X.509 certificate is used.

    • IoT Edge device: Select True to declare that the enrollment is for an IoT Edge device.

    • Select the IoT hubs this device can be assigned to: Choose the linked IoT hub that you want to connect your device to. You can choose multiple hubs, and the device will be assigned to one of them according to the selected allocation policy.

    • Initial Device Twin State: Add a tag value to be added to the device twin if you'd like. You can use tags to target groups of devices for automatic deployment. For example:

      {
          "tags": {
             "environment": "test"
          },
          "properties": {
             "desired": {}
          }
      }
      
  4. Select Save.

Under Manage Enrollments, you can see the Registration ID for the enrollment you just created. Make note of it, as it can be used when you provision your device.

Now that an enrollment exists for this device, the IoT Edge runtime can automatically provision the device during installation.

Install IoT Edge

Deploy Azure IoT Edge for Linux on Windows on your target device.

Install IoT Edge for Linux on Windows on your target device.

Note

The following PowerShell process outlines how to deploy IoT Edge for Linux on Windows onto the local device. To deploy to a remote target device using PowerShell, you can use Remote PowerShell to establish a connection to a remote device and run these commands remotely on that device.

  1. In an elevated PowerShell session, run each of the following commands to download IoT Edge for Linux on Windows.

    $msiPath = $([io.Path]::Combine($env:TEMP, 'AzureIoTEdge.msi'))
    $ProgressPreference = 'SilentlyContinue'
    Invoke-WebRequest "https://aka.ms/AzEflowMSI" -OutFile $msiPath
    
  2. Install IoT Edge for Linux on Windows on your device.

    Start-Process -Wait msiexec -ArgumentList "/i","$([io.Path]::Combine($env:TEMP, 'AzureIoTEdge.msi'))","/qn"
    

    You can specify custom IoT Edge for Linux on Windows installation and VHDX directories by adding INSTALLDIR="<FULLY_QUALIFIED_PATH>" and VHDXDIR="<FULLY_QUALIFIED_PATH>" parameters to the install command. For example, if you want to use the D:\EFLOW folder for installation and the D:\EFLOW-VHDX for the VHDX, you can use the following PowerShell cmdlet.

    Start-Process -Wait msiexec -ArgumentList "/i","$([io.Path]::Combine($env:TEMP, 'AzureIoTEdge.msi'))","/qn","INSTALLDIR=D:\EFLOW", "VHDXDIR=D:\EFLOW-VHDX"
    
  3. Set the execution policy on the target device to AllSigned if it is not already. See the PowerShell prerequisites for commands to check the current execution policy and set the execution policy to AllSigned.

  4. Create the IoT Edge for Linux on Windows deployment. The deployment creates your Linux virtual machine and installs the IoT Edge runtime for you.

    Deploy-Eflow
    

    Tip

    By default, the Deploy-Eflow command creates your Linux virtual machine with 1 GB of RAM, 1 vCPU core, and 16 GB of disk space. However, the resources your VM needs are highly dependent on the workloads you deploy. If your VM does not have sufficient memory to support your workloads, it will fail to start.

    You can customize the virtual machine's available resources using the Deploy-Eflow command's optional parameters.

    For example, the command below creates a virtual machine with 4 vCPU cores, 4 GB of RAM (represented in MB), and 20 GB of disk space:

    Deploy-Eflow -cpuCount 4 -memoryInMB 4096 -vmDiskSize 20
    

    For information about all the optional parameters available, see PowerShell functions for IoT Edge for Linux on Windows.

    Warning

    By default, the EFLOW Linux virtual machine has no DNS configuration. Deployments using DHCP will try to obtain the DNS configuration propagated by the DHCP server. Please check your DNS configuration to ensure internet connectivity. For more information, see AzEFLOW-DNS.

    You can assign a GPU to your deployment to enable GPU-accelerated Linux modules. To gain access to these features, you will need to install the prerequisites detailed in GPU acceleration for Azure IoT Edge for Linux on Windows.

    To use a GPU passthrough, add the gpuName, gpuPassthroughType, and gpuCount parameters to your Deploy-Eflow command. For information about all the optional parameters available, see PowerShell functions for IoT Edge for Linux on Windows.

    Warning

    Enabling hardware device passthrough may increase security risks. Microsoft recommends a device mitigation driver from your GPU's vendor, when applicable. For more information, see Deploy graphics devices using discrete device assignment.

  5. Enter 'Y' to accept the license terms.

  6. Enter 'O' or 'R' to toggle Optional diagnostic data on or off, depending on your preference.

  7. Once the deployment is complete, the PowerShell window reports Deployment successful.

    A successful deployment will say 'Deployment successful' at the end of the messages, PNG.

    After a successful deployment, you are ready to provision your device.

Note

The following PowerShell process outlines how to deploy IoT Edge for Linux on Windows onto the local device. To deploy to a remote target device using PowerShell, you can use Remote PowerShell to establish a connection to a remote device and run these commands remotely on that device.

  1. In an elevated PowerShell session, run each of the following commands to download IoT Edge for Linux on Windows.

    • X64/AMD64

      $msiPath = $([io.Path]::Combine($env:TEMP, 'AzureIoTEdge.msi'))
      $ProgressPreference = 'SilentlyContinue'
      Invoke-WebRequest "https://aka.ms/AzEFLOWMSI-CR-X64" -OutFile $msiPath
      
    • ARM64

      $msiPath = $([io.Path]::Combine($env:TEMP, 'AzureIoTEdge.msi'))
      $ProgressPreference = 'SilentlyContinue'
      Invoke-WebRequest "https://aka.ms/AzEFLOWMSI-CR-ARM64" -OutFile $msiPath
      
  1. In an elevated PowerShell session, run each of the following commands to download IoT Edge for Linux on Windows.

    • X64/AMD64

      $msiPath = $([io.Path]::Combine($env:TEMP, 'AzureIoTEdge.msi'))
      $ProgressPreference = 'SilentlyContinue'
      Invoke-WebRequest "https://aka.ms/AzEFLOWMSI_1_4_LTS_X64" -OutFile $msiPath
      
    • ARM64

      $msiPath = $([io.Path]::Combine($env:TEMP, 'AzureIoTEdge.msi'))
      $ProgressPreference = 'SilentlyContinue'
      Invoke-WebRequest "https://aka.ms/AzEFLOWMSI_1_4_LTS_ARM64" -OutFile $msiPath
      
  1. Install IoT Edge for Linux on Windows on your device.

    Start-Process -Wait msiexec -ArgumentList "/i","$([io.Path]::Combine($env:TEMP, 'AzureIoTEdge.msi'))","/qn"
    

    You can specify custom IoT Edge for Linux on Windows installation and VHDX directories by adding INSTALLDIR="<FULLY_QUALIFIED_PATH>" and VHDXDIR="<FULLY_QUALIFIED_PATH>" parameters to the install command. For example, if you want to use the D:\EFLOW folder for installation and the D:\EFLOW-VHDX for the VHDX, you can use the following PowerShell cmdlet.

    Start-Process -Wait msiexec -ArgumentList "/i","$([io.Path]::Combine($env:TEMP, 'AzureIoTEdge.msi'))","/qn","INSTALLDIR=D:\EFLOW", "VHDXDIR=D:\EFLOW-VHDX"
    
  2. Set the execution policy on the target device to AllSigned if it is not already. See the PowerShell prerequisites for commands to check the current execution policy and set the execution policy to AllSigned.

  3. Create the IoT Edge for Linux on Windows deployment. The deployment creates your Linux virtual machine and installs the IoT Edge runtime for you.

    Deploy-Eflow
    

    Tip

    By default, the Deploy-Eflow command creates your Linux virtual machine with 1 GB of RAM, 1 vCPU core, and 16 GB of disk space. However, the resources your VM needs are highly dependent on the workloads you deploy. If your VM does not have sufficient memory to support your workloads, it will fail to start.

    You can customize the virtual machine's available resources using the Deploy-Eflow command's optional parameters. This is required to deploy EFLOW on a device with the minimum hardware requirements.

    For example, the command below creates a virtual machine with 1 vCPU core, 1 GB of RAM (represented in MB), and 2 GB of disk space:

    Deploy-Eflow -cpuCount 1 -memoryInMB 1024 -vmDiskSize 2
    

    Note: vmDataSize is a new parameter intriduced in the EFLOW CR version.

    For information about all the optional parameters available, see PowerShell functions for IoT Edge for Linux on Windows.

    Warning

    By default, the EFLOW Linux virtual machine has no DNS configuration. Deployments using DHCP will try to obtain the DNS configuration propagated by the DHCP server. Please check your DNS configuration to ensure internet connectivity. For more information, see AzEFLOW-DNS.

    You can assign a GPU to your deployment to enable GPU-accelerated Linux modules. To gain access to these features, you will need to install the prerequisites detailed in GPU acceleration for Azure IoT Edge for Linux on Windows.

    To use a GPU passthrough, add the gpuName, gpuPassthroughType, and gpuCount parameters to your Deploy-Eflow command. For information about all the optional parameters available, see PowerShell functions for IoT Edge for Linux on Windows.

    Warning

    Enabling hardware device passthrough may increase security risks. Microsoft recommends a device mitigation driver from your GPU's vendor, when applicable. For more information, see Deploy graphics devices using discrete device assignment.

  4. Enter 'Y' to accept the license terms.

  5. Enter 'O' or 'R' to toggle Optional diagnostic data on or off, depending on your preference.

  6. Once the deployment is complete, the PowerShell window reports Deployment successful.

    A successful deployment will say 'Deployment successful' at the end of the messages, PNG.

    After a successful deployment, you are ready to provision your device.

Provision the device with its cloud identity

Once the runtime is installed on your device, configure the device with the information it uses to connect to the device provisioning service and IoT Hub.

Have the following information ready:

  • The DPS ID Scope value. You can retrieve this value from the overview page of your DPS instance in the Azure portal.
  • The device identity certificate chain file on the device.
  • The device identity key file on the device.

You can use either PowerShell or Windows Admin Center to provision your IoT Edge device.

For PowerShell, run the following command with the placeholder values updated with your own values:

Provision-EflowVm -provisioningType DpsX509 -scopeId PASTE_YOUR_ID_SCOPE_HERE -registrationId PASTE_YOUR_REGISTRATION_ID_HERE -identityCertPath PASTE_ABSOLUTE_PATH_TO_IDENTITY_CERTIFICATE_HERE -identityPrivKeyPath PASTE_ABSOLUTE_PATH_TO_IDENTITY_PRIVATE_KEY_HERE

Run the following command in an elevated PowerShell session with the placeholder values updated with your own values:

Provision-EflowVm -provisioningType DpsX509 -scopeId PASTE_YOUR_ID_SCOPE_HERE -registrationId PASTE_YOUR_REGISTRATION_ID_HERE -identityCertPath PASTE_ABSOLUTE_PATH_TO_IDENTITY_CERTIFICATE_HERE -identityPrivateKey PASTE_ABSOLUTE_PATH_TO_IDENTITY_PRIVATE_KEY_HERE

Verify successful installation

Verify that IoT Edge for Linux on Windows was successfully installed and configured on your IoT Edge device.

You can verify that the individual enrollment that you created in device provisioning service was used. Navigate to your device provisioning service instance in the Azure portal. Open the enrollment details for the individual enrollment that you created. Notice that the status of the enrollment is assigned and the device ID is listed.

  1. Log in to your IoT Edge for Linux on Windows virtual machine using the following command in your PowerShell session:

    Connect-EflowVm
    

    Note

    The only account allowed to SSH to the virtual machine is the user that created it.

  2. Once you are logged in, you can check the list of running IoT Edge modules using the following Linux command:

    sudo iotedge list
    
  3. If you need to troubleshoot the IoT Edge service, use the following Linux commands.

    1. If you need to troubleshoot the service, retrieve the service logs.

      sudo journalctl -u iotedge
      
    2. Use the check tool to verify configuration and connection status of the device.

      sudo iotedge check
      

    Note

    On a newly provisioned device, you may see an error related to IoT Edge Hub:

    × production readiness: Edge Hub's storage directory is persisted on the host filesystem - Error

    Could not check current state of edgeHub container

    This error is expected on a newly provisioned device because the IoT Edge Hub module isn't running. To resolve the error, in IoT Hub, set the modules for the device and create a deployment. Creating a deployment for the device starts the modules on the device including the IoT Edge Hub module.

  1. Log in to your IoT Edge for Linux on Windows virtual machine using the following command in your PowerShell session:

    Connect-EflowVm
    

    Note

    The only account allowed to SSH to the virtual machine is the user that created it.

  2. Once you are logged in, you can check the list of running IoT Edge modules using the following Linux command:

    sudo iotedge list
    
  3. If you need to troubleshoot the IoT Edge service, use the following Linux commands.

    1. If you need to troubleshoot the service, retrieve the service logs.

      sudo iotedge system logs
      
    2. Use the check tool to verify configuration and connection status of the device.

      sudo iotedge check
      

    Note

    On a newly provisioned device, you may see an error related to IoT Edge Hub:

    × production readiness: Edge Hub's storage directory is persisted on the host filesystem - Error

    Could not check current state of edgeHub container

    This error is expected on a newly provisioned device because the IoT Edge Hub module isn't running. To resolve the error, in IoT Hub, set the modules for the device and create a deployment. Creating a deployment for the device starts the modules on the device including the IoT Edge Hub module.

When you create a new IoT Edge device, it will display the status code 417 -- The device's deployment configuration is not set in the Azure portal. This status is normal, and means that the device is ready to receive a module deployment.

Uninstall IoT Edge for Linux on Windows

If you want to remove the Azure IoT Edge for Linux on Windows installation from your device, use the following commands.

  1. Open Settings on Windows
  2. Select Add or Remove Programs
  3. Select Azure IoT Edge LTS app
  4. Select Uninstall
  1. Open Settings on Windows
  2. Select Add or Remove Programs
  3. Select Azure IoT Edge app
  4. Select Uninstall

Next steps

The device provisioning service enrollment process lets you set the device ID and device twin tags at the same time as you provision the new device. You can use those values to target individual devices or groups of devices using automatic device management. Learn how to Deploy and monitor IoT Edge modules at scale using the Azure portal or using Azure CLI.

You can also: