【Azure】Private LinkとマネージドIDを使用したIoT Hubの構築

#1. はじめに
###1.1 ご挨拶
初めまして、井村と申します。
プロジェクトでAzure IoT Hubを検証する機会がありました。
様々な記事を寄せ集めて、作成した環境になりますので備忘録として本記事を作成しました。

###1.2 対象読者
・Azure portalからAzureサービスを操作したことある
・Azure IoT Hubに興味がある

###1.3 成果物
Microsoft公式ドキュメントより[「Private Link とマネージド ID を使用した仮想ネットワークの IoT Hub サポート」](https://docs.microsoft.com/ja-jp/azure/iot-hub/virtual-network-support)
を参考にAzure IoT Hubおよびその他Azureサービスを構築します。セキュアな環境を作りたい方にオススメです。 

###1.4 本記事の流れ
いくつかの参考記事をベースにAzureサービスを作成します。
最後は簡単な動作検証を行います。
参考記事との差分やつまずきポイントを本記事で記載します。

###1.5 構築の流れ
 - Azure VMおよびAzure Bastionを構築
 - Azure VM上にアプリを作成(※Node.jsでIoTデバイスアプリを作成しますが、プログラミングが苦手な方でも大丈夫です。コピペです。)
 - Azure Blob Storageを構築
 - Azure IoT Hubを構築
 - 検証の実施(アプリ実行後、Azure IoT Hubを経由しAzure Blob Storageにファイルが格納されるまで)

#2. 参考記事
 - [Private Link とマネージド ID を使用した仮想ネットワークの IoT Hub サポート](https://docs.microsoft.com/ja-jp/azure/iot-hub/virtual-network-support)
 - [チュートリアル:Bastion を構成し、Windows VM に接続する](https://docs.microsoft.com/ja-jp/azure/bastion/tutorial-create-host-portal)
 - [Windows での NodeJS のインストール](https://docs.microsoft.com/ja-jp/windows/dev-environment/javascript/nodejs-on-windows)
 - [nvm-windows](https://github.com/coreybutler/nvm-windows/releases)
 - [演習 - デバイス アプリを作成して実行する](https://docs.microsoft.com/ja-jp/learn/modules/manage-azure-iot-hub-with-metrics-alerts/3-exercise-write-device-telemetry-code?pivots=vscode-node)
 - [Visual Studio Code(Down Load for Windows)](https://code.visualstudio.com/)
 - [クイック スタート:Azure portal を使用して BLOB をアップロード、ダウンロード、および一覧表示する](https://docs.microsoft.com/ja-jp/azure/storage/blobs/storage-quickstart-blobs-portal)
 - [Azure Portal を使用して IoT Hub を作成する](https://docs.microsoft.com/ja-jp/azure/iot-hub/iot-hub-create-through-portal)
 - [IoT Hub でのマネージド ID のサポート](https://docs.microsoft.com/ja-jp/azure/iot-hub/iot-hub-managed-identity)
 - [Azure Storage ファイアウォールおよび仮想ネットワークを構成する](https://docs.microsoft.com/ja-jp/azure/storage/common/storage-network-security?tabs=azure-portal)
 - [IoT ハブのパブリック ネットワーク アクセスの管理](https://docs.microsoft.com/ja-jp/azure/iot-hub/iot-hub-public-network-access)



#3. 構築_事前準備
参考記事を元に構築を進めます。IoT Hub以外を構築します。
###3.1 Azure VMおよびAzure Bastionを構築
[「チュートリアル:Bastion を構成し、Windows VM に接続する」](https://docs.microsoft.com/ja-jp/azure/bastion/tutorial-create-host-portal)を参照し、Azure VMおよびAzure Bastionを構築します。記事内の「VM のパブリック IP アドレスを削除する」の前まで進めます。
※サブネットはAzure VM用、Azure Bastion用、Azure PrivateEndpoint用で合計３つ作成します。以下は私の環境になります。

|![3_1_仮想ネットワーク.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1989465/d63ea20f-9e40-9e7e-1418-5f05dd6ce2b2.png)|
|:--|

###3.2 Azure VM上にアプリを作成
####3.2.1 nvm-windows ,node.js ,npm のインストール
リモートデスクトップ接続でAzure VMにログインします。[「Windows での NodeJS のインストール」](https://docs.microsoft.com/ja-jp/windows/dev-environment/javascript/nodejs-on-windows)を参照し、記事内の「11. npm --version を実行して...」まで進めます。
※私はローカル端末のブラウザ上で[「nvm-windows」](https://github.com/coreybutler/nvm-windows/releases)から「nvm-setup.zip」をダウンロードし、コピペでAzure VM上のデスクトップに配置しました。

####3.2.2 IoTデバイスアプリの構築
[「Visual Studio Code(Down Load for Windows)」](https://code.visualstudio.com/)からVSCodeをダウンロード後、Azure VMにインストールします。
[「演習 - デバイス アプリを作成して実行する」](https://docs.microsoft.com/ja-jp/learn/modules/manage-azure-iot-hub-with-metrics-alerts/3-exercise-write-device-telemetry-code?pivots=vscode-node)を参照し、「テレメトリを送信するためのコードを追加する」の「2.次のコードをコピーして貼り付けます。」まで進めます。

####3.2.3 Azure VMのパブリックIPアドレスの削除
[「チュートリアル:Bastion を構成し、Windows VM に接続する」](https://docs.microsoft.com/ja-jp/azure/bastion/tutorial-create-host-portal)を参照し、「VM のパブリック IP アドレスを削除する」を行います。

###3.3 Azure Blob Storageを構築
Azure portalにサインイン後、[「クイック スタート:Azure portal を使用して BLOB をアップロード、ダウンロード、および一覧表示する」](https://docs.microsoft.com/ja-jp/azure/storage/blobs/storage-quickstart-blobs-portal)を参照し、「コンテナーを作成する」の「6.[OK] を選択してコンテナーを作成します。」まで進めます。
※以下は私の環境になります。ストレージアカウント名「sttestiot」、コンテナー名「iot-test」です。

|![3_2_3_ストレージアカウント.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1989465/4f976ccd-c3fa-fe6d-d761-83f379d11290.png)|
|:--|

#4. 構築_IoT Hub構築
ここからメインのAzure IoT Hubを構築します。
###4.1 Azure IoT Hubを構築
[「Azure Portal を使用して IoT Hub を作成する」](https://docs.microsoft.com/ja-jp/azure/iot-hub/iot-hub-create-through-portal)を参照し、「IoT Hub の作成」の「9.[作成] を選択して...」まで進めてAzure IoT Hubを構築します。
※「ネットワーク」タブで「プライベートアクセス（推奨）」を選んで構築したら私の環境だと毎回構築失敗しました。。その為、「パブリックアクセス」で構築します。最後にネットワーク制限を行いますので問題ございません。
※「管理」タブの「価格とスケールティア」は「F1:Free レベル」で大丈夫です。

###4.2 マネージドIDおよびストレージアカウントへの適用
####4.2.1 Azure IoT HubのマネージドID設定
[「IoT Hub でのマネージド ID のサポート」](https://docs.microsoft.com/ja-jp/azure/iot-hub/iot-hub-managed-identity)を参照し、「Azure portal でシステム割り当てマネージド ID を追加および削除する」の「4.IoT ハブからシス...」まで進めます。
※以下は私の環境になります。Azure IoT Hub名「iothub-test-1234」です。

|![4_2_ID.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1989465/3f9951a7-a529-e857-7fa8-e976bb4c9cc9.png)|
|:--|

####4.2.2 Storage AccountのIAM設定
Azure IoT HubのマネージドIDを用いてStorage Accountへの接続設定を行います。
[「IoT Hub でのマネージド ID のサポート」](https://docs.microsoft.com/ja-jp/azure/iot-hub/iot-hub-managed-identity)を参照し、「マネージド ID を使用してメッセージ ルーティングを構成する」の「1.まず、Azure portal...」から「4.システム割り当て...」まで進めます。
※「3.ユーザー割り当ての場合」は今回は不要です。
※ロールは[ストレージ BLOB データ共同作成者]を選択します。
※以下は私の環境になります。

|![4_2_2_IAM.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1989465/0ccf8d55-4734-1ddd-a550-42561a6a8956.png)|
|:--|

####4.2.3 Storage Accountのネットワーク設定
[「Azure Storage ファイアウォールおよび仮想ネットワークを構成する」](https://docs.microsoft.com/ja-jp/azure/storage/common/storage-network-security?tabs=azure-portal)を参照し、「Azure リソース インスタンスからのアクセスを許可する (プレビュー)」および「例外を管理する」を行います。
※以下は私の環境になります。アドレス範囲にはクライアント端末のIPアドレスを追加しています。

|![4_2_3_Firewall.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1989465/aedfc13a-9869-a132-f224-c922a47f101c.png)|
|:--|

###4.3 Azure IoT Hubのルーティング設定
[「Azure Portal を使用して IoT Hub を作成する」](https://docs.microsoft.com/ja-jp/azure/iot-hub/iot-hub-create-through-portal)を参照し、「IoT Hub のメッセージ ルーティング」の「ルート」を行います。
※ルーティングクエリはそのままで大丈夫です。
※エンドポイントは「3.3 Azure Blob Storageを構築」で作成したコンテナーを選択します。
※「ストレージエンドポイントの追加」の「認証の種類」は「システム割り当て」を選択します。

###4.4 Azure IoT Hubのデバイス設定
[「Azure Storage ファイアウォールおよび仮想ネットワークを構成する」](https://docs.microsoft.com/ja-jp/azure/storage/common/storage-network-security?tabs=azure-portal)を参照し、「IoT ハブに新しいデバイスを登録する」を行います。

###4.5 Azure IoT Hubのネットワーク設定
####4.5.1 パブリックアクセスの無効化
[「IoT ハブのパブリック ネットワーク アクセスの管理」](https://docs.microsoft.com/ja-jp/azure/iot-hub/iot-hub-public-network-access)を参照し、「Azure portal を使用してパブリック ネットワーク アクセスを無効にする」の「5.[保存] を選択します。」まで進めます。

####4.5.2 プライベートアクセスの有効化
[「Private Link とマネージド ID を使用した仮想ネットワークの IoT Hub サポート」](https://docs.microsoft.com/ja-jp/azure/iot-hub/virtual-network-support)を参照し、「IoT Hub のイングレス用のプライベート エンドポイントを設定する」を行います。

#5. 検証の実施
最後の章になります。まずは簡単に流れを記載し、各記事を紹介します。
 - Azure BastionからAzure VMに接続します。
 - 「 app.js ファイル」を修正して、アプリを実行します。
 - Azure Storage Account上でファイルが作成されていることを確認します。

###5.1 Azure VMへの接続
Azure VMのパブリックIPアドレスを削除しているため、Azure VMはプライベートIPアドレスだけ付与されています。その為、Azure Bastionを用いてAzure VMへサインインします。
[「チュートリアル:Bastion を構成し、Windows VM に接続する」](https://docs.microsoft.com/ja-jp/azure/bastion/tutorial-create-host-portal)を参照し、「VM への接続」を行います。

###5.2 IoTデバイスアプリの修正および実行
Azure VMとAzure IoT Hubを接続するために、以下作業を行います。
「4.4 Azure IoT Hubのデバイス設定」で行った「プライマリ接続文字列」を用意します。
[「演習 - デバイス アプリを作成して実行する」](https://docs.microsoft.com/ja-jp/learn/modules/manage-azure-iot-hub-with-metrics-alerts/3-exercise-write-device-telemetry-code?pivots=vscode-node)を参照し、「テレメトリを送信するためのコードを追加する」および「テレメトリを送信するためのコードをテストする」を行います。
IoTデバイスアプリのテレメトリがAzure IoT Hubへ送信されていることが確認できます。

###5.3 Azure Storage Account上で作成されたファイルの確認
最後にファイルの確認なります。「4.3 Azure IoT Hubのルーティング設定」の「エンドポイント」でファイル形式を以下のようにしました。IoT Hubアカウント名が第１階層となり、年月日順にフォルダ作成されます。
「{iothub}/{partition}/{YYYY}/{MM}/{DD}/{HH}/{mm}.Avro」
{iothub}←フォルダ第１階層
{partition}←フォルダ第２階層
{YYYY}←フォルダ第３階層
{MM}←フォルダ第４階層
{DD}←フォルダ第５階層
{HH}←フォルダ第６階層
{mm}←ファイル名

※以下は私の環境になります。

|![5_3_StorageAccount.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1989465/8c61e20e-b0b9-ec5f-7ea6-a9a2925c7592.png)|
|:--|

#6. さいごに
本記事を最後まで読んで頂きましてありがとうございます。初投稿になります。
Azureを初めて触れてから１年数ヶ月経過しました。日々参考書やサイト等でインプットしますが、やはりアウトプットが最強のインプットだと感じます。これからも定期的に記事投稿をしていこうと思います。
以上、よろしくお願いいたします。