次の方法で共有


チュートリアル: Azure Event Grid への双方向 MQTT ブリッジ

重要

Azure Arc によって実現されている Azure IoT Operations プレビューは、現在プレビュー段階です。 運用環境ではこのプレビュー ソフトウェアを使わないでください。

Azure IoT Operations の一般公開リリースが提供されたときには、新規インストールをデプロイすることが必要になります。 プレビュー インストールからのアップグレードはできません。

ベータ版、プレビュー版、または一般提供としてまだリリースされていない Azure の機能に適用される法律条項については、「Microsoft Azure プレビューの追加使用条件」を参照してください。

このチュートリアルでは、Azure IoT Operations MQTT ブローカーと Azure Event Grid の間に双方向 MQTT ブリッジを設定します。 チュートリアルを簡単にしておくため、Azure IoT Operations MQTT ブローカーと Azure Event Grid エンドポイントには既定の設定を使い、変換は適用しません。

前提条件

環境変数を設定する

Azure CLI を使ってサインインします。

az login

設定の残りの部分の環境変数を設定します。 <> の値を、選択した有効な値または名前に置き換えます。 新しい Azure Event Grid 名前空間とトピック空間は、指定した名前に基づいて Azure サブスクリプション内に作成されます。

# For this tutorial, the steps assume the IoT Operations cluster and the Event Grid
# are in the same subscription, resource group, and location.

# Name of the resource group of Azure Event Grid and IoT Operations cluster 
export RESOURCE_GROUP=<RESOURCE_GROUP_NAME>

# Azure region of Azure Event Grid and IoT Operations cluster
export LOCATION=<LOCATION>

# Name of the Azure Event Grid namespace
export EVENT_GRID_NAMESPACE=<EVENT_GRID_NAMESPACE>

# Name of the Arc-enabled IoT Operations cluster 
export CLUSTER_NAME=<CLUSTER_NAME>

# Subscription ID of Azure Event Grid and IoT Operations cluster
export SUBSCRIPTION_ID=<SUBSCRIPTION_ID>

MQTT ブローカーを有効にして Event Grid 名前空間を作成する

Azure CLI を使用して Event Grid 名前空間を作成します。 場所は、Azure IoT Operations のデプロイに使用した場所と同じである必要があります。

az eventgrid namespace create \
  --namespace-name $EVENT_GRID_NAMESPACE \
  --resource-group $RESOURCE_GROUP \
  --location $LOCATION \
  --topic-spaces-configuration "{state:Enabled,maximumClientSessionsPerAuthenticationName:3}"

topic-spaces-configuration を設定すると、このコマンドにより次のような名前空間が作成されます。

  • MQTT ブローカー が有効になっている
  • 認証名あたりのクライアント セッションの最大数が 3 である。

最大クライアント セッション オプションを使うと、Azure IoT Operations MQTT は複数のインスタンスを生成して、接続を維持できます。 詳細については、マルチセッションのサポートを参照してください。

トピック空間を作成する

Event Grid 名前空間で、トピック テンプレート telemetry/# を使用して tutorial という名前のトピック空間を作成します。

az eventgrid namespace topic-space create \
  --resource-group $RESOURCE_GROUP \
  --namespace-name $EVENT_GRID_NAMESPACE \
  --name tutorial \
  --topic-templates "telemetry/#"

トピック テンプレートで # ワイルドカードを使用すると、 telemetry トピック空間の下の任意のトピックに発行できます。 たとえば、telemetry/temperature または telemetry/humidity です。

Azure IoT Operations に Event Grid トピック空間へのアクセスを許可する

Azure CLI を使って、Azure IoT Operations Arc 拡張機能のプリンシパル ID を調べます。 このコマンドを実行すると、後で使用できるようにプリンシパル ID を変数に格納することができます。

export PRINCIPAL_ID=$(az k8s-extension list \
  --resource-group $RESOURCE_GROUP \
  --cluster-name $CLUSTER_NAME \
  --cluster-type connectedClusters \
  --query "[?extensionType=='microsoft.iotoperations'].identity.principalId | [0]" -o tsv)
echo $PRINCIPAL_ID

次の形式の GUID 値である出力値 identity.principalId を書き留めておきます。

d84481ae-9181-xxxx-xxxx-xxxxxxxxxxxx

次に、Azure CLI を使って、作成したトピック空間に対するパブリッシャーとサブスクライバーのロールを Azure IoT Operations MQTT に割り当てます。

パブリッシャー ロールを割り当てます。

az role assignment create \
  --assignee $PRINCIPAL_ID \
  --role "EventGrid TopicSpaces Publisher" \
  --scope /subscriptions/$SUBSCRIPTION_ID/resourceGroups/$RESOURCE_GROUP/providers/Microsoft.EventGrid/namespaces/$EVENT_GRID_NAMESPACE/topicSpaces/tutorial

サブスクライバー ロールを割り当てます。

az role assignment create \
  --assignee $PRINCIPAL_ID \
  --role "EventGrid TopicSpaces Subscriber" \
  --scope /subscriptions/$SUBSCRIPTION_ID/resourceGroups/$RESOURCE_GROUP/providers/Microsoft.EventGrid/namespaces/$EVENT_GRID_NAMESPACE/topicSpaces/tutorial

ヒント

スコープは、 az eventgrid namespace topic-space create を使用して前の手順で作成したトピック空間の id と一致し、コマンドの出力で見つけることができます。

Event Grid MQTT ブローカーのホスト名

Azure CLI を使用して Event Grid MQTT ブローカーのホスト名を取得します。

az eventgrid namespace show \
  --resource-group $RESOURCE_GROUP \
  --namespace-name $EVENT_GRID_NAMESPACE \
  --query topicSpacesConfiguration.hostname \
  -o tsv

topicSpacesConfiguration.hostname のようなホスト名値の出力値を書き留めておきます。

example.region-1.ts.eventgrid.azure.net

Azure IoT Operations MQTT ブローカーの既定のデータフロー エンドポイントを理解する

既定では、Azure IoT Operations は MQTT ブローカーと共に MQTT ブローカー データフロー エンドポイントをデプロイします。 MQTT ブローカー データフロー エンドポイントは、MQTT ブローカーへの接続に使われます。 既定の構成では、組み込みのサービス アカウント トークンが認証に使われます。 エンドポイントは default という名前で、Azure IoT Operations と同じ名前空間で使用できます。 エンドポイントは、次の手順で作成するデータフローのソースとして使われます。

既定の MQTT ブローカー データフロー エンドポイントについて詳しくは、Azure IoT Operations のローカル MQTT ブローカーの既定のエンドポイントに関する記事をご覧ください。

Azure Event Grid データフロー エンドポイントを作成する

Azure Event Grid のデータフロー エンドポイントを作成します。 このエンドポイントは、メッセージを Azure Event Grid に送信するデータフローの送信先です。 <EVENT_GRID_HOSTNAME> は、前のステップで取得した MQTT ホスト名に置き換えます。 ポート番号 8883 を含めます。

Azure Event Grid のデータフローとデータフロー エンドポイントは、Azure リソース プロバイダー (RP) の実装があるため、標準の Azure リソースとしてデプロイできます。 「MQTT ブリッジ データフロー チュートリアル用の Bicep ファイル」から入手できるこの Bicep テンプレート ファイルでは、必要なデータフローとデータフロー エンドポイントがデプロイされます。

ファイルをローカル環境にダウンロードし、customLocationNameaioInstanceNameeventGridHostName の値をご自分の値に置き換えてください。

param customLocationName string = '<CUSTOM_LOCATION_NAME>'
param aioInstanceName string = '<AIO_INSTANCE_NAME>'
param eventGridHostName string = '<EVENT_GRID_HOSTNAME>:8883'

resource customLocation 'Microsoft.ExtendedLocation/customLocations@2021-08-31-preview' existing = {
  name: customLocationName
}

resource aioInstance 'Microsoft.IoTOperations/instances@2024-09-15-preview' existing = {
  name: aioInstanceName
}
resource remoteMqttBrokerDataflowEndpoint 'Microsoft.IoTOperations/instances/dataflowEndpoints@2024-09-15-preview' = {
  parent: aioInstance
  name: 'eventgrid'
  extendedLocation: {
    name: customLocation.id
    type: 'CustomLocation'
  }
  properties: {
    endpointType: 'Mqtt'
    mqttSettings: {
      host: eventGridHostName
      authentication: {
        method: 'SystemAssignedManagedIdentity'
        systemAssignedManagedIdentitySettings: {}
      }
      tls: {
        mode: 'Enabled'
      }
    }
  }
}

次に、ターミナルで次のコマンドを実行します。 <FILE> は、ダウンロードした Bicep ファイルの名前に置き換えます。

az deployment group create --resource-group <RESOURCE_GROUP> --template-file <FILE>.bicep

ここでは、認証方法は SystemAssignedManagedIdentity に設定され、Azure IoT Operations 拡張機能のマネージド ID を使って Event Grid MQTT ブローカーでの認証が行われます。 Azure IoT Operations 拡張機能には Event Grid トピック空間へのパブリッシュとサブスクライブに必要なアクセス許可が Azure RBAC ロールを通じて構成されているため、この設定は機能します。 構成にユーザー名やパスワードなどのシークレットが必要ないことに注意してください。

Event Grid MQTT ブローカーには TLS が必要であるため、tls の設定が有効になっています。 Event Grid MQTT ブローカーは広く信頼されている証明機関を使うため、信頼できる CA 証明書を提供する必要はありません。

データフローを作成する

Azure IoT Operations MQTT ブローカー エンドポイントを送信元とし、Azure Event Grid エンドポイントを送信先とするもの、およびその逆のものの、2 つのデータフローを作成します。 変換を構成する必要はありません。

param customLocationName string = '<CUSTOM_LOCATION_NAME>'
param aioInstanceName string = '<AIO_INSTANCE_NAME>'

resource customLocation 'Microsoft.ExtendedLocation/customLocations@2021-08-31-preview' existing = {
  name: customLocationName
}
resource aioInstance 'Microsoft.IoTOperations/instances@2024-09-15-preview' existing = {
  name: aioInstanceName
}
resource defaultDataflowProfile 'Microsoft.IoTOperations/instances/dataflowProfiles@2024-09-15-preview' existing = {
  parent: aioInstance
  name: 'default'
}
resource dataflow_1 'Microsoft.IoTOperations/instances/dataflowProfiles/dataflows@2024-09-15-preview' = {
  parent: defaultDataflowProfile
  name: 'local-to-remote'
  extendedLocation: {
    name: customLocation.id
    type: 'CustomLocation'
  }
  properties: {
    mode: 'Enabled'
    operations: [
      {
        operationType: 'Source'
        sourceSettings: {
          endpointRef: 'default'
          dataSources: array('tutorial/local')
        }
      }
      {
        operationType: 'Destination'
        destinationSettings: {
          endpointRef: remoteMqttBrokerDataflowEndpoint.name
          dataDestination: 'telemetry/aio'
        }
      }
    ]
  }
} 
resource dataflow_2 'Microsoft.IoTOperations/instances/dataflowProfiles/dataflows@2024-09-15-preview' = {
  parent: defaultDataflowProfile
  name: 'remote-to-local'
  extendedLocation: {
    name: customLocation.id
    type: 'CustomLocation'
  }
  properties: {
    mode: 'Enabled'
    operations: [
      {
        operationType: 'Source'
        sourceSettings: {
          endpointRef: remoteMqttBrokerDataflowEndpoint.name
          dataSources: array('telemetry/#')
        }
      }
      {
        operationType: 'Destination'
        destinationSettings: {
          endpointRef: 'default'
          dataDestination: 'tutorial/cloud'
        }
      }
    ]
  }
} 

データフロー エンドポイントと同様に、ターミナルで次のコマンドを実行します。

az deployment group create --resource-group <RESOURCE_GROUP> --template-file <FILE>.bicep

全体として、2 つのデータフローによって MQTT ブリッジが形成され、次のようになります。

  • Event Grid MQTT ブローカーをリモート ブローカーとして使用する
  • ローカル ブローカーとしてローカル Azure IoT Operations MQTT ブローカーを使用する
  • リモート ブローカーとローカル ブローカーの両方に TLS を使用する
  • リモート ブローカーへの認証にシステム割り当てマネージド ID を使用する
  • ローカル ブローカーへの認証に Kubernetes サービス アカウントを使用する
  • トピック マップを使用して、tutorial/local トピックをリモート ブローカーの telemetry/aio トピックにマップする
  • トピック マップを使用して、リモート ブローカーの telemetry/# トピックをローカル ブローカーの tutorial/cloud トピックにマップする

ローカルの Azure IoT Operations MQTT ブローカーで tutorial/local トピックにパブリッシュすると、メッセージはリモートの Event Grid MQTT ブローカーの telemetry/aio トピックにブリッジされます。 その後、メッセージはローカルの Azure IoT Operations MQTT ブローカーの tutorial/cloud トピックに逆にブリッジされます (telemetry/# ワイルドカード トピックがそれをキャプチャするため)。 同様に、リモートの Event Grid MQTT ブローカーで telemetry/aio トピックにパブリッシュすると、メッセージはローカルの Azure IoT Operations MQTT ブローカーの tutorial/cloud トピックにブリッジされます。

MQTT クライアントをデプロイする

MQTT ブリッジが機能していることを確認するには、Azure IoT Operations と同じ名前空間に MQTT クライアントをデプロイします。 次の client.yaml という名前の新しいファイルで、クライアントのデプロイを指定します。

現在、Bicep は MQTT クライアントのデプロイには適用されません。

サブスクライバーを開始する

kubectl exec を使用して mosquitto クライアント ポッドでシェルを立ち上げます。

kubectl exec --stdin --tty mqtt-client -n azure-iot-operations -- sh

シェル内で、mosquitto_sub を使って tutorial/# トピック空間の Azure IoT Operations ブローカーへのサブスクライバーを開始します。

mosquitto_sub --host aio-broker --port 18883 \
  -t "tutorial/#" \
  --debug --cafile /var/run/certs/ca.crt \
  -D CONNECT authentication-method 'K8S-SAT' \
  -D CONNECT authentication-data $(cat /var/run/secrets/tokens/broker-sat)

コマンドを実行したままにして、新しいターミナル ウィンドウを開きます。

ブリッジ経由で MQTT メッセージをクラウドに発行する

新しいターミナル ウィンドウ上で、mosquitto クライアント ポッドの別のシェルを立ち上げます。

kubectl exec --stdin --tty mqtt-client -n azure-iot-operations -- sh

シェル内で mosquitto を使用して、tutorial/local トピックに 5 つのメッセージを発行します。

mosquitto_pub -h aio-broker -p 18883 \
  -m "This message goes all the way to the cloud and back!" \
  -t "tutorial/local" \
  --repeat 5 --repeat-delay 1 -d \
  --debug --cafile /var/run/certs/ca.crt \
  -D CONNECT authentication-method 'K8S-SAT' \
  -D CONNECT authentication-data $(cat /var/run/secrets/tokens/broker-sat)

サブスクライバー内のメッセージを表示する

サブスクライバー シェルに、発行したメッセージが表示されます。

これにより、メッセージが tutorial/local トピックへのローカル Azure IoT Operations ブローカーにパブリッシュされ、Event Grid MQTT ブローカーにブリッジされた後、tutorial/cloud トピックでローカル Azure IoT Operations ブローカーにブリッジして戻されることがわかります。 その後、メッセージはサブスクライバーに配信されます。 この例では、ラウンド トリップ時間は約 80 ミリ秒です。

Event Grid メトリックを確認してメッセージ配信を確認する

Event Grid メトリックを確認して、メッセージが Event Grid MQTT ブローカーに配信されていることを確認することもできます。 Azure portal で、作成した Event Grid 名前空間に移動します。 [メトリック]>[MQTT: 正常に発行されたメッセージ] の下にあります。 ローカル Azure IoT Operations ブローカーにメッセージをパブリッシュすると、パブリッシュおよび配信されるメッセージの数が増えることがわかるはずです。

成功した MQTT メッセージを表示する Azure portal のメトリック ビューのスクリーンショット。

ヒント

データフロー、QoS、メッセージ ルートの構成は、CLI 拡張機能 az iot ops check --detail-level 2 で確認できます。

次のステップ

このチュートリアルでは、Azure Event Grid MQTT ブローカーを使用する双方向 MQTT ブリッジ用に Azure IoT Operations を構成する方法について説明しました。 次の手順としては、以下のシナリオをご確認ください。

  • MQTT クライアントを使用して Event Grid MQTT ブローカーに直接メッセージを発行するには、「Event Grid MQTT ブローカーに MQTT メッセージを発行する」を参照してください。 作成したトピック空間に対する発行元のアクセス許可バインドをクライアント に付与すると、telemetry/temperaturetelemetry/humidityなど、telemetry の下にある任意のトピックにメッセージを発行できます。 これらのメッセージはすべて、ローカル Azure IoT Operations ブローカーの tutorial/cloud トピックにブリッジされます。
  • Event Grid MQTT ブローカーのルーティング規則を設定するには、「Event Grid MQTT ブローカーのルーティング規則の構成」を参照してください。 ルーティング規則を使用すると、トピック名に基づいて異なるトピックにメッセージをルーティングしたり、メッセージの内容に基づいてメッセージをフィルター処理したりできます。