Azure IoT Hub Device Provisioning Service のカスタム割り当てポリシーを理解する
カスタム割り当てポリシーを使用すると、デバイスを IoT ハブに割り当てる方法をより細かくコントロールできます。 Device Provisioning Service (DPS) で提供される組み込みのポリシーがご自身のシナリオの要件を満たしていない場合は、カスタム割り当てポリシーを使用して独自の割り当てポリシーを定義できます。
たとえば、プロビジョニングの際にデバイスで使用されている証明書を確認し、証明書のプロパティに基づいて IoT ハブにデバイスを割り当てる必要がある場合です。 または、デバイス用のデータベースに情報を格納していて、どの IoT ハブにデバイスを割り当てるか、またはデバイスの初期ツインの設定方法を決定するためにそのデータベースを照会する必要がある場合です。
カスタム割り当てポリシーは、Azure Functions でホストされている Webhook に実装します。 その後、1 つ以上の個別登録と登録グループで Webhook を構成できます。 構成された登録エントリを介してデバイスで登録されると、DPS では Webhook が呼び出され、IoT ハブを返してデバイスを登録し、必要に応じて、デバイスの初期ツイン設定とデバイスに直接返される情報が取得されます。
概要
次の手順では、カスタム割り当てポリシーのしくみについて説明します。
カスタム割り当ての開発者は、目的の割り当てポリシーを実装する Webhook を開発し、それを HTTP トリガー関数として Azure Functions にデプロイします。 Webhook では、DPS 登録エントリとデバイスに関する情報が取得され、デバイスの登録が必要な IoT ハブと、必要に応じてデバイスの初期状態に関する情報が返されます。
IoT オペレーターは、カスタム割り当て用に 1 つ以上の個別登録や登録グループを構成し、Azure Functions のカスタム割り当て Webhook の呼び出しに関する詳細を提供します。
カスタム割り当て Webhook 用に構成された登録エントリを介してデバイスで登録されると、DPS では要求本文を AllocationRequest 要求オブジェクトに設定して POST 要求が Webhook に送信されます。 AllocationRequest オブジェクトには、プロビジョニングしようとしているデバイスと、プロビジョニングする個別登録または登録グループに関する情報が含まれます。 デバイス情報には、登録要求でデバイスから送信されたオプションのカスタム ペイロードを含めることができます。 詳細については、「カスタム割り当てポリシーの要求」を参照してください。
Azure 関数では、成功した場合に AllocationResponse オブジェクトが実行され返されます。 AllocationResponse オブジェクトには、デバイスのプロビジョニングが必要な IoT ハブ、初期ツイン状態、およびデバイスに返すオプションのカスタム ペイロードが含まれています。 詳細については、「カスタム割り当てポリシーの応答」を参照してください。
DPS では、応答で示された IoT ハブにデバイスが割り当てられ、初期ツインが返された場合は、それに応じてデバイスの初期ツインが設定されます。 カスタム ペイロードが Webhook によって返された場合、割り当てられた IoT ハブと DPS からの登録応答の認証の詳細と共にデバイスに渡されます。
デバイスは、割り当てられた IoT ハブに接続され、その初期ツイン状態がダウンロードされます。 登録応答でカスタム ペイロードが返された場合、デバイスでは、独自のクライアント側ロジックに従ってそれが使用されます。
次のセクションでは、カスタム割り当ての要求と応答、カスタム ペイロード、ポリシーの実装について詳しく説明します。 カスタム割り当てポリシーの完全なエンド ツー エンドの例については、カスタム割り当てポリシーの使用に関するページを参照してください。
カスタム割り当てポリシーの要求
DPS では、次のエンドポイント: https://{your-function-app-name}.azurewebsites.net/api/{your-http-trigger}
で Webhook に POST 要求が送信されます。
要求本文は AllocationRequest オブジェクトです。
プロパティ名 | 説明 |
---|---|
individualEnrollment | 割り当て要求の送信元の個別登録に関連付けられているプロパティを含む個別登録のレコード。 個別登録を介してデバイスで登録されている場合に表示されます。 |
enrollmentGroup | 割り当て要求の送信元の登録グループに関連付けられているプロパティを含む登録グループのレコード。 登録グループを介してデバイスで登録されている場合に表示されます。 |
deviceRuntimeContext | 登録が行われているデバイスに関連付けられているプロパティを含むオブジェクト。 常に存在します。 |
linkedHubs | 割り当て要求の送信元の登録エントリにリンクされている IoT ハブのホスト名を含む配列。 デバイスは、これらの IoT ハブのいずれかに割り当てることができます。 常に存在します。 |
DeviceRuntimeContext オブジェクトには、次のプロパティがあります。
プロパティ | タイプ | 説明 |
---|---|---|
registrationId | string | 実行時にデバイスで提供される登録 ID。 常に存在します。 |
currentIotHubHostName | string | デバイスが以前に割り当てられた IoT ハブのホスト名 (存在する場合)。 これが最初の割り当ての場合は存在しません。 このプロパティを使用して、これがデバイスの最初の割り当てであるか、デバイスが以前に割り当てられているかどうかを判断できます。 |
currentDeviceId | string | デバイスの以前の割り当て時のデバイス ID (存在する場合)。 これが最初の割り当ての場合は存在しません。 |
x509 | X509DeviceAttestation | X.509 構成証明の場合は、証明書の詳細が含まれます。 |
symmetricKey | SymmetricKeyAttestation | 対称キー構成証明の場合は、主キーとセカンダリ キーの詳細が含まれます。 |
tpm | TpmAttestation | TPM 構成証明の場合は、保証キーとストレージ ルート キーの詳細が含まれます。 |
payload | object | 登録時にデバイスのペイロード プロパティで指定されたプロパティが含まれます。 DPS 登録要求でデバイスからカスタム ペイロードが送信される場合に表示されます。 |
次の JSON は、対称キー ベースの登録グループを介して登録するデバイスに対して DPS から送信される AllocationRequest オブジェクトを示しています。
{
"enrollmentGroup":{
"enrollmentGroupId":"contoso-custom-allocated-devices",
"attestation":{
"type":"symmetricKey"
},
"capabilities":{
"iotEdge":false
},
"etag":"\"13003fea-0000-0300-0000-62d1d5e50000\"",
"provisioningStatus":"enabled",
"reprovisionPolicy":{
"updateHubAssignment":true,
"migrateDeviceData":true
},
"createdDateTimeUtc":"2022-07-05T21:27:16.8123235Z",
"lastUpdatedDateTimeUtc":"2022-07-15T21:02:29.5922255Z",
"allocationPolicy":"custom",
"iotHubs":[
"custom-allocation-toasters-hub.azure-devices.net",
"custom-allocation-heatpumps-hub.azure-devices.net"
],
"customAllocationDefinition":{
"webhookUrl":"https://custom-allocation-function-app-3.azurewebsites.net/api/HttpTrigger1?****",
"apiVersion":"2021-10-01"
}
},
"deviceRuntimeContext":{
"registrationId":"breakroom499-contoso-tstrsd-007",
"symmetricKey":{
}
},
"linkedHubs":[
"custom-allocation-toasters-hub.azure-devices.net",
"custom-allocation-heatpumps-hub.azure-devices.net"
]
}
これはデバイスの初期登録であるため、deviceRuntimeContext プロパティには、デバイスの登録 ID と認証の詳細のみが含まれています。 次の JSON は、同じデバイスを登録する後続の呼び出しの deviceRuntimeContext を示しています。 現在の IoT Hub ホスト名とデバイス ID が要求に含まれていることに注意してください。
{
"deviceRuntimeContext":{
"registrationId":"breakroom499-contoso-tstrsd-007",
"currentIotHubHostName":"custom-allocation-toasters-hub.azure-devices.net",
"currentDeviceId":"breakroom499-contoso-tstrsd-007",
"symmetricKey":{
}
},
}
カスタム割り当てポリシーの応答
要求が成功すると、AllocationResponse オブジェクトが返されます。
プロパティ | 説明 |
---|---|
initialTwin | 省略可能。 割り当てられた IoT ハブの初期ツインで設定が必要なプロパティとタグを含むオブジェクト。 DPS では、最初の割り当て時、または登録エントリの移行ポリシーが "再プロビジョニングして初期構成にリセット" に設定され再プロビジョニングされる際に、initialTwin プロパティを使用して、割り当てられた IoT ハブに初期ツインが設定されます。どちらの場合も、initialTwin が返されない、または null に設定されている場合、DPS では割り当てられた IoT ハブのツインを登録エントリの初期ツイン設定に設定します。 DPS では、登録エントリ内にある他のすべての再プロビジョニング設定の initialTwin は無視されます。 詳細については、「実装の詳細」を参照してください。 |
iotHubHostName | 必須。 デバイスを割り当てる IoT ハブのホスト名。 これは、要求の linkedHubs プロパティで渡される IoT ハブのいずれかである必要があります。 |
payload | 省略可能。 Registration 応答でデバイスに返されるデータを含むオブジェクト。 正確なデータは、デバイスとカスタム割り当て関数の間で開発者が定義した暗黙的なコントラクトによって異なります。 |
次の JSON は、上記の登録例について、カスタム割り当て関数で DPS に返される AllocationResponse オブジェクトを示しています。
{
"iotHubHostName":"custom-allocation-toasters-hub.azure-devices.net",
"initialTwin":{
"properties":{
"desired":{
"state":"ready",
"darknessSetting":"medium"
}
},
"tags":{
"deviceType":"toaster"
}
}
}
カスタム割り当てでデバイス ペイロードを使用する
デバイスでは、DPS から渡されるカスタム ペイロードをカスタム割り当て Webhook に送信でき、そのデータはロジックで使用できます。 Webhook では、デバイスを割り当てる IoT ハブを特定したり、初期ツインのプロパティを設定するために使用される外部データベース内の情報を検索したりするためなど、さまざまな方法でこのデータが使用される場合があります。 逆に、Webhook では DPS を介してデバイスにデータを返すことができます。これは、デバイスのクライアント側ロジックで使用できます。
たとえば、デバイス モデルに基づいてデバイス名を割り当てる必要があるとします。 この場合、DPS に登録するときに要求ペイロード内のモデル情報を報告するようにデバイスを構成できます。 DPS ではこのペイロードをカスタム割り当て Webhook に渡します。これにより、デバイス モデル情報に基づいて、デバイスがプロビジョニングされる IoT ハブが決定されます。 必要に応じて、Webhook では Webhook 応答の JSON オブジェクトとして DPS にデータを返すことができます。DPS では登録応答でこのデータをデバイスに返します。
デバイスから DPS にデータ ペイロードを送信する
デバイスでレジスタ API が呼び出されて DPS に登録されます。 要求は、オプションのペイロード プロパティを使用して拡張できます。 このプロパティには、任意の有効な JSON オブジェクトを含めることができます。 正確な内容は、ソリューションの要件によって異なります。
TPM での構成証明の場合、要求本文は次のようになります。
{
"registrationId": "mydevice",
"tpm": {
"endorsementKey": "xxxx-device-endorsement-key-xxxxx",
"storageRootKey": "xxxx-device-storage-root-key-xxxxx"
},
"payload": { "property1": "value1", "property2": {"propertyA":"valueA", "property2-2":1234}, .. }
}
DPS からカスタム割り当て Webhook にデータ ペイロードを送信する
デバイスに登録要求のペイロードが含まれている場合、DPS ではカスタム割り当て Webhook を呼び出すときに AllocationRequest.deviceRuntimeContext.payload プロパティでペイロードが渡されます。
前のセクションの TPM 登録要求の場合、デバイスのランタイム コンテキストは次のようになります。
{
"registrationId": "mydevice",
"tpm": {
"endorsementKey": "xxxx-device-endorsement-key-xxxxx",
"storageRootKey": "xxxx-device-storage-root-key-xxxxx"
},
"payload": { "property1": "value1", "property2": {"propertyA":"valueA", "property2-2":1234}, .. }
}
これがデバイスの初期登録でない場合、ランタイム コンテキストには currentIoTHubHostname および currentDeviceId プロパティも含まれます。
カスタム割り当て Webhook から DPS にデータを返送する
カスタム割り当てポリシー Webhook では、Webhook 応答で AllocationResponse.payload プロパティを使用すると、デバイスを対象としたデータを JSON オブジェクトで DPS に返すことができます。
次の JSON は、ペイロードを含む Webhook 応答を示しています。
{
"iotHubHostName":"custom-allocation-toasters-hub.azure-devices.net",
"initialTwin":{
"properties":{
"desired":{
"state":"ready",
"darknessSetting":"medium"
}
},
"tags":{
"deviceType":"toaster"
}
},
"payload": { "property1": "value1" }
}
DPS からデバイスにデータ ペイロードを送信する
DPS では、Webhook 応答でペイロードを受信した場合、登録が成功した場合の応答で、RegistrationOperationStatus.registrationState.payload プロパティ内のデバイスにこのデータを渡します。 registrationState プロパティは、DeviceRegistrationResult 型です。
次の JSON は、ペイロード プロパティを含む TPM デバイスの正常な登録応答を示しています。
{
"operationId":"5.316aac5bdc130deb.b1e02da8-xxxx-xxxx-xxxx-7ea7a6b7f550",
"status":"assigned",
"registrationState":{
"assignedHub":"myIotHub",
"createdDateTimeUtc" : "2022-08-01T22:57:47Z",
"deviceId" : "myDeviceId",
"etag" : "xxxx-etag-value-xxxxx",
"lastUpdatedDateTimeUtc" : "2022-08-01T22:57:47Z",
"payload": { "property1": "value1" },
"registrationId": "mydevice",
"status": assigned,
"substatus": initialAssignment,
"tpm": {"authenticationKey": "xxxx-encrypted-authentication-key-xxxxx"}
}
}
実装詳細
カスタム割り当て Webhook は、DPS で以前に登録されていないデバイス (最初の割り当て) または DPS で以前に登録されたデバイス (再プロビジョニング) に対して呼び出すことができます。 DPS では、次の再プロビジョニング ポリシーがサポートされています。"データの再プロビジョニングと移行"、"再プロビジョニングして初期構成にリセット"、および "再プロビジョニングしない"。 これらのポリシーは、以前にプロビジョニングされたデバイスが新しい IoT ハブに割り当てられるたびに適用されます。 詳細については、再プロビジョニングに関するページを参照してください。
次のポイントでは、カスタム割り当て Webhook で監視する必要がある要件と、Webhook を設計するときに注意する必要がある動作について説明します。
デバイスは、AllocationRequest.linkedHubs プロパティのいずれかの IoT ハブに割り当てる必要があります。 このプロパティには、デバイスを割り当てることができるホスト名別の IoT ハブの一覧が含まれています。 これは通常、登録エントリ用に選択された IoT ハブで構成されています。 登録エントリで IoT ハブが選択されていない場合は、DPS インスタンスにリンクされているすべての IoT ハブが含まれます。 最後に、デバイスが再プロビジョニング中で、登録エントリに "再プロビジョニングしない" ポリシーが設定されている場合、デバイスが現在割り当てられている IoT ハブのみが含まれます。
最初の割り当て時に、Webhook から initialTwin プロパティが返された場合、DPS では割り当てられた IoT ハブ上のデバイスの初期ツインを適宜設定します。 initialTwin プロパティが省略されているか null の場合、DPS ではデバイスの初期ツインを登録エントリで指定された初期ツイン設定に設定します。
再プロビジョニングの際は、DPS では登録エントリで設定された再プロビジョニング ポリシーが遵守されます。 DPS では、現在の IoT ハブが変更され、登録エントリに設定されている再プロビジョニング ポリシーが "再プロビジョニングして初期構成にリセット" である場合、応答では initialTwin プロパティのみが使用されます。この場合、DPS では、前の箇条書きの最初の割り当て時とまったく同じように、新しい IoT ハブ上のデバイスの初期ツインが設定されます。 それ以外の場合、DPS では initialTwin プロパティは無視されます。
応答でペイロード プロパティが設定されている場合、DPS では、要求が最初の割り当て用か再プロビジョニング用かに関係なく、常にデバイスに返されます。
デバイスが以前に IoT ハブにプロビジョニングされている場合、AllocationRequest.deviceRuntimeContext には currentIotHubHostName プロパティが含まれます。このプロパティは、デバイスが現在割り当てられている IoT ハブのホスト名に設定されます。
要求で AllocationRequest.individualEnrollment または AllocationRequest.enrollmentGroup プロパティの reprovisionPolicy プロパティを調べると、登録エントリで現在設定されている再プロビジョニング ポリシーを特定できます。 次の JSON は、"データの再プロビジョニングと移行" ポリシーの設定を示しています。
"reprovisionPolicy":{ "updateHubAssignment":true, "migrateDeviceData":true }
SDK サポート
DPS デバイス SDK では、デバイスを DPS に登録するのに役立つ C、C#、Java、および Node.js の API を提供しています。 IoT Hub SDK と DPS SDK のどちらでも、デバイス ツインや登録エントリなどのデバイスとサービスの成果物を表すクラスを提供しています。これは、カスタム割り当て Webhook を開発するときに役立つ可能性があります。 IoT Hub と IoT Hub Device Provisioning サービスで利用可能な Azure IoT SDK の詳細については、「Microsoft Azure IoT SDKs」および Azure DPS SDK に関するページを参照してください。
次のステップ
カスタム割り当てポリシーを使用するエンド ツー エンドの例については、カスタム割り当てポリシーの使用に関するページを参照してください
Azure Functions の詳細については、「Azure Functions のドキュメント」を参照してください