[AWS IoT Greengrass V2] RaspberryPIでコンポーネントを作成してみました

2021.08.11

1 はじめに

IoT事業部の平内(SIN)です。

前回、AWS IoT Greengrass V2(以下、Greengrass V2)をRaspberryPiにセットアップしてみました。

今回は、このRasPi上で、入門チュートリアルをなぞりながら、初めてのコンポーネントを作成してみました。

2 レシピとアーティファクト

コンポーネントは、コアデバイス上で動作するソフトウェアモジュールですが、レシピアーティファクトで構成されています。

  • レシピ(設定パラメータ、依存関係、ライフサイクル、互換性を指定するメタ情報)
  • アーティファクト(複数のスクリプト、バイナリ、静的リソースなど)

アーティファクトのフォルダのパスは、「artifacts/componentName/componentVersion/」の形式となっていますが、実際に展開してみると、以下のようになります。

.
├── artifacts
│   └── com.example.HelloWorld
│       └── 1.0.0
│           └── hello_world.py
└── recipes
    └── com.example.HelloWorld-1.0.0.yaml

レシピとアーティファクトの内容は、以下です。

com.example.HelloWorld-1.0.0.yaml

---
RecipeFormatVersion: 2020-01-25
ComponentName: com.example.HelloWorld
ComponentVersion: '1.0.0'
ComponentDescription: My first AWS IoT Greengrass component.
ComponentPublisher: Amazon
ComponentConfiguration:
  DefaultConfiguration:
    Message: world
Manifests:
  - Platform:
      os: linux
    Lifecycle:
      Run: |
        python3 -u {artifacts:path}/hello_world.py '{configuration:/Message}'

hello_world.py

import sys
import datetime

message = "Hello, %s! Current time: %s." % (sys.argv[1], datetime.datetime.now())

# Print the message to stdout.
print(message)

# Append the message to the log file.
with open('/tmp/Greengrass_HelloWorld.log', 'a') as f:
    print(message, file=f)

3 Greengrass CLI

Greengrass CLIを使用して、ローカルでコンポーネントのデプロイ、削除等を行うことができます。
参考:Greengrass コマンドラインインターフェイス

(1) デプロイ

deployment createで、コンポーネントをデプロイできます。

※ コマンドは、artifacts及び、recipesが、カレントディレクトリの配下に存在するものとして実行しています。

$ sudo /greengrass/v2/bin/greengrass-cli deployment create \
  --recipeDir ./recipes \
  --artifactDir ./artifacts \
  --merge "com.example.HelloWorld=1.0.0"

INFO: Socket connection /greengrass/v2/ipc.socket:8033 to server result [AWS_ERROR_SUCCESS]
Aug 10, 2021 11:55:56 PM software.amazon.awssdk.eventstreamrpc.EventStreamRPCConnection$1 onProtocolMessage
INFO: Connection established with event stream RPC server
Local deployment submitted! Deployment Id: c84f0f04-3b2e-4827-84cb-eaf333bf7e38

コンポーネントが実行されていることは、hello_world.pyが出力するログで確認できます。

$ tail -f /tmp/Greengrass_HelloWorld.log
Hello, world! Current time: 2021-08-11 08:04:34.316443.

(2) 再起動

component restart でコンポーネントを再起動します。

$ sudo /greengrass/v2/bin/greengrass-cli component restart \
  --names "com.example.HelloWorld"

  INFO: Socket connection /greengrass/v2/ipc.socket:8033 to server result [AWS_ERROR_SUCCESS]
Aug 11, 2021 8:18:36 AM software.amazon.awssdk.eventstreamrpc.EventStreamRPCConnection$1 onProtocolMessage
INFO: Connection established with event stream RPC server

hello_world.pyのログです。再起動されたため、1行追加されています。

$ tail -f /tmp/Greengrass_HelloWorld.log
Hello, world! Current time: 2021-08-11 08:04:34.316443.
Hello, world! Current time: 2021-08-11 08:08:04.969137.

(3) 一覧

component listでコンポーネントが一覧されます。

デプロイしたcom.example.HelloWorldも確認できます。

$ sudo /greengrass/v2/bin/greengrass-cli component list
AWS libcrypto resolve: searching process and loaded modules
AWS libcrypto resolve: found static aws-lc HMAC symbols
AWS libcrypto resolve: found static aws-lc libcrypto 1.1.1 EVP_MD symbols
Aug 11, 2021 8:19:47 AM software.amazon.awssdk.eventstreamrpc.EventStreamRPCConnection$1 onConnectionSetup
INFO: Socket connection /greengrass/v2/ipc.socket:8033 to server result [AWS_ERROR_SUCCESS]
Aug 11, 2021 8:19:48 AM software.amazon.awssdk.eventstreamrpc.EventStreamRPCConnection$1 onProtocolMessage
INFO: Connection established with event stream RPC server
Components currently running in Greengrass:
Component Name: aws.greengrass.Nucleus
    Version: 2.4.0
    State: FINISHED
    Configuration: {"awsRegion":"ap-northeast-1","componentStoreMaxSizeBytes":"10000000000","deploymentPollingFrequencySeconds":"15","envStage":"prod","fleetStatus":{"periodicStatusPublishIntervalSeconds":86400.0},"greengrassDataPlanePort":"8443","iotCredEndpoint":"c1jhhexzr7sabg.credentials.iot.ap-northeast-1.amazonaws.com","iotDataEndpoint":"a10wed1626vai6-ats.iot.ap-northeast-1.amazonaws.com","iotRoleAlias":"GreengrassV2TokenExchangeRoleAlias","jvmOptions":"-Dlog.store=FILE","logging":{},"mqtt":{"spooler":{}},"networkProxy":{"proxy":{}},"platformOverride":{},"runWithDefault":{"posixShell":"sh","posixUser":"ggc_user:ggc_group"},"telemetry":{}}
Component Name: DeploymentService
    Version: 0.0.0
    State: RUNNING
    Configuration: null
Component Name: aws.greengrass.Cli
    Version: 2.4.0
    State: RUNNING
    Configuration: {"AuthorizedPosixGroups":null}
Component Name: UpdateSystemPolicyService
    Version: 0.0.0
    State: RUNNING
    Configuration: null
Component Name: com.example.HelloWorld
    Version: 1.0.0
    State: FINISHED
    Configuration: {"Message":"world"}
Component Name: TelemetryAgent
    Version: 0.0.0
    State: RUNNING
    Configuration: null
Component Name: FleetStatusService
    Version: 0.0.0
    State: RUNNING
    Configuration: null

(4) 削除

コンポーネントの削除は、deployment create --remove=XXX で行います。

$ sudo /greengrass/v2/bin/greengrass-cli deployment create --remove="com.example.HelloWorld"

INFO: Socket connection /greengrass/v2/ipc.socket:8033 to server result [AWS_ERROR_SUCCESS]
Aug 11, 2021 8:21:22 AM software.amazon.awssdk.eventstreamrpc.EventStreamRPCConnection$1 onProtocolMessage
INFO: Connection established with event stream RPC server
Local deployment submitted! Deployment Id: dc2abd5f-daa0-4818-a80a-c3454bd766c8

4 ログ

作成したコンポーネントのログは、/greengrass/v2/logsの下に出力されています。

$ sudo tail -f /greengrass/v2/logs/com.example.HelloWorld.log

2021-08-10T23:08:04.982Z [INFO] (Copier) com.example.HelloWorld: Run script exited. {exitCode=0, serviceName=com.example.HelloWorld, currentState=RUNNING}
2021-08-10T23:11:03.258Z [INFO] (pool-2-thread-36) com.example.HelloWorld: shell-runner-start. {scriptName=services.com.example.HelloWorld.lifecycle.Run, serviceName=com.example.HelloWorld, currentState=STARTING, command=["python3 -u /greengrass/v2/packages/artifacts/com.example.HelloWorld/1.0.0/hell..."]}
2021-08-10T23:11:03.340Z [INFO] (Copier) com.example.HelloWorld: stdout. Hello, world! Current time: 2021-08-11 08:11:03.339794.. {scriptName=services.com.example.HelloWorld.lifecycle.Run, serviceName=com.example.HelloWorld, currentState=RUNNING}

5 最後に

今回は、初めてのコンポーネントということで、Greengrass CLIを使用して、デバイス上(ローカル)で作業してみました。

Greengrass クラシック (V1)のように、実行プログラムは、Lambdaに限りません。今回のように、pythonのスクリプトも軽易に利用可能であることが分かります。 なんか、Greegrass V2の可能性を感じます。

## 6 参考リンク
[AWS IoT Greengrass V2] RaspberryPIにインストールしてみました
[AWS IoT Greengrass V2] RaspberryPIでコンポーネントを作成してみました
[AWS IoT Greengrass V2] クラウド側から複数のコアデバイスにコンポーネントをデプロイしてみました
[AWS IoT Greengrass V2] クラウド側からコンポーネントを削除してみました
[AWS IoT Greengrass V2] ローカルデバッグコンソール(aws.greengrass.LocalDebugConsole)を使用してみました
[AWS IoT Greengrass V2] Lambda関数(コンポーネント)をデプロイしてみました
[AWS IoT Greengrass V2] コンポーネントからIoT CoreのメッセージブローカーにPublish/Subscribeしてみました
[AWS IoT Greengrass V2] コンポーネントからシークレットマネージャにアクセスしてみました