Share via


クイック スタート:ARM テンプレートを使用して Azure IoT ハブとストレージ アカウントをデプロイする

このクイックスタートでは、Azure Resource Manager テンプレート (ARM テンプレート) を使用して、IoT ハブと Azure Storage アカウント、および IoT ハブからストレージにメッセージを送信するルートを作成します。 このハブは、ルーティング条件が満たされた場合に、そのハブに送信されたメッセージをストレージ アカウントに自動的にルーティングするように構成されます。 このクイックスタートの最後には、ストレージ アカウントを開いて、送信されたメッセージを確認することができます。

Azure Resource Manager テンプレートは JavaScript Object Notation (JSON) ファイルであり、プロジェクトのインフラストラクチャと構成が定義されています。 このテンプレートでは、宣言型の構文が使用されています。 デプロイしようとしているものを、デプロイを作成する一連のプログラミング コマンドを記述しなくても記述できます。

環境が前提条件を満たしていて、ARM テンプレートの使用に慣れている場合は、 [Azure へのデプロイ] ボタンを選択します。 テンプレートが Azure portal で開きます。

Deploy To Azure

前提条件

テンプレートを確認する

このクイックスタートでは、Azure クイックスタート テンプレートから入手した 101-iothub-auto-route-messages というテンプレートを使用します。

テンプレートでは、次の 2 つの Azure リソースが定義されています。

  • Microsoft.Storage/storageAccounts: コンテナーを含むストレージ アカウント。
  • Microsoft.Devices/IotHubs: ストレージ コンテナーを指すエンドポイントと、フィルター処理されたメッセージをそのエンドポイントに送信するルートを持つ IoT ハブ。
{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "metadata": {
    "_generator": {
      "name": "bicep",
      "version": "0.26.54.24096",
      "templateHash": "1111741482289134864"
    }
  },
  "parameters": {
    "projectName": {
      "type": "string",
      "defaultValue": "contoso",
      "minLength": 1,
      "maxLength": 11,
      "metadata": {
        "description": "Define the project name or prefix for all objects."
      }
    },
    "location": {
      "type": "string",
      "defaultValue": "[resourceGroup().location]",
      "metadata": {
        "description": "The datacenter to use for the deployment."
      }
    },
    "skuName": {
      "type": "string",
      "defaultValue": "S1",
      "metadata": {
        "description": "The SKU to use for the IoT Hub."
      }
    },
    "skuUnits": {
      "type": "int",
      "defaultValue": 1,
      "metadata": {
        "description": "The number of IoT Hub units."
      }
    },
    "d2cPartitions": {
      "type": "int",
      "defaultValue": 4,
      "metadata": {
        "description": "Partitions used for the event stream."
      }
    }
  },
  "variables": {
    "iotHubName": "[format('{0}Hub{1}', parameters('projectName'), uniqueString(resourceGroup().id))]",
    "storageAccountName": "[format('{0}{1}', toLower(parameters('projectName')), uniqueString(resourceGroup().id))]",
    "storageEndpoint": "[format('{0}StorageEndpont', parameters('projectName'))]",
    "storageContainerName": "[format('{0}results', toLower(parameters('projectName')))]"
  },
  "resources": [
    {
      "type": "Microsoft.Storage/storageAccounts",
      "apiVersion": "2023-01-01",
      "name": "[variables('storageAccountName')]",
      "location": "[parameters('location')]",
      "sku": {
        "name": "Standard_LRS"
      },
      "kind": "Storage",
      "properties": {
        "allowBlobPublicAccess": false,
        "minimumTlsVersion": "TLS1_2",
        "supportsHttpsTrafficOnly": true
      }
    },
    {
      "type": "Microsoft.Storage/storageAccounts/blobServices/containers",
      "apiVersion": "2023-01-01",
      "name": "[format('{0}/default/{1}', variables('storageAccountName'), variables('storageContainerName'))]",
      "properties": {
        "publicAccess": "None"
      },
      "dependsOn": [
        "[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName'))]"
      ]
    },
    {
      "type": "Microsoft.Devices/IotHubs",
      "apiVersion": "2023-06-30",
      "name": "[variables('iotHubName')]",
      "location": "[parameters('location')]",
      "sku": {
        "name": "[parameters('skuName')]",
        "capacity": "[parameters('skuUnits')]"
      },
      "properties": {
        "eventHubEndpoints": {
          "events": {
            "retentionTimeInDays": 1,
            "partitionCount": "[parameters('d2cPartitions')]"
          }
        },
        "routing": {
          "endpoints": {
            "storageContainers": [
              {
                "connectionString": "[format('DefaultEndpointsProtocol=https;AccountName={0};EndpointSuffix={1};AccountKey={2}', variables('storageAccountName'), environment().suffixes.storage, listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName')), '2023-01-01').keys[0].value)]",
                "containerName": "[variables('storageContainerName')]",
                "fileNameFormat": "{iothub}/{partition}/{YYYY}/{MM}/{DD}/{HH}/{mm}",
                "batchFrequencyInSeconds": 100,
                "maxChunkSizeInBytes": 104857600,
                "encoding": "JSON",
                "name": "[variables('storageEndpoint')]"
              }
            ]
          },
          "routes": [
            {
              "name": "ContosoStorageRoute",
              "source": "DeviceMessages",
              "condition": "level=\"storage\"",
              "endpointNames": [
                "[variables('storageEndpoint')]"
              ],
              "isEnabled": true
            }
          ],
          "fallbackRoute": {
            "name": "$fallback",
            "source": "DeviceMessages",
            "condition": "true",
            "endpointNames": [
              "events"
            ],
            "isEnabled": true
          }
        },
        "messagingEndpoints": {
          "fileNotifications": {
            "lockDurationAsIso8601": "PT1M",
            "ttlAsIso8601": "PT1H",
            "maxDeliveryCount": 10
          }
        },
        "enableFileUploadNotifications": false,
        "cloudToDevice": {
          "maxDeliveryCount": 10,
          "defaultTtlAsIso8601": "PT1H",
          "feedback": {
            "lockDurationAsIso8601": "PT1M",
            "ttlAsIso8601": "PT1H",
            "maxDeliveryCount": 10
          }
        }
      },
      "dependsOn": [
        "[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName'))]"
      ]
    }
  ],
  "outputs": {
    "name": {
      "type": "string",
      "value": "[variables('iotHubName')]"
    },
    "resourceId": {
      "type": "string",
      "value": "[resourceId('Microsoft.Devices/IotHubs', variables('iotHubName'))]"
    },
    "resourceGroupName": {
      "type": "string",
      "value": "[resourceGroup().name]"
    },
    "location": {
      "type": "string",
      "value": "[parameters('location')]"
    }
  }
}

テンプレートのデプロイ

このセクションでは、ARM テンプレートをデプロイする手順について説明します。

  • ARM テンプレートをデプロイしてリソースを作成します。

    Deploy To Azure

device-to-cloud メッセージを送信する

このセクションでは、新しい IoT ハブにデバイスを登録し、そのデバイスから IoT Hub にメッセージを送信します。 IoT ハブでテンプレートによって構成されたルートは、メッセージ プロパティ level=storage が含まれている場合にのみメッセージをストレージに送信します。 このルーティング条件が期待どおりに動作することをテストするために、そのプロパティを含むいくつかのメッセージと含まないいくつかのメッセージを送信します。

ヒント

このクイック スタートでは、便宜上 Azure CLI のシミュレートされたデバイスを使用します。 ルーティングに関するメッセージ プロパティを使用してデバイスからクラウドへのメッセージを送信するコード例については、Azure IoT SDK for .NET の HubRoutingSample を参照してください。

  1. テンプレートによって自動的に作成された IoT ハブの名前を取得します。

    前のセクションで既定のコマンドを使用した場合は、ContosoResourceGrp リソース グループにリソースが作成されています。 別のリソース グループを使用した場合は、一致するように次のコマンドを更新します。

    az iot hub list --resource-group ContosoResourceGrp --output table
    
  2. 出力から IoT ハブの名前をコピーします。 contosoHub{randomidentifier} のように書式設定する必要があります

  3. デバイスをハブに追加します。

    az iot hub device-identity create --device-id contosoDevice --hub-name {YourIoTHubName} 
    
  4. デバイスをシミュレートし、デバイスからクラウドへのメッセージを送信します。

    --data パラメーターを使用すると、メッセージ本文を設定できます。

    az iot device simulate \
      --device-id contosoDevice \
      --hub-name {YourIoTHubName} \
      --data "This message won't be routed."
    

    シミュレーターによって 100 個のメッセージが送信された後、シミュレーターは切断されます。 このクイック スタートの目的上は、100 件すべてを待つ必要はありません。

    ヒント

    Azure CLI では、メッセージの送信時にメッセージは出力されません。 ハブに到着したメッセージを監視する必要がある場合は、Visual Studio Code 用の Azure IoT Hub 拡張機能をインストールし、それを使用して組み込みのエンドポイントを監視できます。

  5. ストレージにルーティングされるデバイスからクラウドへのメッセージを送信します。

    --properties パラメーターを使用すると、メッセージ、アプリケーション、またはシステムのプロパティを既定のメッセージに追加できます。 このクイック スタートでは、IoT ハブ内のルートが、メッセージ プロパティ level=storage を含むメッセージを探しています。

    az iot device simulate \
      --device-id contosoDevice \
      --hub-name {YourIoTHubName} \
      --properties level=storage \
      --data "This message will be routed to storage."
    

デプロイされているリソースを確認する

  1. Azure portal にサインインして、リソース グループを選択し、ストレージ アカウントを選択します。

  2. ストレージ アカウントをドリルダウンしてファイルを見つけます。

    Look at the storage account files

  3. いずれかのファイルを選択して [ダウンロード] を選択し、後で見つけやすい場所にそのファイルをダウンロードします。 このファイルには、数値の名前 (例: 47) が付けられています。 末尾に " .txt" を追加し、ファイルをダブルクリックして開きます。

  4. 開いたファイルの各行はそれぞれ異なるメッセージを表しており、また、各メッセージの本文は暗号化されています。 メッセージの本文に対してクエリを実行するためには、そのようになっている必要があります。

    View the sent messages

    Note

    これらのメッセージは UTF-32 および Base64 でエンコードされています。 メッセージを復元して ASCII として読み取るためには、Base64 と UTF-32 からデコードする必要があります。 興味がある方は、ルーティングのチュートリアルで説明されている ReadOneRowFromFile メソッドを使用して、これらのメッセージ ファイルのうちから 1 つを読み取り、ASCII にデコードしてみてください。 ReadOneRowFromFile は、このクイックスタートで解凍した IoT C# SDK リポジトリにあります。 このフォルダーの最上位を起点とするパスは、./iothub/device/samples/getting started/RoutingTutorial/SimulatedDevice/Program.cs です。ブール値 readTheFile を true に設定し、ディスク上のファイルへのパスをハードコーディングしてください。これにより、ファイルの先頭行が開かれて変換されます。

このクイックスタートでは、IoT ハブとストレージ アカウントを作成する ARM テンプレートをデプロイし、そのハブにメッセージを送信するプログラムを実行しました。 メッセージは、メッセージのプロパティに基づいてルーティングされ、表示できるストレージ アカウントに格納されます。

リソースをクリーンアップする

このクイックスタートで追加したリソースを削除するために、Azure portal にサインインします。 [リソース グループ] を選択し、このクイックスタートに使用したリソース グループを見つけてください。 リソース グループを選択し、 [削除] を選択します。 グループが削除されると、グループ内のすべてのリソースも削除されます。

次のステップ