見出し画像

【Part4】ラズパイにLambda関数をデプロイする

AWSでエッジコンピューティング環境を作る 
Part4です。Greengrassの環境を構築できていない方はPart3からどうぞ

【Part3】AWSでエッジコンピューティング環境を作る(Lambda設定編)

ラズパイにGreengrass Coreを載せ、そこにデプロイするLambda関数の作成までできました。いよいよ実際にクラウド上から遠隔でデプロイしましょう(On The Air アップデートとか言うらしいです)。

Greengrassの各機能

しかし、まだ何ができるかしっくり来ていない方のほうが多いと思います。

AWS IoT Greengrass グループ

実際にエッジに反映させたいことは関数の他に、どういったリソースを使いたいか、AWSのなんのサービスにつなぐか、メッセージのやり取りはどうやって行うかなど、色々あるわけです。下図のように、これらをまとめて・セキュアに管理できるのがGreengrassの良いところです。

画像1

実は、Part2の設定で、すでにCoreの設定が完了しています。証明書関係をラズパイに転送したと思いますが、それがGreengrassとラズパイを対応付けるCoreの設定で、証明書を通じてセキュアな通信を保証しています。

今回は、この図の中でもLambdaとサブスクリプションを触ります。Greengrassで設定したものを、ラズパイにデプロイして"Hello World"のやり取りをするところまでやっていきましょう

Greengrass : Lambdaの設定

まず、Part2で作成した、AWS IoT Greengrassのグループを選択し、"Lambda"を選びます。

画像2

今回はPart3で作ったLambdaを使うので、"既存のLambda"を選択しましょう。

4既存のlambda

先程作ったLambda関数と、それに付随して作ったエイリアスを選択します。

画像5

画像4

これでGreengrass CoreにLambdaがひも付きます。

さて、紐付けたLambdaの状態では、Lambdaのライフサイクルはオンデマンドになっています。2つの違いは公式ページ(Greengrass Lambda 関数のライフサイクル設定)に詳しく書いていますが、

オンデマンド : 関数実行のたびにコンテナを作り、実行終了時に破棄される
無制限に稼働 : 一度作られた関数実行用のコンテナがずっと残る

両者の違いはカウンター(たとえば、AWS IoTにパブリッシュした数を数える)などを考えるとわかりやすくて、オンデマンドはコンテナが再作成された時点でカウンターが0にリセットされる一方で、無制限に稼働する場合は、エッジ端末が再起動するまではカウンターは増え続けるというイメージです。

画像6

Greengrass : Subscriptionの設定

GreengrassとLambdaの紐付けが終わったら、次はサブスクリプションの設定です。サブスクリプションとは、ざっくりいうと、AWS IoTや他のサービス、他のGreengrass Core端末と、メッセージのやり取りをする決まりみたいなものです。受け手と送り手のトピックが一致すると、送受信ができるようになります。

Greengrass groupのメニューからサブスクリプションを選択しましょう。

画像7

送り手(ソース)と、受け手(ターゲット)を決めます。今回はLambdaからメッセージを送るようになっているので、Lambda⇨AWS IoTです。

画像8

次に、トピックを決めます。

画像9

これでひとまずのサブスクリプションの定義は完了です。後で少し説明しますが、AWS IoT⇨Lambdaの方向にもメッセージを送る事はできるので、双方向の通信が可能です。

デプロイする

コレまでで、下記の設定が完了しました。

・Core (デバイス登録、証明書関連) 
・Lambda (関数関連)
・サブスクリプション (メッセージ関連)

いよいよ、デプロイです!デプロイ前に、ラズパイ上のgreengrassdがきちんと起動しているかどうかをチェックしておきましょう。じゃないと、永遠にデプロイ実行中で止まります。

下図のようにアクション⇨デプロイと押すと、今まで設定したものをラズパイ上に反映してくれるわけです。

画像10

デプロイの成功/失敗は下図のように履歴で表示されます

画像12

実際、関数が上手く実行され、メッセージが届いているかを、AWS IoTのテストサービス上で確認することができます。

画像11

この設定をして、下記のようなメッセージが5秒おきに届いていれば成功です。

画像13

これにて、無事デプロイメントが完了です!

【応用】双方向のコミュニケーションにしてみる

Lambdaのハンドラー内に実行関数を書き、上記のサブスクリプションに加え、AWS IoT⇨Lambdaへのサブスクリプションも記述すると、トピックを受けた時点でラズパイ内にデプロイした関数が発火、IoTにデータを送信できるようになります。

参考までに、双方向向けのLambda関数も貼っておきます。greengrassHelloWorld.pyをこれに置き換えて設定します。

#
# Copyright 2010-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
#

import greengrasssdk
import platform
import time
import json

# Creating a greengrass core sdk client
client = greengrasssdk.client('iot-data')

# Retrieving platform information to send from Greengrass Core
my_platform = platform.platform()

# Counter to keep track of invocations of the function_handler
my_counter = 0


def function_handler(event, context):
   global my_counter
   my_counter = my_counter + 1
   if not my_platform:
       client.publish(
           topic='hello/world/counter',
           payload=json.dumps({'message': 'Hello world! Sent from Greengrass Core.  Invocation Count: {}'.format(my_counter)})
       )
   else:
       client.publish(
           topic='hello/world/counter',
           payload=json.dumps({'message': 'Hello world! Sent from Greengrass Core running on platform: {}.  Invocation Count: {}'
                               .format(my_platform, my_counter)})
       )
   time.sleep(20)
   return

※実は先程設定した、オンデマンドと、長い存続期間によってAWS IoTで受けるcounterの値が変わってきます。コンテナのライフサイクルの関係でそうなっているので、試して違いを実感してみてください。

デバッグのコツ

さて、今回はコピペなので、基本的にうまくいくと思いますが、実際に関数を触っているとそういうわけにもいかず、エラーが出るとデバッグしなければいけません。AWS IoT上にデータが上手くあがっていなかったり、なにか異変がある場合、クラウド上のLambdaとは違うので、実行結果を見るにはラズパイ内に入って確認するしかありません。異変がある場合、まずデプロイされているか、そして正常に実行されているかどうかを確認しましょう

・デプロイされているかの確認。下記フォルダ内に実行するLambda関数の名前のログがある

$ sudo ls /greengrass/ggc/var/log/user/{region名}/{アカウントID}/

なければデプロイが上手くいっていない可能性が高い。あれば、実行時エラーの可能性が高い。実行時ログの確認は下記

$ sudo tail -f /greengrass/ggc/var/log/user/{region名}/{アカウントID}/Greengrass_HelloWorld.log

まとめ

今回までで、クラウドからエッジに関数をデプロイすることができました!これにより、できることがグッと広がってきます。

次回は、実際にGETしたデータを貯める方法についてまとめていきます。ではでは。

Part3. Lambda設定編
Part5. S3転送編 

サポートいただけると励みになります! よろしくおねがいします!!