Raspberry PiでAWS GreenGrassをセットアップし、AWS Lambda 関数を設定するまで 


最近、組み込み×クラウドの話をよく耳にします。
自分でも、どんな取り組みがあるのかと調べては試してを繰り返しています。 

そんな中、AWS Summit で「IoT GreenGrass」を見て便利そうだなと思ったで、環境構築からチュートリアル実行までやってみました。


# 参考ページ

[AWS IoT Greengrass の使用開始 チュートリアル](https://docs.aws.amazon.com/ja_jp/greengrass/latest/developerguide/module1.html)

# AWS IoT Greengrass の設定

AWS IoT から IoT Greengrass を選択。

![q1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308887/790cf3c1-5aaa-94b1-0d89-01445268317d.png)

「グループを作成」を選択。

![q2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308887/f1742e1f-f203-f260-974f-f6a4a18a8490.png)

「簡単な作成の使用」を選択。

![q3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308887/9b590897-b623-33d5-6254-23938990331a.png)

グループに任意の名前をつけます。

<img width="1029" alt="q4.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308887/c28e96eb-be46-3e78-4fa9-b7480f364353.png">

Core機能の名前はそのままで大丈夫です。
グループ名の末に_Coreがつくと思います。

<img width="1048" alt="q5.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308887/ca850552-db47-09f3-716d-fc68a29a642d.png">

グループとCoreの作成をしてください。
その後のコアのセキュリティリソースのダウンロードも忘れずに。

![q6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308887/38803dba-1455-4507-7385-c47284039eb3.png)

また以下からAWS IoT Greengrass Core ソフトウェアインストールパッケージをダウンロードしておきます。
（ページの下の方に進むとあります）

[AWS IoT Greengrass Core ソフトウェア](https://docs.aws.amazon.com/ja_jp/greengrass/latest/developerguide/what-is-gg.html#gg-core-download-tab)

今回はラズパイに入れるので「Raspbian」を選びましょう。

![q7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308887/9458d7e3-9836-933c-3b88-8592f9481749.png)


# Raspberry Pi側の設定

### Raspberry Pi のセットアップ

以下コマンドを実行。

```
sudo adduser --system ggc_user
sudo addgroup --system ggc_group
```

起動時にオペレーティングシステムのハードリンクとソフトリンクの保護を有効にする。
まずは以下コマンドを実行。

```
cd /etc/sysctl.d
ls
```

98-rpi.conf ファイルがあれば以下の２行を末尾に追加。
（rootとして実行する必要がある場合も）

```
fs.protected_hardlinks = 1
fs.protected_symlinks = 1
```

再起動して以下を実行。

```
sudo sysctl -a 2> /dev/null | grep fs.protected
```
fs.protected_hardlinks = 1 と fs.protected_symlinks = 1が表示されればOKです。

次にコマンドラインブートファイル (cmdline.txt)を編集し、メモリ cgroups を有効にしてマウントします。
containerization モードで実行するには、Cgroups も必要になります。
boot直下に移動します。

```
cd /boot/
```

ファイルの既存行の末尾に以下を追加。

```
cgroup_enable=memory cgroup_memory=1
```
再起動して完了です。

### パッケージ作成の前準備

まずは先ほどダウンロードしたAWS IoT Greengrass Core ソフトウェアインストールパッケージを解凍します。
すると以下の様なフォルダ構成になると思います。

```
greengrass
 |
 |- cers
 |- config
 |- ggc
 |- ota
```

次にグループ作成時にダウンロードした、コアのセキュリティリソースのフォルダも解凍します。
すると以下の様なフォルダ構成になると思います。

```
(コアのセキュリティリソースのフォルダ名)
 |
 |- cers
 |- config
```

上記で解凍したコアのセキュリティリソースの cers の中身を、 greengrass 直下の同じ名前のフォルダに移動します。
また、セキュリティリソースの config の config.json を greengrass 直下の config に移動し、ファイルを上書きします。

上記が終了したら、 greengrass を圧縮し、 Raspberry Pi へ送信します。
(自分はmacだったので、scpコマンドを使いました。)

送信できたら、 Raspberry Pi で、圧縮した greengrass フォルダを解凍し、/ 直下に配置します。

### ルート CA 証明書を配置

以下のコマンドを実行し、ルート CA 証明書を配置。
（別の証明書を使いたい場合は[こちら](https://docs.aws.amazon.com/iot/latest/developerguide/managing-device-certs.html#server-authentication)を参考に）

```
cd /greengrass/certs/
sudo wget -O root.ca.pem https://www.amazontrust.com/repository/AmazonRootCA1.pem
```

ダウンロードしたファイルが空でないか確認します。

```
cat root.ca.pem
```

Raspberry Pi で AWS IoT Greengrass を起動します。
「Greengrass successfully started」メッセージが表示されたら、PID をメモしておいてください。

```
cd /greengrass/ggc/core/
sudo ./greengrassd start
```

AWS IoT Greengrass コア ソフトウェア が機能しているか確認します。

```
ps aux | grep (PIDをかく)
```
実行中の Greengrass デーモンへのパスを持つ PID のエントリが表示されれば機能しています。

# Lambda 関数の作成、パッケージ化

### パッケージ作成

以下のページから、AWS IoT Greengrass Core SDK for Python をダウンロードします。

[AWS IoT Greengrass Core SDK](https://docs.aws.amazon.com/ja_jp/greengrass/latest/developerguide/what-is-gg.html#gg-core-sdk-download)

Python の 最新バージョンを選択。

![q8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308887/9a7f058d-061e-12fb-c656-c1943570a0f0.png)

今回はフォルダから以下を取得。

```
examples\HelloWorld (フォルダ)
greengrasssdk (フォルダ)
```

greengrasssdk を HelloWorld フォルダ直下ににコピー。

greengrassHelloWorld.py ファイルと greengrasssdk フォルダを hello_world_python_lambda.zip という名前の圧縮された .zip ファイルに保存。
この様にして Lambda 関数デプロイパッケージを作成します。

![q9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308887/9ad4aeb4-86f5-d7cd-2b3a-32b39e178cf7.png)

macなどの場合は以下のコマンドで上記パッケージが簡単に作成できます。

```
sudo zip -r hello_world_python_lambda.zip greengrasssdk greengrassHelloWorld.py
```

### Lambda 関数の作成

AWS のサービスから Lambda を選択。

![q10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308887/dcd10bb2-57db-35fe-0c16-9a9b009d8ba8.png)

関数の作成を選択。

![q11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308887/ff56e830-743d-0522-ac53-a56720bd2958.png)

一から作成を選択。

![q12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308887/77b19e70-2071-2dee-2ede-98b7a29c17ad.png)

関数名は任意で、ランタイムはPython 2.7を選択。

![q13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308887/83968a3b-a718-5741-a4b6-7d862ecfc37b.png)

ロールの設定はこんな感じ。
そして、関数の作成を押下。

![q14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308887/afce3332-eb78-85ce-1414-2926a564b0e8.png)

設定タブの関数コードを以下の様に設定し、先ほど作成したパッケージをアップロードします。![q16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308887/8081998b-fc3d-1df0-9684-1bc186fb225f.png)

アクションから「新しいバージョンを発行」を選択。

![q15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308887/fdc12281-e325-0135-fb8f-41799b1c3623.png)

任意のバージョン名を設定。そして発行します。

![q17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308887/4c63e892-929a-b9ec-76aa-6d1306f3a01a.png)

一応エイリアスも設定しておきます。

![q18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308887/251ea04c-eb07-f36f-17d9-9deef76ac700.png)

任意の名前で作成。

![スクリーンショット 2019-06-13 20.57.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308887/22420e42-f7d1-33de-c5b9-6c80a5b1bbd3.png)

作成完了です。

# IoT Greengrass の Lambda 関数の設定

IoT Greengrass のグループメニュー（先ほど作成した）から Lambda を選択。
その後、Lambdaの追加を選択。

![q19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308887/fb91dea1-66e9-34a3-823a-07c035e31df1.png)

「既存の Lambda の使用」を選択。

![q20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308887/417abaec-fb85-816d-9bfc-60fa326e6603.png)

先程作成した Lambda 関数が出てくるので選択し次へ。

![q21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308887/33e2be84-408e-0790-896e-cf039e9ce4af.png)

エイリアスも先ほど作ったものを選択し完了。

![q22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308887/c8b89d58-d966-8aeb-58a9-57f7a46a61dc.png)

「...」を選択し、設定の編集を選択します。

![q23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308887/a94a40fc-c50a-b233-50dd-1b24ab30b5fe.png)

下記の赤い枠で括った部分の設定を変更します。
その後、更新。

![q24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308887/8bcafd56-a22b-9fe7-d6c0-62b349db2a51.png)

次に「サブスクリプション」を選択し、「最初のサブスクリプションの追加」を追加します。

![q25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308887/05e69515-733b-af6d-53fd-05238bb5964f.png)

ソースの選択では以下の様に選択。

![q26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308887/b354db53-2410-37ec-5174-7cefb442f500.png)

ターゲットの選択では以下の様に選択。
その後、次へ。

![q27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308887/b2b67631-4792-c76c-d741-ad31b0008d57.png)

トピックフィルターを以下の様に入力。
その後次へ、完了を選択。

![スクリーンショット 2019-06-13 21.24.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308887/cbe86396-d326-a45b-10c1-316b8a56fb51.png)

アクションメニューから「デプロイ」を選択。

![q28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308887/19c18646-887f-cdda-27fd-5b072c18d784.png)

「自動検出」を選択。

![q29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308887/410575ec-82fb-d245-909f-9cbcb0ef4290.png)

「権限の付与」を選択。

![q30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308887/fb25d2b6-bf3c-46ab-2af2-0e17bfc7696c.png)

その後デプロイすると...
<img width="1039" alt="スクリーンショット 2019-06-19 11.32.08.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308887/1c456759-0dec-4401-e0a2-a2650d8a4f26.png">

うまくいきました！！！

# そんなスラスラとできたわけではなかった
上記の手順でみていくとあたかも簡単にできた感じですが、実際はめちゃくちゃ躓きました...
(デプロイ成功の日時で察した方もいるかと思いますが..)

自分の要領の悪さと理解不十分のせいかもしれませんが、躓いた部分を以下に記述します。

### なぜか Rasbian os でうまくいかなかった


デプロイした際に進行中のステータスまではいくのですが、そこから進展がなかったです。
Raspberry Pi のOSを UbuntuMATE にして再度やり直したらうまくいきました。
（インストールパッケージはrasbianなのに...?）
もうちょっとちゃんと調べてみます。

### ユーザーの名前空間が有効になっていないために AWS IoT Greengrass コア ソフトウェアが Raspberry Pi で実行されない

自分の環境では以下のエラーが出ました。

```
The AWS IoT Greengrass Core software does not run on Raspberry Pi because user namespace is not enabled.
```

これは以下のコマンドを実行し再デプロイすることで、解決しました。

```
# ファームウェアおよび kernel を最新の安定したバージョンに更新
sudo BRANCH=stable rpi-update
# daemonを停止
cd /greengrass/gcc/core
sudo ./greengrassd stop
# 再起動
sudo reboot
# 再起動後にdaemonを再起動
cd /greengrass/gcc/core
sudo ./greengrassd restart
```

また、その他のエラーが出た場合は[こちら](https://docs.aws.amazon.com/ja_jp/greengrass/latest/developerguide/gg-troubleshooting.html)のトラブルシューティングを参考にするのが良いと思います！

正直使いこなすまでにはもっと理解が必要そうです...