AWS IoT Greengrass V2をTerraformとAnsibleでRaspberry Piに導入するサンプル作った

タイトルの通り、AWS IoT Greengrass V2をTerraformとAnsibleでRaspberry Piに導入するサンプル作りました。

github.com

概要は以下になります。最終的にはRaspberry Piから発行されたMQTTメッセージがAWS IoTで確認できるはずです。

前提

  • PC環境

    • Linux
    • Git
    • Make
    • Docker
    • AWS CLI
  • Raspberry Pi

以下のOSイメージを利用しています。(恐らく他のDebianでも動くはず) SSHでログオンできるようにしておきます。 https://downloads.raspberrypi.org/raspios_lite_armhf/images/raspios_lite_armhf-2022-09-26/

  • S3 Bucket

Terraformのtfstateと、GreengrassにデプロイするArtifact(今回はPythonコード)を保管します。

実行手順

事前準備

Raspberry Pi準備

Raspberry Piをインストールして、SSHでログオンできるようにしておきます。

Gitリポジトリの準備

以下のリポジトリをCloneします。

github.com

$ git clone https://github.com/yomon8/greeengrass-v2-raspberrypi.git
$ cd greengrass-v2-raspberrypi
Makefileのパラメータ確認

Makeをタスクランナーとして利用して作業します。

設定可能なパラメータは以下の通りです。

$ vim Makefile
#############################################
# Parameters
#############################################
DEVICE_NAME := my-ggv2-device
AWS_PROFILE ?= default
AWS_REGION ?= ap-northeast-1
GREENGRASS_VERSION := 2.9.3
COMPONENT_NAME := com.example.greengrassv2
COMPONENT_VERSION := 1.0.0
TARGET_IOT_TOPIC := $(COMPONENT_NAME)/topic
S3_BUCKET :=
DEVICE_IP :=
パラメータ 説明 デフォルト値
DEVICE_NAME Greengrassのグループとデバイス名として利用 my-ggv2-device
AWS_PROFILE AWSプロファイル名 default
AWS_REGION AWSリージョン名 ap-northeast-1
GREENGRASS_VERSION Greengrassのバージョン 2.9.3
COMPONENT_NAME Greengrass Component名 com.example.greengrassv2
COMPONENT_NAME Greengrass Componentバージョン 1.0.0
TARGET_IOT_TOPIC ダミーメッセージをPublish先のAWS IoT Topic名 $(COMPONENT_NAME)/topic
S3_BUCKET tfstateとGreengrassのArtifact保管用 -
DEVICE_IP Raspberry PiのIPアドレス -

S3_BUCKETDEVICE_IP はmakeコマンドの引数としての指定が必須になります。

Terraform実行

まずはTerraformでAWSリソースのプロビジョニングを行います。以下のmakeコマンドで実行します。

$ make tf-apply S3_BUCKET=my-bucket AWS_PROFILE=myprofile

# 省略

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

Terraformの適用が終わると、AWS IoT周りを中心にAWSリソースがデプロイされるのと同時に、以下のようにGreengrassの設定に必要なファイル群が出力されます。これらのファイルを利用して後続の処理が実行されます。

greengrass-config
├── certs
│   ├── AmazonRootCA1.pem
│   ├── device.pem.crt
│   └── private.pem.key
├── component
│   ├── com.example.greengrassv2.json
│   └── recipe
│       └── com.example.greengrassv2_1.0.0.yaml
└── config
    └── config.yaml

4 directories, 6 files

Terraformの内容は以下のドキュメントを参考にして実装しています。

docs.aws.amazon.com

Ansible実行

Ansibleを実行して、Raspberry PiにGreengrassを導入していきます。この際に上記のTerraformから出力した設定ファイルも利用されます。

Raspberry PiにはpiユーザでSSH鍵でログオンできるようにしておきます。sshの接続方法を調整したい場合は、ansible/ssh_config を修正してください。

以下のmakeコマンドでAnsibleを実行します。

make ansible-apply DEVICE_IP=xxx.xxx.xxx.xxx

実行が正常に終了したらRaspberry Piにログオンしてみると、Greengrass Serviceが起動しているのが確認できます。

pi@raspberrypi:~ $ systemctl status greengrass.service 
● greengrass.service - Greengrass Core
     Loaded: loaded (/etc/systemd/system/greengrass.service; enabled; vendor preset: enab>
     Active: active (running) since Tue 2023-02-07 00:13:08 GMT; 26min ago
   Main PID: 5065 (sh)
      Tasks: 41 (limit: 4915)
        CPU: 7.962s
     CGroup: /system.slice/greengrass.service
             ├─5065 /bin/sh /greengrass/v2/alts/current/distro/bin/loader
             └─5073 java -Dlog.store=FILE -Dlog.store=FILE -Droot=/greengrass/v2 -jar /gr>

Feb 07 00:13:08 raspberrypi systemd[1]: Started Greengrass Core.
Feb 07 00:13:08 raspberrypi sh[5065]: Greengrass root: /greengrass/v2
Feb 07 00:13:08 raspberrypi sh[5065]: Java executable: java
Feb 07 00:13:08 raspberrypi sh[5065]: JVM options: -Dlog.store=FILE -Droot=/greengrass/v2
Feb 07 00:13:08 raspberrypi sh[5065]: Nucleus options: --setup-system-service false
Feb 07 00:13:10 raspberrypi sh[5073]: Launching Nucleus...
Feb 07 00:13:12 raspberrypi sh[5073]: Launched Nucleus successfully.

AWSマネジメントコンソールからもGreengrassのコアデバイスが登録されていることを確認できます。

Greengrassへのコンポーネントデプロイ

Terraformの実行時にGreengrassのコンポーネントファイルとして、こちらが参照されます。

./greengrass-config/component/com.example.greengrassv2_1.0.0.json

以下のmakeコマンドで、GreengrassコンポーネントをAWSにデプロイします。

$ make greengrass-component AWS_PROFILE=myprofile
{
    "arn": "arn:aws:greengrass:ap-northeast-1:123456789012:components:com.example.greengrassv2:versions:1.0.0",
    "componentName": "com.example.greengrassv2",
    "componentVersion": "1.0.0",
    "creationTimestamp": "2023-02-07T09:41:36.273000+09:00",
    "status": {
        "componentState": "REQUESTED",
        "message": "NONE",
        "errors": {}
    }
}

AWSマネジメントコンソールからもGreengrassコンポーネントが登録されていることを確認できます。

Greengrassコンポーネントをデバイスにデプロイ

以下のmakeコマンドで、GreengrassコンポーネントのRaspberry Piへのデプロイが開始されます。

$ make greengrass-deploy AWS_PROFILE=myprofile

AWSマネジメントコンソールからもGreengrassコンポーネントのデプロイ状態を確認できます。以下のように成功のステータスとなれば、デプロイが無事に完了しています。

AWS IoT MQTTテストクライアントでメッセージ確認

ここまで来たら、AWS IoTのMQTTテストクライアントで、設定したTopicをサブスクライブしてみます。以下のようにRaspberry Piから発行されたMQTTメッセージが定期的に表示されるのが確認できるはずです。