Zenn
🌱

AWS IoT GreengrassをMacで少し試す

2025/03/22に公開
1

普段なかなか使わないけど、気になっていたサービスを触ってみる個人的な備忘録です。

みなさん、AWS IoT Greengrassはご存知ですか??

https://aws.amazon.com/jp/greengrass/

私は業務の中でIoT関連を扱うことがあるのですが、AWS IoT Greengrassはほとんど触れたことがなく、AWSのIoT系のサービスの中でもレベル400的なハードル感があります(個人的見解です)。

というのも、Linuxを積んだマシン(例えば、Raspberry Pi)とかを実際に用意しないといけなかったりするので、Cloud9がサ終になる今、なかなか気軽に試せないサービスだなーと思ったりしていました。

ただ、別の用件で、MacでGreengrassを調査する必要があったので、タイトル通り、Macで無理やり試してみました。

参考: AWS Black Belt Online Seminar
https://pages.awscloud.com/rs/112-TZM-766/images/AWS-Black-Belt_2024_AWS-IoT-Greengrass-Basic_1106_v1.pdf

参考: AWS IoT Greengrass V2 入門ハンズオン
https://catalog.us-east-1.prod.workshops.aws/workshops/5ecc2416-f956-4273-b729-d0d30556013f/ja-JP

参考: AWS IoT Greengrass V2 の使い方の基本
https://dev.classmethod.jp/articles/aws-iot-greengrass-v2-basics/

環境

Apple M1
macOS Sequoia 15.2

Greengrassをセットアップ

セットアップはほぼ公式のハンズオン通りに進めました。ロールやポリシーはハンズオンの設定をそのまま反映。Greengrassの設定は、AWSコンソールからAWS IoTに移動し、Greengrassのコアデバイスを選択。

コアデバイスをセットアップを押して、デバイスの情報を入力していきます。
コアデバイス名:<任意の名前を入力>
モノのグループ:GrrengrassQuickStartGroup
Greengrassコアソフトの選択:Nucleus Classic
オペレーティングシステム:Linux

デバイスのセットアップ方法ですが、いくつか選択することができます。

ここでは、Macに直接ダウンロードすることを目的にインストーラのダウンロードでデバイスをセットアップするを選びました。

すると、丁寧に次のステップを記載してくれています。
Javaをインストールするんですね。Java使ったことないや、、、

Javaをインストールする

どうやらいろんなところからJDKが出ているのですが、ここではAmazon Corretoでインストールしてみます

brew install --cask corretto
java --version
openjdk 23.0.2 2025-01-21
OpenJDK Runtime Environment Corretto-23.0.2.7.1 (build 23.0.2+7-FR)
OpenJDK 64-Bit Server VM Corretto-23.0.2.7.1 (build 23.0.2+7-FR, mixed mode, sharing)

ふむふむ。これで入ったみたいですね。

AWS IoTモノを作成して接続キットをダウンロード

[モノを作成]ボタンを押すと自動でポリシーやロール関係が設定れれて作成済みになります。
Thingを訳して[モノ]と表現するのもなかなかの違和感ですが、[ブツ]と表現するよりはマシかな。

続いて、[接続キットをダウンロード]ボタンを押してローカルにzipファイルをダウンロード。

インストーラーをダウンロード

[インストーラをダウンロード]ボタンを押してローカルにzipファイルをダウンロードします。

ダウンロードをデバイスに転送してセットアップ

コンソール上では、デバイスへのダウンロードの仕方を丁寧に説明してくれています。

ですが、今回は、Macに直接インストールするので、少し修正をしました。

sed -i 's|{{config_dir}}|/greengrass/v2|g; s|{{nucleus_component}}|aws.greengrass.Nucleus|g' /greengrass/v2/config.yaml && sudo -E java -Droot="/greengrass/v2" -Dlog.store=FILE -jar ./GreengrassInstaller/lib/Greengrass.jar --init-config /greengrass/v2/config.yaml --component-default-user ggc_user:ggc_group --setup-system-service true

これをMacで実行します。

Creating group ggc_group 
ggc_group created 
Added ggc_user to ggc_group 
Launching Nucleus...
Launched Nucleus successfully.

と出て、どうやらうまくいったようです。よしよし。

別のターミナルを立ち上げて状況を見てみます。

 ps aux | grep greengrass

とすると、

59565   0.0  0.0 38537680   3384 s007  S+   Sat06PM   0:43.25 /usr/bin/java -Droot=/Users/okunisan/Documents/dev/aws/self_greengrass_test/greengrass/v2 -Dlog.store=FILE -jar /Users/okunisan/Documents/dev/aws/self_greengrass_test/GreengrassInstaller/greengrass-nucleus-latest/lib/Greengrass.jar --init-config /Users/okunisan/Documents/dev/aws/self_greengrass_test/greengrass/v2/config.yaml --component-default-user ggc_user:ggc_group --setup-system-service false
root             59564   0.0  0.0 410289616    880 s007  S+   Sat06PM   0:00.04 sudo -E java -Droot=/Users/okunisan/Documents/dev/aws/self_greengrass_test/greengrass/v2 -Dlog.store=FILE -jar /Users/okunisan/Documents/dev/aws/self_greengrass_test/GreengrassInstaller/greengrass-nucleus-latest/lib/Greengrass.jar --init-config /Users/okunisan/Documents/dev/aws/self_greengrass_test/greengrass/v2/config.yaml --component-default-user ggc_user:ggc_group --setup-system-service false
okunisan  11964   0.0  0.0 410218224   1376 s009  S+    9:42PM   0:00.01 grep greengrass

おお!どうやら動いている様子ですね。

AWS IoTのコンソールで、Greengrassデバイスでコアデバイスを確認できました。

デバイスの証明書には下記のポリシーがアタッチされていますね。

でもローカル開発で必要となるgreengrass-cliがインストールされませんでした。どうやら、コアソフトウェアのインストール時に、

--deploy-dev-tools true

このオプションを付けてなかったのが原因でした。そこで、今回は、クラウド側からデバイス(今回は手元のMac)に対して、デプロイを試します。

greengrass.Cliコンポーネントのデプロイ

そもそも、greengrass-cliとはなんぞや?って話なんですが、

https://docs.aws.amazon.com/ja_jp/greengrass/v2/developerguide/greengrass-cli-component.html

IoTの場合は、現場にデバイスが置かれるのでクラウド側からソフトウェア更新する場面が多いのですが、開発フェーズだと直接デバイス側でコードをいじったり試したりすることが多く、その時にローカルにデプロイしたり、デバッグするのに役立つのがgreengrass-cliです。

このCLIを導入するには、先ほどのダウンロード時にオプションをつけてインストールするほか、AWS IoTコンソールのGreengrassにおいて、パブリックコンポーネントとしてもあらかじめ用意されており、クラウド側から現場デバイスにデプロイすることができます。(便利!)

参考: UbuntuにAWS IoT GreengrassV2をインストールする - Qiita
https://qiita.com/Yokogawa_Ishino/items/0b28cbd543812b73bd92

この通りにやると、greengrass/v2/binの中にgreengrass-cliが入りました。

❯ greengrass/v2/bin/greengrass-cli --version
Greengrass CLI Version: 2.13.0

しっかり入ってますね。

Greengrassの起動・停止、再起動など各種操作

ということで、無事にGreengrassが入りました。
ところで、Greengrassって、稼働状態を見たり、停止や再起動ってどうするんだろうと気になり、調べました。

❯ ps aux | grep greengrass
root             19023   0.0  0.0 38849384   3252   ??  S    27 125   17:19.44 /usr/bin/java -Dlog.store=FILE -Dlog.store=FILE -Droot=/Users/okunisan/Documents/dev/aws/self_greengrass_test/greengrass/v2 -jar /Users/okunisan/Documents/dev/aws/self_greengrass_test/greengrass/v2/alts/current/distro/lib/Greengrass.jar --setup-system-service false
okunisan  92215   0.0  0.0 410218224   1376 s006  S+    9:37PM   0:00.00 grep greengrass

ふむふむ。rootで何か動いてそう。

sudo lsof -i | grep java
java      19023            root   21u  IPv4 0xcc99d19c9095ffa4      0t0    TCP 192.168.100.30:51084->ec2-35-74-159-248.ap-northeast-1.compute.amazonaws.com:8883 (ESTABLISHED)

通信もしてそうですね。

停止する場合

# Greengrassのプロセスを確認
ps aux | grep greengrass

# 見つかったプロセスIDを使って停止(例:プロセスIDが19023の場合)
sudo kill 19023

無理やり止めます。笑。

再起動する場合

# もしルートディレクトリにいて、配下にgreengrass/v2ディレクトリが存在している場合
sudo greengrass/v2/alts/current/distro/bin/loader

greengrass-cliを使った各種確認

動いているコンポーネントの状況を確認してみます。こういうときにgreengrass-cliが役立ちます。

sudo greengrass/v2/bin/greengrass-cli component list
Password:
Components currently running in Greengrass:
Component Name: aws.greengrass.Nucleus
    Version: 2.13.0
    State: FINISHED
    Configuration: {"awsRegion":"ap-northeast-1","componentStoreMaxSizeBytes":"10000000000","deploymentPollingFrequencySeconds":"15","envStage":"prod","fipsMode":"false","fleetStatus":{"periodicStatusPublishIntervalSeconds":86400.0},"greengrassDataPlaneEndpoint":"","greengrassDataPlanePort":"8443","httpClient":{},"iotCredEndpoint":"<iotCredEndpoint>.credentials.iot.ap-northeast-1.amazonaws.com","iotDataEndpoint":"<iotDataEndpoint>-ats.iot.ap-northeast-1.amazonaws.com","iotRoleAlias":"GreengrassV2TokenExchangeCoreDeviceRoleAlias","jvmOptions":"-Dlog.store=FILE","logging":{},"mqtt":{"spooler":{}},"networkProxy":{"proxy":{}},"platformOverride":{},"runWithDefault":{"posixUser":"ggc_user:ggc_group"},"s3EndpointType":"GLOBAL","telemetry":{}}
Component Name: FleetStatusService
    Version: 0.0.0
    State: RUNNING
    Configuration: null
Component Name: UpdateSystemPolicyService
    Version: 0.0.0
    State: RUNNING
    Configuration: null
Component Name: aws.greengrass.Cli
    Version: 2.13.0
    State: RUNNING
    Configuration: {"AuthorizedPosixGroups":null,"AuthorizedWindowsGroups":null}
Component Name: TelemetryAgent
    Version: 0.0.0
    State: RUNNING
    Configuration: null
Component Name: DeploymentService
    Version: 0.0.0
    State: RUNNING
    Configuration: null

ほほう。こんなのがコンポーネントに入っているんですね。
greengrass-cliさん、便利です。

(オプション)コンポーネントを作成してみる

さて、Macに入れて動かすという初期の目的は達成しましたが、ここからは、入門ハンズオンで説明されていたコンポーネントの作成を試してみます。

ところでGreengrassでいうコンポーネントって何のことでしょうか?

ここがGreengrassのわかりにくいところなんですよね(私的に)
AWS Black Beltを読み返し、自分の中でも概念を整理してみました。

AWS Greengrass コアデバイス
    |---- AWS IoT Greengrass Coreソフトウェア
    |      |---- Nucleus (必須)
    |      |---- Greengrass CLI (ローカル開発ツール)
    |      |---- そのほかいろいろ
    |
    |---- AWS IoT Greengrass コンポーネント
    |      |---- カスタムコンポーネント1
    |      |      |---- レシピ
    |      |      |---- アーティファクト
    |      |---- カスタムコンポーネント2
    |      |      |---- レシピ
    |      |      |---- アーティファクト
    |
    |---- Operating System

コンポーネントとは、カスタムで作れるソフトウェアモジュールなんですね。コンポーネントはレシピとアーティファクトによって定義・設定されます。

レシピ

  • 設定パラメータ、依存関係、ライフサイクル、互換性を指定するメタ情報が書かれたもので、YAMLまたはJSONファイル

アーティファクト:

  • スクリプト、バイナリ、静的リソースそのもの。S3とかECRに置いてデバイスにダウンロードもできる(レシピで指定する)

ふむふむ。少しわかった気がします。
さて実際に、入門ハンズオンで書いているコンポーネント作成をやってみます。greengrass-cliを使い、ローカルデプロイを試みます。

Macのどこかのディレクトリでアーティファクトのフォルダと空のスクリプトファイルを作成します。

mkdir -p artifacts/com.example.HelloWorld/1.0.0

touch artifacts/com.example.HelloWorld/1.0.0/hello_world.py

ここで大事なのは、アーティファクトのパスというのは下記のようにする必要があります。

artifacts/componentName/componentVersion/

なお、componentNameとcomponentVersionは後ほど作る任意の名前になります。

そんで、hello_world.pyの中身は下記とします。

# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: MIT-0
import sys
import datetime
import time

while True:

    message = f"Hello, {sys.argv[1]}! Current time: {str(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)

    time.sleep(1)

コンポーネントレシピの作成とローカルデプロイメント

レシピは各種パラメーターが書かれた定義書です。YAMLかJSONで作成するのですが、今回はJSONで作成してみます。

早速,com.example.HelloWorld-1.0.0.jsonを作成します。

mkdir recipes

touch recipes/com.example.HelloWorld-1.0.0.json

com.example.HelloWorld-1.0.0.jsonの中身

{
  "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": "Darwin"
      },
      "Lifecycle": {
        "Run": "python3 -u {artifacts:path}/hello_world.py '{configuration:/Message}'\n"
      }
    }
  ]
}

では、ついにコアデバイスにローカルデプロイしてみましょう

sudo bin/greengrass-cli deployment create --recipeDir recipes --artifactDir artifacts --merge "com.example.HelloWorld=1.0.0"
Password:
Local deployment submitted! Deployment Id: a2f14f38-9ade-435f-922f-74443ddf2707

これでローカルにデプロイできました。やった。簡単ですね!
うまくいけば、HelloWorldのlogが出るようですが、、、、

あれ、、?エラーだ。。。

Macでやっていたため、たくさんのエラーが吐かれてしまい、うまくいかず。。。ここから数時間、沼にハマりました。

と言うことで今回はここで断念。いつかまた。。。笑

1

Discussion

ログインするとコメントできます