Terraformを用いたAzure IoT Hubのメッセージルーティングの設定

# 初めに
Terraformを用いてIoTHubのメッセージルーティングを構築する一例を紹介します。

## IoT Hubとは？
IoT Hubは、Azureが提供するフルマネージドサービスで、大量のIoTデバイスからのメッセージを安全に収集し、それらを管理するためのソリューションです。これにより、デバイス間通信、デバイスの管理、セキュリティ対策などが可能となります。

https://learn.microsoft.com/ja-jp/azure/iot-hub/iot-concepts-and-iot-hub

## メッセージルーティングとは？
メッセージルーティングは、IoT Hubが受信したメッセージを特定のエンドポイントに自動的にルーティングする機能です。これにより、必要なデータを必要な場所に効率的に配信することが可能となります。

https://learn.microsoft.com/ja-jp/azure/iot-hub/iot-hub-devguide-messages-d2c

# ハマった点
結論から言うと、Storage Accountの認証に問題がありました。
Terraformの公式ドキュメントでは、認証に関する記載が特にありませんでした。

https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/iothub_route#argument-reference

```bash
resource "azurerm_resource_group" "example" {
  name     = "example-resources"
  location = "West Europe"
}

resource "azurerm_storage_account" "example" {
  name                     = "examplestorageaccount"
  resource_group_name      = azurerm_resource_group.example.name
  location                 = azurerm_resource_group.example.location
  account_tier             = "Standard"
  account_replication_type = "LRS"
}

resource "azurerm_storage_container" "example" {
  name                  = "example"
  storage_account_name  = azurerm_storage_account.example.name
  container_access_type = "private"
}

resource "azurerm_iothub" "example" {
  name                = "exampleIothub"
  resource_group_name = azurerm_resource_group.example.name
  location            = azurerm_resource_group.example.location

  sku {
    name     = "S1"
    capacity = "1"
  }

  tags = {
    purpose = "testing"
  }
}

resource "azurerm_iothub_endpoint_storage_container" "example" {
  resource_group_name = azurerm_resource_group.example.name
  iothub_id           = azurerm_iothub.example.id
  name                = "example"

  connection_string          = azurerm_storage_account.example.primary_blob_connection_string
  batch_frequency_in_seconds = 60
  max_chunk_size_in_bytes    = 10485760
  container_name             = azurerm_storage_container.example.name
  encoding                   = "Avro"
  file_name_format           = "{iothub}/{partition}_{YYYY}_{MM}_{DD}_{HH}_{mm}"
}

resource "azurerm_iothub_route" "example" {
  resource_group_name = azurerm_resource_group.example.name
  iothub_name         = azurerm_iothub.example.name
  name                = "example"

  source         = "DeviceMessages"
  condition      = "true"
  endpoint_names = [azurerm_iothub_endpoint_storage_container.example.name]
  enabled        = true
}
```

# 修正した点
IoT Hubのストレージコンテナエンドポイントに認証タイプとエンドポイントURIを追加しました。

・authentication_type: ストレージコンテナエンドポイントに対する認証タイプを設定します。下記では、"identityBased"が指定されています。

・endpoint_uri: ストレージコンテナエンドポイントのURIを設定します。下記では、指定したストレージアカウントの主要なblobエンドポイントが使用されています。

```bash
resource "azurerm_resource_group" "example" {
  name     = "example-resources"
  location = "West Europe"
}

resource "azurerm_storage_account" "example" {
  name                     = "examplestorageaccount"
  resource_group_name      = azurerm_resource_group.example.name
  location                 = azurerm_resource_group.example.location
  account_tier             = "Standard"
  account_replication_type = "LRS"
}

resource "azurerm_storage_container" "example" {
  name                  = "example"
  storage_account_name  = azurerm_storage_account.example.name
  container_access_type = "private"
}

resource "azurerm_iothub" "example" {
  name                = "exampleIothub"
  resource_group_name = azurerm_resource_group.example.name
  location            = azurerm_resource_group.example.location

  sku {
    name     = "S1"
    capacity = "1"
  }

  tags = {
    purpose = "testing"
  }
}
resource "azurerm_iothub_endpoint_storage_container" "example" {
  resource_group_name = azurerm_resource_group.example.name
  iothub_id           = azurerm_iothub.example.id
  name                = "example"

  connection_string          = azurerm_storage_account.example.primary_blob_connection_string
  batch_frequency_in_seconds = 60
  max_chunk_size_in_bytes    = 10485760
  container_name             = azurerm_storage_container.example.name
  encoding                   = "Avro"
  file_name_format           = "{iothub}/{partition}_{YYYY}_{MM}_{DD}_{HH}_{mm}"
  authentication_type        = "identityBased" #追加
  endpoint_uri               = azurerm_storage_account.example.primary_blob_endpoint #追加
}

resource "azurerm_iothub_route" "example" {
  resource_group_name = azurerm_resource_group.example.name
  iothub_name         = azurerm_iothub.example.name
  name                = "example"

  source         = "DeviceMessages"
  condition      = "true"
  endpoint_names = [azurerm_iothub_endpoint_storage_container.example.name]
  enabled        = true
}
```

# 補足
Azure portalを使用してメッセージルーティングを設定する場合、コンテナと認証の種類も設定する必要があります。このことから、Terraformを使用してインフラストラクチャを構築する際にも、これらのパラメータが必要であることが理解できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1620947/a71b987c-bee1-0b1c-e3fa-3d85073d2af1.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1620947/8115a6d7-353d-4b2e-e73e-ec04650e33fb.png)