ラズパイでAWS Greengrass

まずはセットアップするところまで。
せっかく書いたから投稿するけど、Greengrassタグが65個あったのでもっといい記事がありそう..

## ラズパイの基本セットアップについて
詳細は下記参照。ラズパイのセットアップ、アップグレード、sshなどを設定。

https://qiita.com/rootpia/items/372a0c92c5a9a7839f37

環境のみ抜粋する。
使用モデル：Raspberry Pi 4 Model B (RAM 4GB)

```shell
$ cat /etc/os-release
PRETTY_NAME="Raspbian GNU/Linux 11 (bullseye)"
NAME="Raspbian GNU/Linux"
VERSION_ID="11"
VERSION="11 (bullseye)"
VERSION_CODENAME=bullseye
ID=raspbian
ID_LIKE=debian
HOME_URL="http://www.raspbian.org/"
SUPPORT_URL="http://www.raspbian.org/RaspbianForums"
BUG_REPORT_URL="http://www.raspbian.org/RaspbianBugs"
```

## 前準備（AWS側）
### IAMロールを作成
[インストーラーがリソースをプロビジョニングするための最小限の IAM ポリシー](https://docs.aws.amazon.com/ja_jp/greengrass/v2/developerguide/provision-minimal-iam-policy.html)を参考にして、下記ポリシーを持ったロールを作成する。

以下、GreenGrassRoleとする。

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "iot:AddThingToThingGroup",
                "iot:AttachPolicy",
                "iot:AttachThingPrincipal",
                "iot:CreateKeysAndCertificate",
                "iot:CreatePolicy",
                "iot:CreateRoleAlias",
                "iot:CreateThing",
                "iot:CreateThingGroup",
                "iot:DescribeEndpoint",
                "iot:DescribeRoleAlias",
                "iot:DescribeThingGroup",
                "iot:GetPolicy",
                "iam:GetRole",
                "iam:CreateRole",
                "iam:PassRole",
                "iam:CreatePolicy",
                "iam:AttachRolePolicy",
                "iam:GetPolicy",
                "sts:GetCallerIdentity"
            ],
            "Resource": "*"
        },
        {
            "Sid": "DeployDevTools",
            "Effect": "Allow",
            "Action": [
                "greengrass:CreateDeployment",
                "iot:CancelJob",
                "iot:CreateJob",
                "iot:DeleteThingShadow",
                "iot:DescribeJob",
                "iot:DescribeThing",
                "iot:DescribeThingGroup",
                "iot:GetThingShadow",
                "iot:UpdateJob",
                "iot:UpdateThingShadow"
            ],
            "Resource": "*"
        }
    ]
}
```

ロール作成後、GreenGrassRoleのページの「認証関係」タブを選択し、「認証関係の編集」ボタンを押下。
jsonで下記を設定する。アカウントIDは12桁の数値、ユーザ名は次手順で作成するユーザ名（本資料ではGreengrassUser）に置き換えること。

```json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::<アカウントID>:user/<ユーザ名>"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
```


### IAMユーザを作成
IAM > ユーザー から「ユーザーを追加」ボタンを押下。

* ユーザー名：  
    適当な名称（以下、GreengrassUser とする）。
* AWS認証情報タイプを選択：  
    アクセスキーのみチェック。
* ユーザーにつけるポリシー：  
    アカウントID、ロール名（本資料ではGreenGrassRole）は置き換えること。

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": [
                "sts:AssumeRole"
            ],
            "Effect": "Allow",
            "Resource": [
                "arn:aws:iam::<アカウントID>:role/<ロール名>"
            ]
        }
    ]
}
```
作成後、アクセスキー＆シークレットアクセスキーを書き留めておく。


## 前準備（ラズパイ側）
[AWS IoT greengrass（AWSマネジメントコンソール）](
https://ap-northeast-1.console.aws.amazon.com/iot/home?region=ap-northeast-1#/greengrassIntro)にも手順が記載されているが、前準備も含めて具体的に記載する。


ラズパイにJDK（JAVA）をインストール

```shell
$ sudo apt install default-jdk 
```

インストール後のバージョン

```shell
$ java --version
openjdk 11.0.13 2021-10-19
OpenJDK Runtime Environment (build 11.0.13+8-post-Raspbian-1deb11u1)
OpenJDK Server VM (build 11.0.13+8-post-Raspbian-1deb11u1, mixed mode)
```

AWS CLIをインストール。ラズパイへのインストール方法が以下に詳しく記載されている。

https://qiita.com/ekzemplaro/items/b5b42ce90fbe2fb05cd2

JSON成型用にjqコマンドをインストール

```shell
$ sudo apt install jq
```

AWS CLIをセッティング。

```shell
$ aws configure
AWS Access Key ID [None]:　　　　※前手順で書き留めたIAMユーザのアクセスキー
AWS Secret Access Key [None]:　　※　　　　　　〃　　　　　　　 シークレットアクセスキー
Default region name [None]:　　　※ap-northeast-1　を入力（東京リージョン以外は適宜変更）
Default output format [None]:　　※そのままReturnキー押下（jsonとなる）
```

セッショントークンを取得＆環境変数に設定。
AWS_ACCESS_KEY_ID、AWS_SECRET_ACCESS_KEYはconfigureの設定値を見て欲しいのに、環境変数に入れないとダメっぽい...

```shell
$ export STSRES=$(aws sts assume-role --role-arn arn:aws:iam::<アカウントID>:role/GreenGrassRole --role-session-name sts-session --duration-second 3600 --profile default)
#echo $STSRES | jq .
$ export AWS_ACCESS_KEY_ID=$(echo $STSRES | jq -r '.Credentials.AccessKeyId')
$ export AWS_SECRET_ACCESS_KEY=$(echo $STSRES | jq -r '.Credentials.SecretAccessKey')
$ export AWS_SESSION_TOKEN=$(echo $STSRES | jq -r '.Credentials.SessionToken')
$ unset STSRES
```

## Greengrassをラズパイにインストール
[マネジメントコンソールからGreengrassのセットアップページ](https://ap-northeast-1.console.aws.amazon.com/iot/home?region=ap-northeast-1#/greengrassIntro)へ移動し、「1 つの Core デバイスをセットアップ」ボタンを押下。
以下、入力する。

* ステップ 1: Greengrass コアデバイスを登録する
    * コアデバイス名：適当な名称を入力。（本資料ではGreengrass-rsp001とした）
* ステップ 2: モノのグループに追加して継続的なデプロイを適用する
    * モノのグループ： 「新しいグループ名を入力」を選択し、適当な名称を入力。（本資料ではGreengrassQuickStartGroupとした）
* ステップ 3: Greengrass コアソフトウェアをインストール
    * オペレーティングシステム： 「Linux」を選択

上記まで入力すると、ページの下半分に記載されているコマンド内容が動的に変わる。
以下はマネジメントコンソールにも記載されているが念のため記載しておく。
※設定値によってコマンド引数が変わるため、コピペした方がよい

Greengrassインストーラのダウンロード　　※ラズパイで実行

```shell
$ cd /tmp
$ curl -s https://d2s8p88vqu9w66.cloudfront.net/releases/greengrass-nucleus-latest.zip > greengrass-nucleus-latest.zip && unzip greengrass-nucleus-latest.zip -d GreengrassCore
```

Greengrassインストーラの実行　　※ラズパイで実行

```shell
$ sudo -E java -Droot="/greengrass/v2" -Dlog.store=FILE -jar ./GreengrassCore/lib/Greengrass.jar --aws-region ap-northeast-1 --thing-name Greengrass-rsp001 --thing-group-name GreengrassQuickStartGroup --component-default-user ggc_user:ggc_group --provision true --setup-system-service true --deploy-dev-tools true
```
失敗する場合は、一時権限を1hで取得しているため、aws sts コマンドでセッショントークンを再取得＆再設定するとよい。
コマンド実行後（コマンドはすぐ返ってくるが）AWS側で登録されるまで10～20分かかる。

## インストール後の確認
* [AWS IoT > Greengrass > コアデバイス](https://ap-northeast-1.console.aws.amazon.com/iot/home?region=ap-northeast-1#/greengrass/v2/cores)のページにコアデバイスが追加されていることを確認する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490864/3601125c-48f9-86e5-5269-8d6ae595d190.png)

* [AWS IoT > 管理 > モノ](https://ap-northeast-1.console.aws.amazon.com/iot/home?region=ap-northeast-1#/thinghub)のページにもデバイスが追加されていることを確認する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490864/92f48f9d-dd18-20cc-4ea2-4216f53c9c16.png)

* [AWS IoT > 証明書](https://ap-northeast-1.console.aws.amazon.com/iot/home?region=ap-northeast-1#/certificatehub)に証明書が追加されていることを確認する。
どうやら後は証明書による認証でAWSと通信するっぽい。

* [AWS IoT > ポリシー](https://ap-northeast-1.console.aws.amazon.com/iot/home?region=ap-northeast-1#/policyhub)が2つ追加される
    コアデバイスのポリシーは以下ポリシーの権限に加え、STSでロールエイリアス（GreengrassV2TokenExchangeRoleAlias）が追加されて使われる様子。
    * GreengrassV2IoTThingPolicy
    * GreengrassTESCertificatePolicyGreengrassV2TokenExchangeRoleAlias

* [AWS IoT > ロールエイリアス]が1つ追加される
    * GreengrassV2TokenExchangeRoleAlias  
    使いたいサービスがあれば、このロールに追加すればよさそう。  
    ポリシー：GreengrassV2TokenExchangeRoleAccessが初期権限として付いている。

## 後片付け
不要なものを削除しておく。

```shell
$ rm -rf ~/.aws          # AWS CLI
$ rm -f ~/.bash_history  # コマンド履歴
$ rm -f /tmp/greengrass-nucleus-latest.zip   # greengrass一時ファイル
$ rm -rf /tmp/GreengrassCore                 # 同上
```

セットアップ時に使用したユーザは不要なので停止しておく。
[IAM > ユーザー > ＜該当ユーザ＞]のページの「認証情報」タブを開き、「アクセスキー」のステータスから「無効」を選択。