Dockerコンテナ上でGreengrass(V1)を実行する

#はじめに
AWSはGreengrass Coreソフトウェアと依存関係がインストールされたDocker file、Dockerイメージを公開しています。
今回は、以下の公式ドキュメントを参考に、EC2上のDockerコンテナでGreengrassを実行します。
参考：[Docker コンテナでの AWS IoT Greengrass の実行](https://docs.aws.amazon.com/ja_jp/greengrass/v1/developerguide/run-gg-in-docker-container.html#docker-linux-enable-ipv4)
#1　環境構築
公式ドキュメントの「Prerequisites」を参考に、Greengrassを実行する環境を用意します。
今回は最終的に以下の構成となります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1001693/fe48bcf1-5a60-23f4-1787-ed5215374780.png)
##1-1　ネットワーク設定
VPC周辺を以下の通り作成します。
なお、作業は東京リージョンで行い、サブネットはap-northeast-1aに作成しています。
※詳細な手順は以下を参照のこと
　参考：[AWS上にエッジ環境を構築してGreengrass(V1)の動きを確認する - 1-1　ネットワーク周りの作成](https://qiita.com/kt-yt/items/ebdf00c30d399057b73b#1-1%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E5%91%A8%E3%82%8A%E3%81%AE%E4%BD%9C%E6%88%90)

| 作成するもの | 詳細 |
|:-|:-|
| VPC | CIDR：10.0.0.0/16 |
| サブネット | CIDR：10.0.0.0/24 |
| インターネットゲートウェイ | VPCにアタッチする |
| ルートテーブル | 10.0.0.0/16 -> local , 0.0.0.0/0 -> IGW |

##1-2　インスタンスの作成
次に、今回Greengrassを動かすEC2インスタンスを作成します。
※詳細な手順は以下を参照のこと
　参考：[AWS上にエッジ環境を構築してGreengrass(V1)の動きを確認する - 1-2　EC2インスタンスの作成](https://qiita.com/kt-yt/items/ebdf00c30d399057b73b#1-2ec2%E3%82%A4%E3%83%B3%E3%82%B9%E3%82%BF%E3%83%B3%E3%82%B9%E3%81%AE%E4%BD%9C%E6%88%90)

1.以下の通りセキュリティグループを作成する
※アウトバウンドルールはデフォルトのままとしている

| タイプ | ポート範囲 | ソース | 備考 |
|:-|:-|:-|:-|
| SSH | 22 | マイIP | 自身の環境からEC2にSSH接続できるようにするため |
| カスタムTCP | 8883 | 任意の場所 | IoT Coreとの通信用 |

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1001693/b35b79c6-a8ca-b295-c6b5-83f30152543e.png)
2.インスタンスを以下の通り作成する

| 設定項目 | 選択した内容 |
|:-|:-|
| AMI | Amazon Linux 2 AMI（64ビット(x86)） |
| インスタンスタイプ | t2.micro |
| ネットワーク | ※作成したVPC |
| サブネット | ※作成したサブネット |
| 自動割り当てパブリックIP | 有効 |
| セキュリティグループ | ※作成したセキュリティグループ |

3.`yum upgrade` と `yum update` を実施する

```bash
$ sudo yum upgrade -y
$ sudo yum update -y
```
4.タイムゾーンを変更する
参考：[【Linux】タイムゾーン(Timezone)の変更](https://qiita.com/azusanakano/items/b39bd22504313884a7c3)

```bash
#タイムゾーンファイルの変更
$ sudo ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime

#タイムゾーンが変更されていることを確認
$ date
Wed Apr 14 18:29:31 JST 2021

#再起動後にUTCに戻ることを防ぐため /etc/sysconfig/clock を編集
$ sudo vim /etc/sysconfig/clock
```
```:/etc/sysconfig/clock
ZONE="Asia/Tokyo"
UTC=false
```
##1-3　DockerとAWS CLIのインストール
公式ドキュメントのPrerequisitesにある通り、DockerとAWS CLIをインストールします。
「AWS CLI version 2」タブの要件に従います。

1.Dockerをインストールする
参考：[Amazon Linux2にDockerをインストールする](https://qiita.com/reoring/items/0d1f556064d363f0ccb8)

```bash
#Dockerインストール
$ sudo yum install -y docker

#ec2-userをdockerグループに追加（コマンド実行後ログインし直す）
$ sudo usermod -a -G docker ec2-user

#バージョン確認
$ docker version
Client:
 Version:           20.10.4
#中略
Server:
 Engine:
 Version:           20.10.4
#後略

#自動起動設定
$ sudo systemctl enable docker
```
2.AWS CLIをバージョン2にアップデートする
参考：[Linux で AWS CLI バージョン 2 をインストールする](https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/install-cliv2-linux.html)

```bash
#現在のバージョン確認
$ aws --version
aws-cli/1.18.147 Python/2.7.18 Linux/4.14.225-169.362.amzn2.x86_64 botocore/1.18.6

#AWS CLI V1の削除
$ which aws
/usr/bin/aws

#AWS CLI V2のインストール
$ curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"

$ unzip awscliv2.zip

$ sudo ./aws/install
You can now run: /usr/local/bin/aws --version

#インストールされたことの確認
$ aws --version
aws-cli/2.1.38 Python/3.8.8 Linux/4.14.225-169.362.amzn2.x86_64 exe/x86_64.amzn.2 prompt/off
```

以上で以下の構成まで作成できました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1001693/93bb7903-3fdc-b88d-99bd-2857ccd96275.png)
#2　Amazon ECRからGreengrassコンテナイメージを取得する
公式ドキュメントに記載の通り、Greengrassのコンテナイメージを取得します。
参考：[ステップ 1. Amazon ECR から AWS IoT Greengrass コンテナイメージを取得する](https://docs.aws.amazon.com/ja_jp/greengrass/v1/developerguide/run-gg-in-docker-container.html#docker-pull-image)

1.awsコマンドを実行するため、ユーザのクレデンシャル情報環境変数に設定する
※あるいはaws configureコマンドで設定を行う
　なお、利用するIAMユーザには `ecr:GetAuthorizationToken` のポリシーがアタッチされている必要がある

```bash
#環境変数の設定
$ export AWS_ACCESS_KEY_ID='AWSのアクセスキー'
$ export AWS_SECRET_ACCESS_KEY='AWSのシークレットアクセスキー'

#設定されていることの確認
$ echo $AWS_ACCESS_KEY_ID
$ echo $AWS_SECRET_ACCESS_KEY
```
2.Greengrassのコンテナイメージをプルする

```bash
#Amazon ECRレジストリにログイン
$ aws ecr get-login-password --region  us-west-2 | docker login --username AWS --password-stdin https://216483018798.dkr.ecr.us-west-2.amazonaws.com
WARNING! Your password will be stored unencrypted in /home/ec2-user/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded

#Greengrassコンテナイメージを取得
$ docker pull 216483018798.dkr.ecr.us-west-2.amazonaws.com/aws-iot-greengrass:latest

#取得結果
$ docker images
REPOSITORY                                                        TAG       IMAGE ID       CREATED       SIZE
216483018798.dkr.ecr.us-west-2.amazonaws.com/aws-iot-greengrass   latest    d32ac0324f03   8 weeks ago   1.25GB
```
3.シンボリックリンクとハードリンクの保護を有効にする

```bash
#rootユーザに切り替え（sudoで実行してもPermission Deniedになったため）
$ sudo su -

#/etc/sysctl.confに設定を追加
$ echo '# AWS Greengrass' >> /etc/sysctl.conf 
$ echo 'fs.protected_hardlinks = 1' >> /etc/sysctl.conf 
$ echo 'fs.protected_symlinks = 1' >> /etc/sysctl.conf
```
4.IPv4 ネットワーク転送を有効にする

```bash
#ファイル末尾に「net.ipv4.ip_forward = 1」を追記
vim /etc/sysctl.conf

#設定の反映
$ sysctl -p
fs.protected_hardlinks = 1
fs.protected_symlinks = 1
net.ipv4.ip_forward = 1
```
#3　GreengrassグループとCoreの作成
IoT CoreのマネジメントコンソールでGreengrassグループを作成します。
作成後、証明書とコアの設定ファイルを取得します。
参考：[AWS IoT Greengrass の AWS IoT の設定](https://docs.aws.amazon.com/ja_jp/greengrass/v1/developerguide/gg-config.html)

1.IoT Coreのマネジメントコンソールで Greengrass > クラシック(V1) > 「グループの作成」の順にクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1001693/3c9ed628-4d64-b8be-2552-8de07e78a5ba.png)
2.「デフォルト作成を使用」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1001693/e27f18bf-f33e-0e02-7d8c-86796dfcc5d2.png)
3.任意のグループ名を入力して「次へ」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1001693/ba7faaa7-a219-372d-655f-7f943c215276.png)
4.任意のCoreの名前を入力して「次へ」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1001693/bbb21ce4-71d2-70f9-a0aa-5f44686a1951.png)
5.「グループとCoreの作成」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1001693/faeea97b-7e36-9839-0646-da40a099106d.png)
6.「これらのリソースはtar.gzとしてダウンロードしてください」をクリックしてセキュリティリソースを取得したら、「完了」をクリック
※ルートCAの取得はのちの手順で行う
※Greengrass CoreのソフトウェアはDockerイメージとして取得済なのでここでは不要
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1001693/219aeeba-c042-af12-6758-4edd751972ee.png)
#4　Greengrassをローカルで実行
セキュリティリソースをEC2インスタンスにアップロードし、Greengrass Coreを起動します。

1.先ほどダウンロードしたtar.gzファイルをEC2インスタンスにアップロードする
※今回はFileZillaを利用した
2.tar.gzファイルを解凍し、greengrass用のディレクトリに格納する

```bash
#格納先のディレクトリを作成
$pwd
/home/ec2-user

$ mkdir greengrass

#解凍する
$ tar xzvf xxxxxxxxxx.tar.gz -C greengrass/
certs/xxxxxxxxxx.cert.pem
certs/xxxxxxxxxx.private.key
certs/xxxxxxxxxx.public.key
config/config.json

$ ls greengrass/
certs  config
```
3.AmazonのルートCA証明書を取得する

```bash
#モノの証明書、秘密鍵が格納されているディレクトリに移動
$ cd greengrass/certs/

#ルートCA証明書を取得
$ sudo wget -O root.ca.pem https://www.amazontrust.com/repository/AmazonRootCA1.pem

$ ls root.ca.pem
root.ca.pem
```
4.IoT Greengrassコンテナをを実行する

```bash
#certs、configディレクトリをバインド、8883のフォワーディングなどを行い実行
$ docker run --rm --init -it --name aws-iot-greengrass \
 --entrypoint /greengrass-entrypoint.sh \
 -v '証明書を格納したディレクトリのパス':/greengrass/certs \
 -v 'configファイルを格納したディレクトリのパス':/greengrass/config \
 -p 8883:8883 \
 216483018798.dkr.ecr.us-west-2.amazonaws.com/aws-iot-greengrass:latest

#成功すると以下の通り出力される
grep: /greengrass/ggc/deployment/group/group.json: No such file or directory
Setting up greengrass daemon
Validating hardlink/softlink protection
Waiting for up to 1m10s for Daemon to start

Greengrass successfully started with PID: 12
```
#5　検証用の各種設定
今回は、最終的にGreengrassデバイスからのMQTTメッセージで実行するLambdaを用意し、動作することを確認します。
これを検証するための準備を行います。
##5-1　グループのLambda設定
公式ドキュメントの以下の引用の通り、GreengrassをDocker上で実行する場合は、Lambdaを「コンテナなし」で実行する必要があります。
対象グループのLambdaのデフォルト設定を先に変えておきます。
>Docker コンテナで AWS IoT Greengrass で実行する場合、すべての Lambda 関数はコンテナ化を使用しないで実行する必要があります。このステップでは、グループのデフォルトのコンテナ化を [No container (コンテナなし)] に設定します。グループを初めてデプロイする前に行う必要があります。
引用元：[ステップ 4. Greengrassグループに対して「コンテナなし」コンテナ化を構成する](https://docs.aws.amazon.com/ja_jp/greengrass/v1/developerguide/run-gg-in-docker-container.html#docker-no-container)

1.IoT Coreのマネジメントコンソールで Greengrass > クラシック(V1) > グループ の順にクリック
2.対象のグループ名 > 設定 の順にクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1001693/6f25acaf-4627-f6df-9edd-424052a4d925.png)
3.「Lambda ランタイム環境」でデフォルトの Lambda 関数コンテナ化で「コンテナなし」を選択し、「デフォルトのLambda実行設定を更新する」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1001693/6f814997-5785-6917-dd76-1a8787e6f429.png)
4.「続行」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1001693/63e90b10-4223-e257-133a-a5a7fe69d264.png)
##5-2　Lambdaの作成
MQTTメッセージを受け取ったあとに以下の挙動をするLambdaを作成します。

* ローカルのログファイルに書き込む
* IoT CoreにMQTTメッセージを送る

1.ローカルで以下のプログラムを作成する

```python:docker_test.py
import greengrasssdk
import logging
import sys
import json
import datetime

logger = logging.getLogger(__name__)
logging.basicConfig(stream=sys.stdout, level=logging.DEBUG)

client = greengrasssdk.client("iot-data")

logfile = "/tmp/docker_test.log"

def docker_test(event, context):
    date = datetime.datetime.now()
    timestamp = date.strftime("%Y-%m-%d %H:%M:%S")
    
    client.publish(
        topic="test/dockertest",
        payload=json.dumps(
            {
                "function": "docker_test", 
                "message": "This is Test",
                "version":  "1.0",
                "timestamp": timestamp
            }
        )
    )
    
    f = open(logfile, mode="a")
    f.write(timestamp + " success!\n")
    f.close()
```
2.以下で「AWS IoT Greengrass SDK for Python」をダウンロードし、「greengrasssdk」フォルダと先ほど作成したプログラムをまとめてzipファイルとして圧縮する
[GitHub:aws-iot-devise-sdk-for-python](https://github.com/aws/aws-iot-device-sdk-python)
3.Lambdaのマネジメントコンソール画面で 関数 > 「関数の作成」の順にクリック
4.以下の通り設定して「関数の作成」をクリック

* 一から作成
* 関数名：※任意の関数名を設定
* ランタイム：Python3.7

5.アップロード元 > .zipファイル > アップロード > 先ほど作成したzipファイルを選択し、「保存」をクリックする
6.ランタイム設定の「編集」をクリックし、ハンドラを「[ファイル名].[関数名]」にして「保存」をクリック
※上記プログラムのファイル名を「docker_test.py」としていた場合は「docker_test.docker_test」となる
7.アクション > 新しいバージョンを発行 > 「発行」の順にクリック
8.エイリアスタブ > 「エイリアスを作成」の順にクリックして、任意のエイリアス名を入力し、先ほど発行したバージョンを選択して「保存」をクリック
##5-3　Greengrassデバイスの用意
Docker上で動くGreengrass Coreと通信するGreengrassデバイスを用意します。
今回はこちらもEC2を利用して仮想デバイスという形で用意します。

1.IoT Coreのマネジメントコンソールで Greengrass > クラシック(V1) > グループ の順にクリック
2.対象のグループ名 > デバイス > 「デバイスの追加」の順にクリック
3.「新しいデバイスの作成」をクリック
4.任意のモノの名前を入力して「次へ」をクリック
5.1-Clickデプロイの「デフォルトを使用」をクリック
6.「これらのリソースはtar.gzとしてダウンロードしてください」をクリックしてファイルをダウンロードし、「完了」をクリック
7.Greengrassデバイス用に「1-2　インスタンスの作成」と同じ設定でEC2インスタンスを用意する
※VPC、サブネット、セキュリティグループは上記で指定したものと同じものを利用

8.インスタンスが起動したらsshで接続し `sudo yum upgrade` と `sudo yum update`を行う
9.Greengrassデバイス用のインスタンスに先ほどダウンロードしたtar.gzファイルをアップロードして解凍する
※私はFileZillaを利用した

```bash
#ファイル格納用のディレクトリを作成
$ pwd
/home/ec2-user
$ mkdir .certs

#tar.gzファイルの解凍
$ tar xzvf xxxxxxxxxx-setup.tar.gz -C .certs
xxxxxxxxxx.cert.pem
xxxxxxxxxx.private.key
xxxxxxxxxx.public.key
```
10.以下のPythonプログラムを作成、実行して、グループ証明書を取得
※/home/ec2-user/.certs はいかにgroupCA.crtとしてグループ証明書を上書きで作成

```python:get_groupCA.py
import requests
import json
import argparse

#get args
psr = argparse.ArgumentParser(
        description = "get groupCA"
        )

psr.add_argument("-t", "--things", required=True, help="thing name")
psr.add_argument("-c", "--cert", required=True, help="cert file")
psr.add_argument("-k", "--key", required=True, help="private key")

args = psr.parse_args()

things = args.things
cert = args.cert
key = args.key

#set variables for requests
url = "https://greengrass-ats.iot.ap-northeast-1.amazonaws.com:8443/greengrass/discover/thing/" + things

#set path for CA file
CAfile = "/home/ec2-user/.certs/groupCA.crt"

#get present group CA
response = requests.get(url, cert=(cert, key))

#make groupCA file
jsonData = response.json()
groupCA = jsonData["GGGroups"][0]['CAs'][0]

f = open(CAfile, "w")
f.write(groupCA)
f.close()
```
```bash
$ python --things 'モノの名前' --cert 'モノの証明書' --key '秘密鍵'
```
11.MQTT通信用にmosquittoをインストールする

```bash
$ sudo amazon-linux-extras install epel -y

$ sudo yum install mosquitto -y
```
##5-4　Greengrassグループの設定
Lambdaの実行、各通信のためにGreengrassグループの設定を行います。
###Lambdaの設定
作成したLambdaをグループに紐づけます。

1.IoT Coreのマネジメントコンソールで Greengrass > クラシック(V1) > グループ の順にクリック
2.対象のグループ名 > Lambda > 「Lambdaの追加」の順にクリック
3.「既存のLambdaを使用」 > 作成したLambdaを選択して「次へ」 > 作成したエイリアスを選択して「完了」をクリック
4.追加されたLambdaの「…」 > 設定の編集 の順にクリック
5.設定の以下項目を設定して、「更新」をクリック

* コンテナ化：グループのデフォルトを使用（現在：コンテナなし）
* Lambdaのライフサイクル：オンデマンド関数

###サブスクリプション
実行したLambdaからIoT Coreへのメッセージ、IoT CoreおよびGreengrassデバイスからLambdaへのメッセージをPub/Subできるようにサブスクリプションを追加します。

1.対象のグループでサブスクリプション > 「サブスクリプションの追加」の順にクリック
2.以下のサブスクリプションを作成する

| ソース | ターゲット | トピック |
|:-|:-|:-|
| Lambda | IoT Core | test/dockertest ※Lambda内で指定したtopic |
| IoT Core | Lambda | ※任意のtopic |
| Greengrassデバイス | Lambda | ※任意のtopic |

###コアの接続情報検出設定
コンテナ上のGreengrass Coreの接続情報を手動で設定します。
※自動検出にした場合、コンテナ内のIPのみに上書きされてしまい、GreengrassデバイスからEC2インスタンスのIP宛にメッセージを送っても受け取ることができなかった

1.対象のグループで　設定 をクリック
2.Core接続情報を「接続情報の手動管理」に変更する
3.対象のグループで コア > コア名 の順にクリック
4.接続 > 編集 の順にクリック
5.接続情報を追加して「更新」をクリック

* エンドポイント：※Greengrassコンテナを動かしているEC2インスタンスのローカルIP
* ポート：8883

##5-5　ログの格納先作成
Lambdaがログを書き出す先はコード上はGreengrassコンテナの`/tmp`としています。
ここで書き出されたログファイルがコンテナ終了後も残るように、コンテナ上の`/tmp`とマッピングするローカルディレクトリを用意します。

1.Greengrassコンテナを動かすEC2インスタンスにsshで接続してディレクトリを作成する

```bash
$ cd /home/ec2-user/greengrass

$ mkdir tmp

$ ls
certs config log

#コンテナ上でLambdaが書き込めるように全権を付与
$ chmod 777 log
```
2.Greengrassコンテナを起動中のターミナルで `Ctrl + C` を実行してコンテナを停止する
※これで上手くいかない場合は `docker ps -a` でコンテナIDを控えて、`docker stop [控えたコンテナID]` で停止する
3.先ほど作成したディレクトリとコンテナ上の `/tmp` をマッピングして再度コンテナを起動する

```bash
docker run --rm --init --name aws-iot-greengrass \
 --entrypoint /greengrass-entrypoint.sh \
 -v /home/ec2-user/greengrass/certs:/greengrass/certs \
 -v /home/ec2-user/greengrass/config:/greengrass/config \
 -v /home/ec2-user/greengrass/tmp:/tmp \
 -p 8883:8883 \
 216483018798.dkr.ecr.us-west-2.amazonaws.com/aws-iot-greengrass:latest
```
以上の手順が完了したらGreengrassグループをデプロイする。
※AWS上で設定したグループの情報はコンテナを停止→起動するたびにデプロイが必要

デプロイによって、予定していた以下の構成となります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1001693/fe48bcf1-5a60-23f4-1787-ed5215374780.png)
#6　検証
MQTTメッセージをトリガとしてコンテナ上のGreengrassがLambdaを実行できることを確認します。
##6-1　IoT Core -> Lambdaで検証
IoT CoreからのMQTTメッセージをトリガとしてLambdaを実行できることを確認します。

1.IoT Coreのマネジメントコンソールで テスト をクリック
2.トピックのフィルターに「test/dockertest」と入力し、「サブスクライブ」をクリック
※Lambda内で指定しているtopic
3.トピックに公開するタブに移動し、トピック名にサブスクリプションで指定したtopicを入力し、「発行」をクリック
4.以下を確認

* IoT Coreでメッセージをサブスクライブできる
* Greengrassコンテナを動かしているEC2のローカルにログファイルが書き出されている

##6-2　Greengrassデバイス -> Lambda で検証
次にGreengrassデバイスからのMQTTメッセージでLambdaが実行されることを確認します。
この検証は、コンテナ上のGreengrassとGreengrassデバイスが通信できることの確認も含んでいます。

1.先ほどの検証で開始したIoT Coreのサブスクライブはそのままとする
2.Greengrassデバイス用のEC2に接続してMQTTをパブリッシュする

```bash
mosquitto_pub --cafile 'グループ証明書' --cert 'モノの証明書' --key '秘密鍵' \
 -i 'モノの名前' --tls-version tlsv1.2 \
 -h 'Greengrassコンテナを動かしているEC2インスタンスのローカルIP' -p 8883 \
 -q 0 -t 'サブスクリプションで指定したtopic' \
 -m "{\"message\":\"Helloworld\"}" -d
```
3.同じく以下を確認

* IoT Coreでメッセージをサブスクライブできる
* Greengrassコンテナを動かしているEC2のローカルにログファイルが書き出されている

#7　おわりに
以上、Dockerコンテナ上で動くGreengrass(V1)の挙動を簡単に確認しました。

GreengrassデバイスからCoreへの通信がハマりどころでした。
自動検出を有効にしていたためにコンテナのローカルIPがGreengrass Coreの接続情報とされており、通信が成功しませんでした。
※手順でも記載した通りですが、Greengrass Coreの接続情報としてEC2インスタンス自体のローカルIPを静的に指定することで解消
#8　参考文献（文中で登場していないもの）

* Dockerコンテナ上でGreengrassを動かしている記事
 * [GreengrassをDocker for Windows上で使用する準備とファイル読み出しテストの手順](https://hblog.brains-tech.co.jp/entry/greengrass_in_docker_container_trial)
* 「#2　Amazon ECRからGreengrassコンテナイメージを取得する」で実行している内容について
 * [Linux豆知識197 /etc/sysctl.conf](https://linuc.org/study/knowledge/527/#:~:text=%E3%80%8C%2Fetc%2Fsysctl.conf%E3%80%8D%E3%81%AF%E3%80%81OS%E8%B5%B7%E5%8B%95,%E3%81%99%E3%82%8B%E3%81%93%E3%81%A8%E3%81%8C%E3%81%A7%E3%81%8D%E3%81%BE%E3%81%99%E3%80%82)
 * [Dockerはサービス起動時に勝手にIPフォワーディングを有効にする](https://qiita.com/mtgto/items/69d97bbe79f93eb87553)
 * [CentOS / RHEL 7でハードリンクおよびシンボリックリンクを保護する方法 - Centos - 2021](https://ja.compozi.com/how-protect-hard)
* Docker周辺で参考にした記事
 * [「Got permission denied while trying to connect to the Docker daemon socket」への対応](https://qiita.com/ashidaka/items/734856443f922ff175b1)
 * [dockerでvolumeをマウントしたときのファイルのowner問題](https://qiita.com/yohm/items/047b2e68d008ebb0f001)