AWS IoT GreengrassにてLambdaの実行

GreengrassをインストーしたデバイスにLambdaをデプロイし、AWS IoT CoreとMQTT通信を実施します。以下の公式ドキュメントを参考に作業を進めます。

モジュール 3 (パート 1): AWS IoT Greengrass での Lambda 関数

環境

既にGreengrass環境は作成されているものとします。

デプロイ用Lambda関数の作成

MQTT通信をするためのLambda関数を作成します。

必要となるライブラリは AWS IoT Greengrass Core SDK となり、該当ライブラリ内にMQTT通信用の下記サンプルコードを用意してくれています。

greengrassHelloWorld.py

Serverless Frameworkにてデプロイできるようファイルを用意しているため、Serverless Framework経由でLambda関数を作成します。下記が該当Lambda作成用のServerless Frameworkのテンプレートとなります。

https://github.com/goodbyegangster/sls_template/tree/master/greengrassHelloWorld

デプロイします。

$ serverless install -u https://github.com/goodbyegangster/sls_template/tree/master/greengrassHelloWorld
$ cd greengrassHelloWorld
$ serverless deploy --aws-profile XXXX

デプロイされたLambda関数の確認。

$ serverless deploy list functions --aws-profile XXXX
Serverless: Listing functions and their last 5 versions:
Serverless: -------------
Serverless: greengrassHelloWorld: $LATEST, 1

作成したLambda関数に GG_HelloWorld という名前のAliasを付与します。

$ aws lambda create-alias `
--function-name greengrassHelloWorld `
--name GG_HelloWorld `
--function-version 1 `
--profile XXX

AWS CLI - create-alias

GreengrassグループにLambdaの登録

IoTコンソールにて、LambdaをデプロイしたいGreengrassグループを選択します。

f:id:goodbyegangster:20201029183643p:plain

左ペインより Lambda を選択し、 Add Lambda をクリックします。

f:id:goodbyegangster:20201029183647p:plain

Use existing Lambda をクリックします。

f:id:goodbyegangster:20201029183651p:plain

先程作成したLambda関数 greengrassHelloWorld を選択して Next をクリックします。

f:id:goodbyegangster:20201029183655p:plain

先程作成したAlias Alias:GG_HelloWorld を選択して Finish をクリックします。

f:id:goodbyegangster:20201029183700p:plain

GreengrassグループにLambdaが登録されますので、登録されたLambdaの右上の ... をクリックし Edit Configuration をクリックします。

f:id:goodbyegangster:20201029183706p:plain

以下の通りパラメーターを設定します。デフォルトから変更する点は TimeoutLambda lifecycle になります。

パラメーター 説明
Run as default IoT デバイス上で利用されるUIDとGIDを指定(defaultでは ggc_userggc_group )
Containerization default IoT デバイス上で関数実行時のコンテナモード利用有無を指定(defaultではコンテナモードを利用)
Memory limit 16 モリー割り当てサイズ
Timeout 25  関数のタイムアウト秒数
Lambda lifecycle Make this function long-lived and keep it running indefinitely Lambda関数の実行サイクルを on-demand(常に新規コンテナを起動)long-lived(コンテナをずっと保持) より指定
Read access to /sys directory Disable IoT デバイスの/sysフォルダへのアクセス権
Input payload data type JSON 関数へのinput payloadデータ形式jsonbinary より指定

各パラメーターの詳細な説明は、下記マニュアルにて。

Controlling execution of Greengrass Lambda functions by using group-specific configuration

Lambda Lifecycleについては、以下の資料では実際の動作を紹介しつつ詳細に説明してくれています。

モジュール 3 (パート 2): AWS IoT Greengrass でのLambda関数

作成したLambda関数を、実行したいGreengrassグループに登録できました。

Greengrassグループにサブスクリプションの登録

Greengrassグループに登録したLambdaを利用して、AWS IoT CoreへMQTT通信するためのサブスクリプションを設定します。AWS IoTにおけるサブスクリプションとは、以下説明されています。

AWS IoT Greengrass はサブスクリプションテーブルを使用して、Greengrass グループ内のデバイス、関数、およびコネクタ間、または AWS IoT Core あるいはローカルシャドウサービスと MQTT メッセージを交換する方法を定義します。各サブスクリプションは、どのメッセージが送信あるいは受信されるかについて、送信元、送信先、MQTT トピック (またはサブジェクト) を指定します。AWS IoT Greengrass では、対応するサブスクリプションが定義されている場合のみ、送信元から送信先にメッセージを送信することが許可されます。

MQTT メッセージングワークフローにおけるマネージドサブスクリプション

実際に設定してみることが、理解早かったです。対象Greengrassグループの左ペインより Subscription を選択し、 Add Subscription をクリックします。

f:id:goodbyegangster:20201029183710p:plain

下記画面が表示されます。

f:id:goodbyegangster:20201029183714p:plain

Sourceには作成したLambda関数の greengrassHelloWorld を、Targetには IoT Cloud を、下記の通り指定して Next をクリックします。

f:id:goodbyegangster:20201029183718p:plain

IoT Coreで利用されるTopic名を求められるので、 hello/world と入力して、 Next をクリックします。利用するTopic名は、Lambda内のコードにて定義されています。

f:id:goodbyegangster:20201029183723p:plain

その後、確認画面が表示されるので、 Finish とクリックするとサブスクリプション登録されます。

f:id:goodbyegangster:20201029183728p:plain

ログ出力設定

IoTデバイス上でのログ出力設定をしておきます。

対象のGreengrassグループの左ペインより Settings を選択し、Local logs configuration部分の Edit をクリックします。

表示される画面にて Add another log type を選択して、以下のログを追加します。

  • User Lambda
  • Greengrass System

下記みたくログ設定がされるはずです。ログレベルとDisk Space Limit(ログ利用最大サイズ)を指定できます。

f:id:goodbyegangster:20201029183733p:plain

Disk Space Limitを超えてログを記録しようとする場合、自動的なクリーンアップ処理が走るとのことです。詳細は下記マニュアルにて。

AWS IoT Greengrass のログ記録の設定

IoT デバイスへのデプロイ

これまで設定してきたLambda関数を、IoTデバイスにデプロイします。

まず、IoTデバイス上でGreengrassプロセスが起動していることを確認します。

$ ps aux | grep -E 'greengrass.*daemon'
root        7580  0.1  1.8 565184 18688 ?        Sl   08:54   0:00 /greengrass/ggc/packages/1.10.1/bin/daemon -core-dir /greengrass/ggc/packages/1.10.1 -greengrassdPid 7571
root        7613  0.0  0.0   9040   736 pts/0    S+   08:55   0:00 grep --color=auto -E greengrass.*daemon

実際のデプロイ方法。IoTコンソールにて、対象のGreengrassグループに移動、画面右上の Actions のプルダウンより Deploy を選択。

f:id:goodbyegangster:20201029183737p:plain

LambdaがIoTデイバイス上のGreengrassにデプロイされます。以下は結果画面。

f:id:goodbyegangster:20201029183740p:plain

確認

IoTデバイス上でLambdaが正常に動作しているかどうか確認します。IoTコンソール上では、MQTTメッセージブローカーの通信を容易にテストできるよう、Publish/Subscribe処理用のテストページが用意されています。

IoTコンソール上のテストページより、下記の通りのSubscribe設定を行い Subscribe to topic をクリックします。

f:id:goodbyegangster:20201029183745p:plain

正しく設定できている場合であれば、IoTデバイス上のGreengrassコンテナで起動したLambda関数では、数秒毎にMQTT通信をPublishしているはずですので、その通信を受け取ることができます。以下の様に、受け取ったデータは画面上に表示されます。

f:id:goodbyegangster:20201029183752p:plain

仮に正常に動作していなかった場合、IoTデバイス上のGreengrass系ログを確認することになります。以下がGreengrassで出力されているログたちです。★印を付けているログを確認する感じです。

/greengrass/
└── ggc
    └── var
        └── log
            ├── crash.log
            ├── system
            │   ├── GGCloudSpooler.log
            │   ├── GGConnManager.log
            │   ├── GGDeviceCertificateManager.log
            │   ├── GGIPDetector.log
            │   ├── GGSecretManager.log
            │   ├── GGShadowService.log
            │   ├── GGShadowSyncManager.log
            │   ├── GGStreamManager.log
            │   ├── GGTES.log
            │   ├── localwatch
            │   │   └── localwatch.log
            │   └── runtime.log ・・・★
            └── user
                └── ap-northeast-1
                    └── 123456789012
                        └── greengrassHelloWorld.log ・・・★