次の方法で共有


チュートリアル: IoT Edge モジュールとしてAzure Functionsをデプロイする

対象:IoT Edge 1.5 チェックマーク IoT Edge 1.5

重要

IoT Edge 1.5 LTS は、サポートされているリリースです。 IoT Edge 1.4 LTS は 2024 年 11 月 12 日に終了しました。 以前のリリースを使用している場合は、「Update IoT Edgeを参照してください。

Azure Functionsを使用して、ビジネス ロジックを実行するコードをAzure IoT Edge デバイスに直接デプロイします。 このチュートリアルでは、シミュレートされたIoT Edge デバイス上のセンサー データをフィルター処理するAzure関数を作成してデプロイする方法について説明します。 クイックスタートで作成したシミュレートされたIoT Edgeデバイスを使用します。 このチュートリアルでは、以下の内容を学習します。

  • Visual Studio Codeを使用してAzure関数を作成する
  • Visual Studio Codeと Docker を使用して Docker イメージを作成し、コンテナー レジストリに発行する
  • コンテナー レジストリから IoT Edge デバイスにモジュールをデプロイする
  • フィルター処理されたデータを表示する

関数モジュールをステージングおよびデプロイする方法を含む、関数アーキテクチャを示す図。

このチュートリアルで作成するAzure関数は、デバイスによって生成された温度データをフィルター処理します。 この関数は、温度が指定されたしきい値を超えている場合にのみ、アップストリームからAzure IoT Hubにメッセージを送信します。

Azure アカウントがない場合は、開始する前に free アカウントを作成します。

前提条件

このチュートリアルを開始する前に、チュートリアルに従って Linux コンテナー開発用の開発環境 (develop Azure IoT Edge モジュールを Visual Studio Code を使用してセットアップします。 完了すると、次の前提条件が満たされます。

Azure Functionsを使用してIoT Edge モジュールを開発するには、開発用コンピューターに次の追加の前提条件をインストールします。

関数プロジェクトを作成する

Visual Studio CodeのAzure IoT Edgeでは、管理機能とコード テンプレートが提供されます。 このセクションでは、Visual Studio Codeを使用して、Azure関数を使用してIoT Edge ソリューションを作成します。

新しいプロジェクトを作成する

カスタマイズ可能な C# 関数ソリューション テンプレートを作成するには、次の手順に従います。

  1. 開発用コンピューターでVisual Studio Codeを開きます。

  2. Visual Studio Codeコマンド パレットを開くには、 View > コマンド パレットを選択します。

  3. コマンド パレットで、コマンド Azure IoT Edge: 新しいIoT Edge ソリューションを追加して実行します。 コマンド パレットに表示されるこれらのメッセージに従って、ソリューションを作成します。

    • フォルダーを選択します。ソリューション ファイルを作成するためのVisual Studio Codeの開発用コンピューター上の場所を選択します。
    • ソリューション名を指定します。 FunctionSolution などのソリューションのわかりやすい名前を追加するか、既定値をそのまま使用します。
    • モジュール テンプレートを選択します。Azure Functions - C# を選択します。
    • モジュール名を指定します。モジュール に CSharpFunction という名前を付けます
    • モジュールの Docker イメージ リポジトリを指定します。イメージ リポジトリには、コンテナー レジストリの名前とコンテナー イメージの名前が含まれます。 Portal では、前の手順で指定したコンテナー イメージがあらかじめ入力されています。 localhost:5000 を、Azure コンテナー レジストリの Login server 値に置き換えます。 Login サーバーは、Azure ポータルのコンテナー レジストリの Overview ページから取得できます。 最後の文字列は <registry name>.azurecr.io/csharpfunctionのようになります。

    Visual Studio Code に Docker イメージ リポジトリ名を追加する場所を示すスクリーンショット

レジストリ資格情報を追加する

ソリューション内の環境ファイルは、コンテナー レジストリの資格情報を格納し、IoT Edge ランタイムと共有します。 ランタイムは、プライベート イメージをIoT Edge デバイスにプルするために、これらの資格情報を必要とします。

Visual Studio CodeのIoT Edge拡張機能は、コンテナー レジストリの資格情報をAzureからプルし、環境ファイルに設定しようとします。 資格情報が既にファイルに含まれているかどうかを確認します。 含まれていない場合は、今すぐ追加してください。

  1. Visual Studio Code エクスプローラーで、.env ファイルを開きます。
  2. Azure コンテナー レジストリからコピーした username および password 値でフィールドを更新します。 もう一度見つけるには、Azureでコンテナー レジストリに移動し、Settings > アクセス キー ページを確認します。
  3. このファイルを保存します。

注意

このチュートリアルでは、Azure Container Registryの管理者ログイン資格情報を使用します。これは、開発とテストのシナリオに便利です。 運用環境では、サービス プリンシパルなどの最小特権認証オプションを使用します。 詳細については、[コンテナー レジストリへのアクセスを管理する] を参照してください。

ターゲット アーキテクチャを AMD64 に設定する

IoT EdgeのAzure Functions モジュールは、Linux AMD64 ベースのコンテナーでのみサポートされます。 Visual Studio Codeの既定のターゲット アーキテクチャは Linux AMD64 ですが、ここでは Linux AMD64 に明示的に設定できます。

  1. コマンド パレットを開き、Azure IoT Edge: Edge ソリューションの既定のターゲット プラットフォームの設定を検索します。
  2. コマンド パレットで、オプションの一覧から AMD64 ターゲット アーキテクチャを選択します。

カスタム コードでモジュールを更新する

CSharpFunction モジュールがエッジでメッセージを処理してからIoT Hubに転送するようにコードを追加します。

  1. Visual Studio Code エクスプローラーで、modules > CSharpFunction > CSharpFunction.cs を開きます。

  2. CSharpFunction.cs ファイルの内容を次のコードに置き換えます。 このコードは、環境温度とマシン温度に関するテレメトリを受信し、マシンの温度が定義されたしきい値を超えている場合にのみ、メッセージをIoT Hubに転送します。

    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Text;
    using System.Threading.Tasks;
    using Microsoft.Azure.Devices.Client;
    using Microsoft.Azure.WebJobs;
    using Microsoft.Azure.WebJobs.Extensions.EdgeHub;
    using Microsoft.Azure.WebJobs.Host;
    using Microsoft.Extensions.Logging;
    using Newtonsoft.Json;
    
    namespace Functions.Samples
    {
        public static class CSharpFunction
        {
            [FunctionName("CSharpFunction")]
            public static async Task FilterMessageAndSendMessage(
                [EdgeHubTrigger("input1")] Message messageReceived,
                [EdgeHub(OutputName = "output1")] IAsyncCollector<Message> output,
                ILogger logger)
            {
                const int temperatureThreshold = 20;
                byte[] messageBytes = messageReceived.GetBytes();
                var messageString = System.Text.Encoding.UTF8.GetString(messageBytes);
    
                if (!string.IsNullOrEmpty(messageString))
                {
                    logger.LogInformation("Info: Received one non-empty message");
                    // Get the body of the message and deserialize it.
                    var messageBody = JsonConvert.DeserializeObject<MessageBody>(messageString);
    
                    if (messageBody != null && messageBody.machine.temperature > temperatureThreshold)
                    {
                        // Send the message to the output as the temperature value is greater than the threshold.
                        using (var filteredMessage = new Message(messageBytes))
                        {
                             // Copy the properties of the original message into the new Message object.
                             foreach (KeyValuePair<string, string> prop in messageReceived.Properties)
                             {filteredMessage.Properties.Add(prop.Key, prop.Value);}
                             // Add a new property to the message to indicate it is an alert.
                             filteredMessage.Properties.Add("MessageType", "Alert");
                             // Send the message.
                             await output.AddAsync(filteredMessage);
                             logger.LogInformation("Info: Received and transferred a message with temperature above the threshold");
                        }
                    }
                }
            }
        }
        //Define the expected schema for the body of incoming messages.
        class MessageBody
        {
            public Machine machine {get; set;}
            public Ambient ambient {get; set;}
            public string timeCreated {get; set;}
        }
        class Machine
        {
            public double temperature {get; set;}
            public double pressure {get; set;}
        }
        class Ambient
        {
            public double temperature {get; set;}
            public int humidity {get; set;}
        }
    }
    
  3. ファイルを保存します。

IoT Edge ソリューションをビルドしてプッシュする

前のセクションでは、IoT Edge ソリューションを作成し、CSharpFunction を変更して、報告されたマシンの温度が許容されるしきい値を下回るメッセージを除外しました。 次に、ソリューションをコンテナー イメージとしてビルドし、コンテナー レジストリにプッシュします。

  1. Visual Studio Code統合ターミナルを開きます。 [ ターミナル > 表示] を選択します。

  2. ターミナルで Docker にサインインします。 Azure コンテナー レジストリのユーザー名、パスワード、認証サーバーを使用します。 これらの値は、Azure ポータルのレジストリの Access キー セクションから取得します。

    docker login -u <ACR username> -p <ACR password> <ACR login server>
    

    --password-stdin の使用を推奨するセキュリティ警告が表示される場合があります。 このベスト プラクティスは、運用環境のシナリオを対象に推奨されていますが、それはこのチュートリアルの範囲外になります。 詳細については、 Docker ログイン リファレンスを参照してください。

  3. Visual Studio Code エクスプローラーで、deployment.template.json ファイルを右クリックし、 Build と Push IoT Edge Solution を選択します。

    ビルドおよびプッシュ コマンドでは、3 つの操作を開始します。 最初に、完全な配置マニフェストを含む config という名前の新しいフォルダーをソリューションに作成します。このフォルダーは、配置テンプレートとその他のソリューション ファイルからビルドされます。 次に、 docker build を実行して、ターゲット アーキテクチャに適した Dockerfile に基づいてコンテナー イメージをビルドします。 そして、docker push を実行して、イメージ リポジトリをコンテナー レジストリにプッシュします。

    このプロセスは初めて数分かかる場合がありますが、次にコマンドを実行すると高速になります。

コンテナー イメージの表示

Visual Studio Codeコンテナー イメージをコンテナー レジストリにプッシュすると、成功メッセージが表示されます。 操作を確認するには、レジストリ内のイメージを表示します。

  1. Azure ポータルで、Azure コンテナー レジストリに移動します。
  2. [サービス > リポジトリ] を選択します。
  3. 一覧に csharpfunction リポジトリが表示されます。 詳細を表示するには、このリポジトリを選択します。
  4. [ タグ ] セクションには、 0.0.1-amd64 タグが表示されます。 このタグには、ビルドしたイメージのバージョンとプラットフォームが表示されます。 CSharpFunction フォルダー内の module.json ファイルは、これらの値を設定します。

ソリューションの配置と実行

Azure ポータルを使用して、クイックスタートのように関数モジュールをIoT Edge デバイスにデプロイします。 Visual Studio Codeからモジュールをデプロイおよび監視することもできます。 次のセクションでは、前提条件に記載されている Azure IoT Edge および IoT Hub 用の Visual Studio Code 拡張機能を使用します。 まだインストールしていない場合は、拡張機能を今すぐインストールします。

  1. Visual Studio Code エクスプローラーの Azure IoT Hub セクションで、Devices を展開して IoT デバイスの一覧を表示します。

  2. IoT Edge デバイスの名前を右クリックし、 [単一デバイスの展開の作成を選択します。

  3. CSharpFunction を含むソリューション フォルダーに移動します。 config フォルダーを開き、deployment.amd64.json ファイルを選択して、 [Select Edge Deployment Manifest](Edge 展開マニフェストの選択) を選択します。

  4. デバイスの下で、[ モジュール ] を展開して、デプロイおよび実行中のモジュールの一覧を表示します。 [更新] ボタンを選択します。 SimulatedTemperatureSensor モジュール、$edgeAgent、および$edgeHubと共に実行されている新しい CSharpFunction を確認できます。

    新しいモジュールが表示されるまでに少し時間がかかる場合があります。 IoT Edge デバイスは、IoT Hubから新しい展開情報を取得し、新しいコンテナーを開始してから、状態をIoT Hubに報告します。

    Visual Studio Codeでデプロイされたモジュールを表示する方法を示すスクリーンショット

生成されたデータを表示する

コマンド パレットで Azure IoT Hub: 組み込みイベント エンドポイントの監視を開始 を実行して、デバイスから IoT ハブに到着したすべてのメッセージを表示します。 メッセージの監視を停止するには、コマンド パレットで Azure IoT Hub: 組み込みイベント エンドポイントの監視を停止を実行します。

ビューをフィルター処理し、特定のデバイスからのメッセージを表示するには、Visual Studio Code エクスプローラーの Azure IoT Hub > Devices セクションでデバイスを右クリックし、Start Monitoring Built-in Event Endpoint を選択します。

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

次の推奨記事に進む場合は、作成したリソースと構成を保持し、再利用します。 テスト デバイスと同じIoT Edge デバイスを使用し続けることもできます。

それ以外の場合は、課金されないように、この記事で作成したローカル構成とAzure リソースを削除します。

Azure リソースを削除する

Azureリソースとリソース グループの削除を元に戻すことはできません。 間違ったリソース グループやリソースをうっかり削除しないようにしてください。 保持するリソースがある既存のリソース グループ内にIoT Hubを作成した場合は、リソース グループではなく、IoT Hub リソース自体のみを削除します。

リソースを削除するには、次の手順に従います。

  1. Azure ポータルにサインインし、Resource グループ を選択します。
  2. IoT Edgeテスト リソースを含むリソース グループの名前を選択します。
  3. リソース グループに含まれているリソースの一覧を確認します。 それらすべてを削除する場合は、[ リソース グループの削除] を選択できます。 一部のみを削除する場合は、各リソースを選択して個別に削除します。

次のステップ

このチュートリアルでは、IoT Edge デバイスによって生成された生データをフィルター処理するコードを含む Azure Function モジュールを作成しました。

次のチュートリアルに進み、Azure IoT Edgeがエッジでデータをビジネス分析情報に変換するのに役立つその他の方法を学習します。

Azure Stream Analytics でフローティング ウィンドウを使用して平均を計算する