AWS IoT Greengrass コアでの Lambda 関数の実行 - AWS IoT Greengrass

AWS IoT Greengrass Version 1 は機能更新を受信しなくなり、2023 年 6 月 30 日までセキュリティパッチとバグ修正のみ受信します。詳細については、「AWS IoT Greengrass V1 メンテナンスポリシー」を参照してください。重要な新機能新たなプラットフォームのサポートが追加された AWS IoT Greengrass Version 2 への移行を強くお勧めします。

AWS IoT Greengrass コアでの Lambda 関数の実行

AWS IoT Greengrass は、AWS Lambda で作成するユーザー定義コード用のコンテナ化された Lambda ランタイム環境を提供します。Lambda 関数は、コアのローカル Lambda ランタイムで実行される AWS IoT Greengrass コアにデプロイされます。ローカル Lambda 関数は、ローカルイベント、クラウドからのメッセージやその他のリソースによってトリガーされ、クライアントデバイスにローカルコンピューティングの機能性をもたらします。例えば、データをクラウドに送信する前にデバイスデータをフィルタリングするために、Greengrass Lambda 関数を使用できます。

Lambda 関数をコアにデプロイするには、この関数を Greengrass グループに追加し (既存の Lambda 関数を参照して行います)、この関数に対してグループ固有の設定を行い、グループをデプロイします。この関数が AWS のサービスにアクセスする場合には、必要なアクセス許可を Greengrass グループロールに追加する必要もあります。

Lambda 関数の実行方法 (アクセス許可、分離、メモリ制限など) を指定するパラメータを設定できます。詳細については、「グループ固有の設定による Greengrass Lambda 関数の実行の制御」を参照してください。

注記

これらの設定により、Docker コンテナで AWS IoT Greengrass を実行することもできます。詳細については、「Docker コンテナでの AWS IoT Greengrass の実行」を参照してください。

以下の表は、サポートされる AWS Lambda ランタイムおよび実行できる AWS IoT Greengrass Core ソフトウェアのバージョンを一覧表示しています。

言語あるいはプラットフォーム GGC のバージョン
Python 3.8 1.11
Python 3.7 1.9 以降
Python 2.7 * 1.0 以降
Java 8 1.1 以降
Node.js 12.x 1.10 以降
Node.js 8.10 * 1.9 以降
Node.js 6.10 * 1.1 以降
C、C++ 1.6 以降

* サポートされているバージョンの AWS IoT Greengrass では、これらのランタイムを使用する Lambda 関数を実行できますが、AWS Lambda で作成することはできません。デバイスのランタイムがその関数のために指定された AWS Lambda ランタイムと異なる場合、FunctionDefintionVersionFunctionRuntimeOverride を使用して独自のランタイムを選択できます。詳細については、「CreateFunctionDefinition」を参照してください。サポートされているランタイムの詳細については、「AWS Lambda Developer Guide」(AWS Lambda 開発者ガイド) の「Runtime support policy」(ランタイムサポートポリシー) を参照してください。

Greengrass Lambda 関数の SDK

AWS には、AWS IoT Greengrass コアで実行する Greengrass Lambda 関数で使用できる 3 つの SDK があります。これらの SDK は別々のパッケージに含まれているため、関数で同時に使用できます。Greengrass Lambda 関数で SDK を使用するには、AWS Lambda にアップロードする Lambda 関数デプロイパッケージに SDK を含めます。

AWS IoT Greengrass コア SDK

コアを操作するローカル Lambda 関数を有効にします。

  • AWS IoT Core で MQTT メッセージを交換します。

  • Greengrass グループのコネクタ、クライアントデバイス、その他の Lambda 関数で MQTT メッセージを交換します。

  • ローカル車道サービスとやり取りを行います。

  • その他のローカル Lambda 関数を呼び出します。

  • シークレットリソースにアクセスします。

  • ストリームマネージャーと対話します。

AWS IoT Greengrass では、GitHub の次の言語とプラットフォームで AWS IoT Greengrass Core SDK を提供します。

Lambda 関数デプロイパッケージに AWS IoT Greengrass Core SDK 依存関係を含めるには、次のようにします。

  1. Lambda 関数のランタイムに一致する AWS IoT Greengrass Core SDK パッケージの言語またはプラットフォームをダウンロードします。

  2. ダウンロードしたパッケージを解凍し、SDK を取得します。SDK は greengrasssdk フォルダです。

  3. 関数コードを含む Lambda 関数デプロイパッケージに greengrasssdk を含めます。これは、Lambda 関数を作成するときに AWS Lambda にアップロードするパッケージです。

 

StreamManagerClient

以下の AWS IoT Greengrass Core SDK は、ストリームマネージャーのオペレーションでのみ使用できます。

  • Java SDK (v1.4.0 以降)

  • Python SDK (v1.5.0 以降)

  • Node.js SDK (v1.6.0 以降)

AWS IoT Greengrass Core SDK for Python を使用してストリームマネージャーと対話するには、Python 3.7 以降をインストールする必要があります。また、Python Lambda 関数のデプロイパッケージに含める依存関係もインストールする必要があります。

  1. requirements.txt ファイルが格納されている SDK ディレクトリに移動します。このファイルには、依存関係が一覧表示されます。

  2. SDK の依存関係をインストールします。例えば、次の pip コマンドを実行して、現在のディレクトリにインストールします。

    pip install --target . -r requirements.txt

 

AWS IoT Greengrass Core SDK for Python をコアデバイス上にインストールする

Python Lambda 関数を実行している場合は、pip を使用して AWS IoT Greengrass Core SDK for Python をコアデバイスにインストールできます。そうすれば、Lambda 関数デプロイパッケージに SDK を含めずに関数をデプロイできます。詳細については、「greengrasssdk」を参照してください。

このサポートは、サイズ制限のあるコアを対象としています。可能な場合は、Lambda 関数デプロイパッケージに SDK を含めることをお勧めします。

 

AWS IoT Greengrass Machine Learning SDK

ローカル Lambda 関数は Greengrass コアに機械学習 (ML) リソースとしてデプロイされる ML モデルを使用できます。Lambda 関数は、この SDK を使用してコネクタとしてコアにデプロイされているローカル推論サービスを呼び出し、このサービスと対話できます。Lambda 関数と ML コネクタも、この SDK を使用してデータを ML フィードバックコネクタへ送信し、アップロードおよび発行を行うことができます。SDK を使用するコード例などの詳細については、「ML イメージ分類コネクタ」、「ML オブジェクト検出コネクタ」、および「ML フィードバックコネクタ」を参照してください。

次の表は、SDK バージョンのサポートされている言語またはプラットフォームと、実行できる AWS IoT Greengrass Core ソフトウェアのバージョンの一覧です。

SDK のバージョン 言語あるいはプラットフォーム 必要な GGC バージョン Changelog
1.1.0 Python 3.7 または 2.7 1.9.3 以降 Python 3.7 のサポートと新しい feedback クライアントを追加しました。
1.0.0 Python 2.7 1.7 以降 初回リリース。

ダウンロード情報については、「AWS IoT Greengrass ML SDK ソフトウェア」を参照してください。

AWS SDK

ローカル Lambda 関数を有効にして、AWS サービス (Amazon S3、DynamoDB、AWS IoT、AWS IoT Greengrass など) を直接呼び出すことができるようにします。AWS SDK を Greengrass Lambda 関数で使用するには、デプロイパッケージに含める必要があります。AWS SDK と AWS IoT Greengrass Core SDK を同じパッケージで使用する場合、Lambda 関数が正しい名前空間を使用していることを確認します。Greengrass Lambda 関数は、このコアがオフラインの場合にクラウドサービスと通信できません。

AWS SDK をご利用開始のためのリソースセンターからダウンロードします。

デプロイパッケージの作成の詳細については、入門チュートリアルの「Lambda 関数の作成とパッケージ化」あるいは「AWS Lambda デベロッパーガイド」の「デプロイパッケージの作成」を参照してください。

クラウドベースの Lambda 関数への移行

AWS IoT Greengrass Core SDK は、AWS SDK プログラミングモデルに従って、クラウド向けに開発された Lambda 関数を AWS IoT Greengrass コア上で実行する Lambda 関数に簡単に移植します。

例えば、次の Python Lambda 関数は、AWS SDK for Python (Boto3) を使用して、クラウドでトピック some/topic にメッセージを発行します。

import boto3 iot_client = boto3.client('iot-data') response = iot_client.publish( topic='some/topic', qos=0, payload='Some payload'.encode() )

AWS IoT Greengrass 向けの関数を移植するには、次の例に示すように、import ステートメントおよび client 初期化で boto3 モジュール名を greengrasssdk に変更します。

import greengrasssdk iot_client = greengrasssdk.client('iot-data') iot_client.publish( topic='some/topic', qos=0, payload='Some payload'.encode() )
注記

AWS IoT Greengrass コア SDK では、QoS = 0 のみの MQTT メッセージを送信できます。詳細については、「サービスのメッセージの品質」を参照してください。

また、プログラミングモデル間の類似性により、クラウド上で開発した Lambda 関数を最小限の労力で AWS IoT Greengrass に移行することが可能になります。Lambda 実行可能ファイルはクラウド上で実行されないため、デプロイ前に AWS SDK を使用してこれらをクラウド上で開発することはできません。

エイリアスまたはバージョンによる Lambda 関数のリファレンス

Greengrass グループは、Lambda 関数をエイリアス別 (推奨) またはバージョン別に参照できます。エイリアスを使用すると、関数コードを更新する時にサブスクリプションテーブルやグループ定義を変更する必要がないため、コード更新を簡単に管理できます。その代わりに、新しい関数バージョンにエイリアスを指定するだけで済みます。エイリアスは、グループデプロイ中にバージョン番号を解決します。エイリアスを使用すると、解決されたバージョンはデプロイ時にエイリアスが示すバージョンに更新されます。

AWS IoT Greengrass は、$LATEST バージョンの Lambda エイリアスをサポートしていません。$LATEST バージョンは、イミュータブルで発行された関数バージョンにバインドされず、いつでも変更できます。これは、AWS IoT Greengrass のバージョン普遍性の原則とは異なります。

Greengrass Lambda 関数がコード変更によって常に更新されるようにするための一般的な方法は、Greengrass グループとサブスクリプションで PRODUCTION という名前のエイリアスを使用することです。Lambda 関数の新しいバージョンを本稼働環境に移行すると、エイリアスが最新の安定バージョンを示し、グループを再デプロイします。また、このメソッドを使用して以前のバージョンにロールバックすることもできます。

Greengrass Lambda 関数のコミュニケーションフロー

Greengrass Lambda 関数は、AWS IoT Greengrass グループの他のメンバー、ローカルサービス、およびクラウドサービス (AWS サービスを含む) と通信するためのいくつかの方法をサポートします。

MQTT メッセージを使用した通信

Lambda 関数は、サブスクリプションによって制御される発行 - サブスクリプションパターンを使用して MQTT メッセージを送受信できます。

このコミュニケーションフローにより、Lambda 関数は以下のエンティティとメッセージを交換することができる。

  • グループ内のクライアントデバイス。

  • グループのコネクタ。

  • グループ内の他の Lambda 関数。

  • AWS IoT.

  • ローカルデバイスシャドウサービス。

サブスクリプションは、メッセージ送信元、メッセージターゲット、および送信元からターゲットへのメッセージのルーティングに使用されるトピック (または件名) を定義します。Lambda 関数に発行されるメッセージは、関数に登録されたハンドラに渡されます。サブスクリプションはより高度なセキュリティを可能にし、予測可能なやり取りを提供します。詳細については、「MQTT メッセージングワークフローにおけるマネージドサブスクリプション」を参照してください。

注記

Greengrass Lambda 関数は、クライアントデバイス、コネクタ、他の関数、およびコアがオフラインのときにローカルシャドウとメッセージを交換できますが、AWS IoT へのメッセージはキュー状態になります。詳細については、「クラウドターゲットの MQTT メッセージキュー」を参照してください。

他の通信フロー

  • コアデバイスでローカルデバイスおよびボリュームリソース、機械学習モデルとやり取りするため、Greengrass Lambda 関数はプラットフォーム固有のオペレーティングシステムインターフェイスを使用します。例えば、Python 関数で os モジュールの open メソッドを使用できます。関数がリソースにアクセスすることを許可するには、この関数がリソースに関連し、read-only あるいは read-write アクセス許可を付与されていることが必要です。AWS IoT Greengrass コアバージョンの利用可能性を含む詳細については、「Lambda 関数とコネクタを使用してローカルリソースにアクセスする」および「Lambda 関数コードから機械学習リソースにアクセスする」を参照してください。

    注記

    コンテナ化せずに Lambda 関数を実行する場合、アタッチされたローカルデバイスおよびボリュームリソースを使用することはできず、直接それらのリソースにアクセスする必要があります。

  • Lambda 関数は、AWS IoT Greengrass Core SDK の Lambda クライアントを使用して Greengrass グループ内の他の Lambda 関数を呼び出すことができます。

  • Lambda 関数は、AWS SDK を使用して AWS のサービスと通信できます。詳細については、「AWSSDK」をご参照ください。

  • Lambda 関数は、クラウドベースの Lambda 関数のように、サードパーティーのインターフェイスを使用して外部のクラウドサービスと通信できます。

注記

Greengrass Lambda 関数は、このコアがオフラインの場合に AWS または他のクラウドサービスと通信できません。

入力 MQTT トピック (または件名) の取得

AWS IoT Greengrass は、サブスクリプションを使用して、グループ内のクライアントデバイス、Lambda 関数、およびコネクタ間の MQTT メッセージの交換を制御し、さらに AWS IoT またはローカルシャドウサービスを使用します。サブスクリプションは、メッセージソース、メッセージターゲット、およびメッセージのルーティングに使用される MQTT トピックを定義します。ターゲットが Lambda 関数の場合、ソースがメッセージを発行すると、関数のハンドラが呼び出されます。詳細については、「MQTT メッセージを使用した通信」を参照してください。

次の例は、Lambda 関数がハンドラに渡された context から入力トピックを取得する方法を示しています。これを行うには、コンテキスト階層から subject キーにアクセスします (context.client_context.custom['subject'])。この例では、入力 JSON メッセージも解析してから、解析したトピックとメッセージを発行します。

注記

AWS IoT Greengrass API では、サブスクリプションのトピックは subject プロパティで表されます。

import greengrasssdk import logging client = greengrasssdk.client('iot-data') OUTPUT_TOPIC = 'test/topic_results' def get_input_topic(context): try: topic = context.client_context.custom['subject'] except Exception as e: logging.error('Topic could not be parsed. ' + repr(e)) return topic def get_input_message(event): try: message = event['test-key'] except Exception as e: logging.error('Message could not be parsed. ' + repr(e)) return message def function_handler(event, context): try: input_topic = get_input_topic(context) input_message = get_input_message(event) response = 'Invoked on topic "%s" with message "%s"' % (input_topic, input_message) logging.info(response) except Exception as e: logging.error(e) client.publish(topic=OUTPUT_TOPIC, payload=response) return

関数をテストするには、デフォルトの設定を使用してグループに追加します。次に、以下のサブスクリプションを追加し、グループをデプロイします。手順については、モジュール 3 (パート 1): AWS IoT Greengrass での Lambda 関数 を参照してください。

ソース ターゲット トピックのフィルター
IoT クラウド この関数 test/input_message
この関数 IoT クラウド test/topic_results

デプロイが完了したら、関数を呼び出します。

  1. AWS IoT コンソールで [MQTT test client] (MQTT テストクライアント) を開きます。

  2. [Subscribe to a topic] (トピックへのサブスクライブ) タブを選択して、test/topic_results をサブスクライブします。

  3. [Publish to a topic] (トピックへの発行) タブを選択して test/input_message トピックを発行します。この例では、JSON メッセージに test-key プロパティを含める必要があります。

    { "test-key": "Some string value" }

    成功した場合、関数は入力トピックとメッセージ文字列を test/topic_results トピックに発行します。

Greengrass Lambda 関数のライフサイクル設定

Greengrass Lambda 関数ライフサイクルは、関数が開始する時期とどのようにコンテナを作成して使用するかを定義します。また、ライフサイクルは関数ハンドラの外部にある変数および処理中のロジックが保持されるかを定義します。

AWS IoT Greengrass は、オンデマンド (デフォルト) または 長い存続期間のライフサイクルをサポートしています。

  • オンデマンド 関数は、呼び出されたときに起動し、実行するタスクが残っていないときに停止します。関数の呼び出しは、再使用できる既存のコンテナが利用可能な場合を除き、呼び出し処理に別のコンテナ (またはサンドボックス) を作成します。関数に送信されたデータは、いずれかのコンテナによってプルされる可能性があります。

    関数の複数の呼び出しは、同時に実行できます。

    関数ハンドラの外部で定義される変数や前処理ロジックは、新しいコンテナが作成されるときに保持されません。

  • 長い存続期間 (あるいは固定された) 関数は、AWS IoT Greengrass コアが単一のコンテナで開始して実行するときに、自動的に開始します。関数に送信されたすべてのデータは、同じコンテナによってプルされます。

    複数の呼び出しは、前の呼び出しが実行されるまでキュー状態になります。

    関数ハンドラの外部で定義される変数と事前処理ロジックは、このハンドラの毎回の呼び出しのために保持されます。

    長い存続期間の Lambda 関数は、初期の入力が全くない実行を開始する必要がある場合に便利です。例えば、存続期間が長い関数は、関数がデバイスデータの受信を開始するときに備えて、ML モデルをロードして処理を開始できます。

    注記

    長い存続期間の関数には、そのハンドラの呼び出しに関連付けられたタイムアウトがあることに注意してください。実行中のコードを無期限で実行する場合には、ハンドラ外でこれを開始する必要があります。関数の初期化の完了を妨害するようなハンドラ外のブロックコードがないことを確認します。

    これらの関数は、コアが停止する (グループのデプロイ中やデバイスの再起動中など) か、関数がエラー状態 (ハンドラのタイムアウト、キャッチされない例外、またはメモリ制限を超えたときなど) にならない限り実行されます。

コンテナの再利用に関する詳細は、AWS コンピューティングブログで「AWS Lambda のコンテナの再利用について」を参照してください。

Lambda 実行可能ファイル

この機能は AWS IoT Greengrass Core v1.6 以降で使用できます。

Lambda 実行可能ファイルは、コア環境でバイナリコードを実行するために使用できる Greengrass Lambda 関数の一種です。これによって、デバイス固有の機能を実行することができ、コンパイルされたコードの小さなフットプリントの利点を活用できます。Lambda 実行可能ファイルは、イベントによる呼び出し、他の関数の呼び出し、そしてローカルリソースにアクセスが可能です。

Lambda 実行可能ファイルはバイナリエンコードタイプのみ (JSON ではなく) をサポートします。それ以外では、Greengrass グループで管理し、他の Greengrass Lambda 関数のようにデプロイできます。ただし、Lambda 実行可能ファイルを作成するプロセスは、Python、Java、および Node.js の Lambda 関数とは異なります。

  • Lambda 実行可能ファイルの作成 (または管理) には AWS Lambda コンソールを使用できません。Lambda 実行可能ファイルの作成には、AWS Lambda API のみを使用できます。

  • 関数をコンパイルされた実行可能ファイルとして、AWS IoT Greengrass Core SDK for C が含まれている AWS Lambda にアップロードします。

  • 実行可能ファイル名を関数のハンドラとして指定します。

Lambda 実行可能ファイルでは、その関数コードに特定の呼び出しおよびプログラミングパターンが実装されている必要があります。例えば、main メソッドは次を満たす必要があります。

  • Greengrass 内部グローバル変数を初期化する gg_global_init 呼び出し。この関数は、スレッドの作成前、およびその他すべての AWS IoT Greengrass Core SDK 関数の呼び出し前に呼び出される必要があります。

  • Greengrass Lambda ランタイムに関数ハンドラを登録する gg_runtime_start の呼び出し。この関数は初期化中に呼び出す必要があります。この関数を呼び出すと、現在のスレッドはランタイムで使用されます。オプションの GG_RT_OPT_ASYNC パラメータはこの関数をブロックしませんが、代わりにランタイムに新規のスレッドを作成します。この関数は SIGTERM ハンドラを使用します。

次のスニペットは、GitHub の mainsimple_handler.c コード例の メソッドです。

int main() { gg_error err = GGE_SUCCESS; err = gg_global_init(0); if(err) { gg_log(GG_LOG_ERROR, "gg_global_init failed %d", err); goto cleanup; } gg_runtime_start(handler, 0); cleanup: return -1; }

実装の要件や制限などの詳細については、「AWS IoT Greengrass Core SDK for C」を参照してください。

Lambda 実行可能ファイルを作成する

SDK でコードをコンパイルしたら、AWS Lambda API を使用して Lambda 関数を作成し、コンパイルした実行可能ファイルをアップロードします。

注記

関数は、C89 互換性のあるコンパイラーでコンパイルする必要があります。

次の例では、create-function CLI コマンドを使用して、Lambda 実行可能ファイルを作成します。このコマンドは以下を指定します。

  • ハンドラの実行可能ファイルの名前。これは、コンパイルされた実行可能ファイルの正確な名前である必要があります。

  • コンパイルされた実行可能ファイルを含む .zip ファイルへのパス。

  • ランタイムの arn:aws:greengrass:::runtime/function/executable。これはすべて Lambda 実行可能ファイルのランタイムです。

注記

role では、任意の Lambda 実行ロールの ARN を指定できます。AWS IoT Greengrass はこのロールを使用しませんが、関数を作成するにはパラメータが必要です。Lambda 実行可能ファイルのロールの詳細については、「AWS Lambda デベロッパーガイド」の「AWS Lambda アクセス権限モデル」を参照してください。

aws lambda create-function \ --region aws-region \ --function-name function-name \ --handler executable-name \ --role role-arn \ --zip-file fileb://file-name.zip \ --runtime arn:aws:greengrass:::runtime/function/executable

次に、AWS Lambda API を使用してバージョンを発行し、エイリアスを作成します。

  • publish-version を使用して、関数バージョンを発行します。

    aws lambda publish-version \ --function-name function-name \ --region aws-region
  • create-alias を使用して、先ほど発行したバージョンを指すエイリアスを作成します。Greengrass グループ に Lambda 関数を追加する場合、この関数をエイリアスで参照することが推奨されます。

    aws lambda create-alias \ --function-name function-name \ --name alias-name \ --function-version version-number \ --region aws-region
注記

AWS Lambda コンソールには、Lambda 実行可能ファイルは表示されません。関数コードを更新するには、AWS Lambda API を使用する必要があります。

次に、Lambda 実行可能ファイルを Greengrass グループに追加し、このグループ固有の設定でバイナリ入力データを受け入れるように設定して、グループをデプロイします。これは AWS IoT Greengrass コンソールまたは AWS IoT Greengrass API を使用して実行できます。