Share via


クイック スタート: Terraform を使用して Azure IoT デバイス プロビジョニングサービス を作成する

このクイックスタートでは、Terraform を使用して、ハッシュされた割り当てポリシーを使用して、Azure IoT Hub Device Provisioning Service (DPS) リソースをデプロイする方法について説明します。

次の Terraform と Terraform プロバイダーのバージョンでテストされたクイックスタート:

Terraform を使用すると、クラウド インフラストラクチャの定義、プレビュー、およびデプロイを行うことができます。 Terraform を使用する際は、HCL 構文を使って構成ファイルを作成します。 HCL 構文では、Azure などのクラウド プロバイダーと、クラウド インフラストラクチャを構成する要素を指定できます。 構成ファイルを作成したら、"実行プラン" を作成します。これにより、インフラストラクチャの変更をデプロイ前にプレビューすることができます。 変更を確認したら、実行プランを適用してインフラストラクチャをデプロイします。

この記事では、次のことについて説明します。

  • ストレージ アカウントとストレージ コンテナーを作成する
  • Event Hubs、名前空間、認可規則を作成する
  • IoT Hub の作成
  • IoT Hub をストレージ アカウント エンドポイントと Event Hubs エンドポイントにリンクする
  • IoT Hub共有アクセス ポリシーを作成する
  • DPS リソースを作成する
  • DPS と IoT Hub をリンクする

前提条件

  • Azure サブスクリプション:Azure サブスクリプションをお持ちでない場合は、開始する前に 無料アカウント を作成してください。

Terraform コードを実装する

  1. サンプル Terraform コードをテストして実行するディレクトリを作成し、それを現在のディレクトリにします。

  2. providers.tf という名前のファイルを作成し、次のコードを挿入します。

    terraform {
      required_version = ">=1.0"
    
      required_providers {
        azurerm = {
          source  = "hashicorp/azurerm"
          version = ">=3.0"
        }
        random = {
          source  = "hashicorp/random"
          version = "~>3.0"
        }
      }
    }
    
    provider "azurerm" {
      features {}
    }
    
  3. main.tf という名前のファイルを作成し、次のコードを挿入します。

    resource "random_pet" "rg_name" {
      prefix = var.resource_group_name_prefix
    }
    
    resource "azurerm_resource_group" "rg" {
      location = var.resource_group_location
      name     = random_pet.rg_name.id
    }
    
    # Create storage account & container
    resource "random_string" "sa_name" {
      length  = 12
      special = false
      upper   = false
    }
    
    resource "azurerm_storage_account" "sa" {
      name                     = random_string.sa_name.id
      resource_group_name      = azurerm_resource_group.rg.name
      location                 = azurerm_resource_group.rg.location
      account_tier             = "Standard"
      account_replication_type = "LRS"
    }
    
    resource "azurerm_storage_container" "my_terraform_container" {
      name                  = "mycontainer"
      storage_account_name  = azurerm_storage_account.sa.name
      container_access_type = "private"
    }
    
    
    # Create an Event Hub & Authorization Rule
    resource "random_pet" "eventhub_namespace_name" {
      prefix = var.eventhub_namespace_name_prefix
    }
    
    resource "azurerm_eventhub_namespace" "namespace" {
      name                = random_pet.eventhub_namespace_name.id
      resource_group_name = azurerm_resource_group.rg.name
      location            = azurerm_resource_group.rg.location
      sku                 = "Basic"
    }
    
    resource "azurerm_eventhub" "my_terraform_eventhub" {
      name                = "myEventHub"
      resource_group_name = azurerm_resource_group.rg.name
      namespace_name      = azurerm_eventhub_namespace.namespace.name
      partition_count     = 2
      message_retention   = 1
    }
    
    resource "azurerm_eventhub_authorization_rule" "my_terraform_authorization_rule" {
      resource_group_name = azurerm_resource_group.rg.name
      namespace_name      = azurerm_eventhub_namespace.namespace.name
      eventhub_name       = azurerm_eventhub.my_terraform_eventhub.name
      name                = "acctest"
      send                = true
    }
    
    
    # Create an IoT Hub
    resource "random_pet" "iothub_name" {
      prefix = var.iothub_name_prefix
      length = 1
    }
    
    resource "azurerm_iothub" "iothub" {
      name                = random_pet.iothub_name.id
      resource_group_name = azurerm_resource_group.rg.name
      location            = azurerm_resource_group.rg.location
    
      sku {
        name     = "S1"
        capacity = 1
      }
    
      endpoint {
        type                       = "AzureIotHub.StorageContainer"
        connection_string          = azurerm_storage_account.sa.primary_blob_connection_string
        name                       = "export"
        batch_frequency_in_seconds = 60
        max_chunk_size_in_bytes    = 10485760
        container_name             = azurerm_storage_container.my_terraform_container.name
        encoding                   = "Avro"
        file_name_format           = "{iothub}/{partition}_{YYYY}_{MM}_{DD}_{HH}_{mm}"
      }
    
      endpoint {
        type              = "AzureIotHub.EventHub"
        connection_string = azurerm_eventhub_authorization_rule.my_terraform_authorization_rule.primary_connection_string
        name              = "export2"
      }
    
      route {
        name           = "export"
        source         = "DeviceMessages"
        condition      = "true"
        endpoint_names = ["export"]
        enabled        = true
      }
    
      route {
        name           = "export2"
        source         = "DeviceMessages"
        condition      = "true"
        endpoint_names = ["export2"]
        enabled        = true
      }
    
      enrichment {
        key            = "tenant"
        value          = "$twin.tags.Tenant"
        endpoint_names = ["export", "export2"]
      }
    
      cloud_to_device {
        max_delivery_count = 30
        default_ttl        = "PT1H"
        feedback {
          time_to_live       = "PT1H10M"
          max_delivery_count = 15
          lock_duration      = "PT30S"
        }
      }
    
      tags = {
        purpose = "testing"
      }
    }
    
    #Create IoT Hub Access Policy
    resource "azurerm_iothub_shared_access_policy" "hub_access_policy" {
      name                = "terraform-policy"
      resource_group_name = azurerm_resource_group.rg.name
      iothub_name         = azurerm_iothub.iothub.name
    
      registry_read   = true
      registry_write  = true
      service_connect = true
    }
    
    # Create IoT Hub DPS
    resource "random_pet" "dps_name" {
      prefix = var.dps_name_prefix
      length = 1
    }
    
    resource "azurerm_iothub_dps" "dps" {
      name                = random_pet.dps_name.id
      resource_group_name = azurerm_resource_group.rg.name
      location            = azurerm_resource_group.rg.location
      allocation_policy   = "Hashed"
    
      sku {
        name     = "S1"
        capacity = 1
      }
    
      linked_hub {
        connection_string       = azurerm_iothub_shared_access_policy.hub_access_policy.primary_connection_string
        location                = azurerm_resource_group.rg.location
        allocation_weight       = 150
        apply_allocation_policy = true
      }
    }
    
  4. variables.tf という名前のファイルを作成し、次のコードを挿入します。

    variable "resource_group_location" {
      default     = "eastus"
      description = "Location of the resource group."
    }
    
    variable "resource_group_name_prefix" {
      default     = "rg"
      description = "Prefix of the resource group name that's combined with a random ID so name is unique in your Azure subscription."
    }
    
    variable "eventhub_namespace_name_prefix" {
      default     = "namespace"
      description = "Prefix of the event hub namespace name that's combined with a random ID so name is unique in your Azure subscription."
    }
    
    variable "iothub_name_prefix" {
      default     = "iothub"
      description = "Prefix of the iot hub name that's combined with a random ID so name is unique in your Azure subscription."
    }
    
    variable "dps_name_prefix" {
      default     = "dps"
      description = "Prefix of the dps name that's combined with a random ID so name is unique in your Azure subscription."
    }
    
  5. outputs.tf という名前のファイルを作成し、次のコードを挿入します。

    output "azurerm_iothub_name" {
      value = azurerm_iothub.iothub.name
    }
    
    output "azurerm_iothub_dps_name" {
      value = azurerm_iothub_dps.dps.name
    }
    
    output "resource_group_name" {
      value = azurerm_resource_group.rg.name
    }
    

Terraform を初期化する

terraform init を実行して、Terraform のデプロイを初期化します。 このコマンドによって、Azure リソースを管理するために必要な Azure プロバイダーがダウンロードされます。

terraform init -upgrade

重要なポイント:

  • -upgrade パラメーターは、必要なプロバイダー プラグインを、構成のバージョン制約に準拠する最新バージョンにアップグレードします。

Terraform 実行プランを作成する

terraform plan を実行して、実行プランを作成します。

terraform plan -out main.tfplan

重要なポイント:

  • terraform plan コマンドは、実行プランを作成しますが、実行はしません。 代わりに、構成ファイルに指定された構成を作成するために必要なアクションを決定します。 このパターンを使用すると、実際のリソースに変更を加える前に、実行プランが自分の想定と一致しているかどうかを確認できます。
  • 省略可能な -out パラメーターを使用すると、プランの出力ファイルを指定できます。 -out パラメーターを使用すると、レビューしたプランが適用内容とまったく同じであることが確実になります。

Terraform 実行プランを適用する

terraform apply を実行して、クラウド インフラストラクチャに実行プランを適用します。

terraform apply main.tfplan

重要なポイント:

  • terraform apply コマンドの例は、以前に terraform plan -out main.tfplan が実行されたことを前提としています。
  • -out パラメーターに別のファイル名を指定した場合は、terraform apply の呼び出しで同じファイル名を使用します。
  • -out パラメーターを使用しなかった場合は、パラメーターを指定せずに terraform apply を呼び出します。

結果を確認する

az iot dps show を実行して、Azure DPS リソースを表示します。

az iot dps show \
   --name <azurerm_iothub_dps_name> \
   --resource-group <resource_group_name>

重要なポイント:

  • リソース グループと DPS インスタンスの名前がterraform apply出力に 表示されます。 また、terraform outputを実行して、これらの出力値を表示することもできます。

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

Terraform を使用して作成したリソースが不要になった場合は、次の手順を実行します。

  1. terraform plan を実行して、destroy フラグを指定します。

    terraform plan -destroy -out main.destroy.tfplan
    

    重要なポイント:

    • terraform plan コマンドは、実行プランを作成しますが、実行はしません。 代わりに、構成ファイルに指定された構成を作成するために必要なアクションを決定します。 このパターンを使用すると、実際のリソースに変更を加える前に、実行プランが自分の想定と一致しているかどうかを確認できます。
    • 省略可能な -out パラメーターを使用すると、プランの出力ファイルを指定できます。 -out パラメーターを使用すると、レビューしたプランが適用内容とまったく同じであることが確実になります。
  2. terraform apply を実行して、実行プランを適用します。

    terraform apply main.destroy.tfplan
    

Azure での Terraform のトラブルシューティング

Azure で Terraform を使用する場合の一般的な問題のトラブルシューティング

次のステップ

このクイックスタートでは、IoT ハブと Device Provisioning Service インスタンスをデプロイし、この 2 つのリソースをリンクしました。 この設定を使用してデバイスをプロビジョニングする方法については、デバイスの作成に関するクイックスタートに進んでください。