【AWS IoT】エッジデバイス（ラズパイ、Jetson nano）をAWS IoT Coreでプロビジョニングしてみた

AWS IoTを使ううえで一番大事なエッジ機器とIoT Coreを繋ぐ（プロビジョニング）部分をやってみたので解説します。

#はじめに
やりたいことの概略図はこんな感じ。![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1001699/066ea190-6a42-8d92-6b7a-587300804c3e.png)

#大まかなプロセス
・  AWSコンソールでデバイス用の証明書と鍵を生成
・  エッジデバイスと通信。エッジデバイスでAWS IoTと通信するためのPython SDKをインストール。
・  エッジデバイスに証明書と鍵を渡す
・  エッジデバイスで今回の肝となるAWS IoTとMQTT通信するためのPythonファイルをいじる
・  Pythonファイルを実行する。証明書と鍵を使ってエッジデバイスからAWS IoT Coreにメッセージをパブリッシュ

このように認証情報をエッジデバイスに渡してそれを使ってエッジデバイスとIoT Coreをとりあえず簡単に通信させるところまでをプロビジョニングと呼びます。

#※この記事で説明していない前提条件
・エッジデバイスへのOSのインストール（ラズパイだとRaspbian OS、Jetson nanoだとUbuntuを入れる人が多いです）

・OSの初期設定（SSH接続を設定から許可する必要があるかもしれません）

・エッジデバイスの内部IPアドレスを調べる（今回はCLIのみのheadlessは想定していません。普通にデスクトップありのOSでモニターを使ってやる想定です。またJetson nanoは1万円以上もするのになぜかWifiモジュールがついてないので普通にLANケーブルを刺す必要があります...500円でWifi/BluetoothがついているESP8266を見習って欲しい）


#1 AWSコンソールでデバイス用の証明書と鍵を生成
お使いのPC（自分はMacBookで作業しています）でAWSコンソールを開き、「サービス」から「IoT Core」を選択すると以下の画面に行く

左にあるメニューから「モノ」を選択し「作成」をクリック![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1001699/208b0e14-8464-9fe6-7fc3-789b82767c31.png)
￼

名前を適当に決めて（自分は今回はJetson nanoをプロビジョニングしたいので「minagawa_Jetson_nano」としました）、「次へ」を選択。
※「タイプ」や「タグ」はたくさんモノを登録していく際に管理しやすくするため。基本はなしで大丈夫。グループも最初は設定なしで行きます。![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1001699/cbc6f4cd-755c-0b3e-ee45-ddeacf8d73dd.png)
￼

証明書は一番上にある「1-Click証明書作成（推奨）」の「証明書を作成」をクリック![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1001699/1aa6ffe6-fb0c-e8bb-307d-02d5361c312f.png)
￼

すると以下のような画面になります。画面に示してあるように
・このモノの証明書（自分の場合Jetson nano用の証明書）
・プライベートキー
・AWS IoTのルートCA（サーバー用の証明書）

の3つが必要なので、ダウンロードします（パブリックキーは使わないのでダウンロードしない）。![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1001699/cf0dda05-2573-19ad-11a5-6de53343577a.png)
また、3つ目のルートCAのダウンロードをクリックすると別タブで以下の画面に飛ばされてセキュリティの度合いが違う4つのタイプから証明書を選べます。量子コンピュータが現実のものとなっていない今はそこまでここの違いは気にしなくて良いらしい、と言うことで一番上の「RSA 2048 bit key:Amazon Root CA 1」をダウンロードします。右クリックでリンクを保存するをクリック、名前は「AmazonRootCA1.pem」と言った感じになっているのでそのまま保存。![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1001699/44e68eca-be5d-ddeb-f05b-3bcb6f758f56.png)
￼



￼必要な証明書2つと秘密鍵がダウンロードできました。![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1001699/8b114241-6097-5c4c-a885-ed3fdb8d5a5e.png)
￼

￼これら3つは後でエッジデバイスに渡すので大事に保管しておきます。

AWSコンソールに戻り「有効化」をクリックし、「ポリシーをアタッチ」をクリック。![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1001699/2bf8eabd-f329-66c6-df58-6b4dfa8bdc81.png)
￼
こんな画面に行きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1001699/df3d20d7-8156-341f-f5d5-a86bc9f4a428.png)AWSは権限を与えない限り基本何もできないギスギスした世界なので、新しいモノにはポリシーという形で基本的人権を与えてあげます。Defaultがそれに当たります。チェックを入れて「モノの登録」をクリック。![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1001699/e81b49f2-d2bd-bb9d-ad13-0e7ce79c44bf.png)


※￼S3に直接データを送信したい場合などは新たにポリシーを作って付与する必要があります（ここがAWSの面倒なところ）。実験段階では、「神権限」を作っておいてモノに付与するのも手です（その場合「ポリシーの作成」から「アクション」と「リソースARN」に「＊」、効果の「許可」にチェックを入れてポリシーを作成します。名前は例えば「God_Policy」とかいかがでしょう）。defaultだとIoT Coreとの通信しか許可されていません。権限が足りなかったら後から付け足すこともできるので（ポリシーは2つ以上付与できます）、自分はとりあえずこのdefaultで行きます。


下の画像のようにメッセージが出たら無事STEP１証明書と鍵の発行は終わりです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1001699/f850a690-3e76-daec-d29c-a633fbfd42e1.png)
￼

※ちなみにもう少し詳しい説明としては、モノにAWSのサービス（例えばS３）へのアクセス権限を当たるポリシーはたった今発行した証明書に紐づけられます。画像のようにラズパイ君が持ってきた証明書に対しAWSが「この証明書は基本的人権が紐づけられてるな」とか「これは神権限が紐づけられてますね、どうぞお通りください」という風に対応する感じです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1001699/f932c986-b0dd-d3de-bea8-c6dd8dce69cf.png)


#2 エッジデバイスとSSH接続してAWS IoT DeviceSDK Pythonをインストール（＆ビルド）する
Jetson nano向けのUbuntuのデスクトップはご覧の通りめちゃくちゃかっこいいですが、今回はMacBookからSSH接続して操作するので使いません。もちろんSSH接続せずエッジデバイスのターミナルで直接コマンドを打っていくのでも大丈夫です。(※WindowsだとSSH接続にPutty等を使います。Jetson nano用のUbuntuディスクイメージはこちらからインストールできます->https://developer.nvidia.com/embedded/learn/get-started-jetson-nano-devkit#write )![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1001699/1e3fdc51-af80-e336-d1b7-75c2f16cb5c0.png)

Jetson nanoのターミナルで

```
hostname -I
```

と打つとLAN内のIPアドレスが表示されます。
ターミナル上で

```
ssh USER_NAME@IP_ADDRESS
```

と打つとパスワードを求められるので入力。（ラズパイのユーザー名とパスワードはデフォルトでそれぞれ「pi」「raspberry」です）
※「USER_NAME」と「IP_ADDRESS」にはそれぞれユーザー名とIPアドレスを入れてください。ちなみに自分の場合は


```
ssh hidehiro@192.168.1.2
```
￼
と入れました。



無事つながりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1001699/bebb4b9f-549f-3a22-e347-18720a8bc131.png)

#3 AWS IoT Device SDK Pythonをエッジデバイスにインストールする
SSH接続ができたのでPython SDKをインストールしていきます。

```
git clone https://github.com/aws/aws-iot-device-sdk-python.git
```

でAWS IoT Device SDK for Pythonをインストールします。自分はhome/hidehiro/配下にインストールしました。

```
ls
```

でaws-iot-device-sdk-pythonというフォルダができていることを確認します。

```
cd aws-iot-device-sdk-python/samples/basicPubSub
ls
```

とすると、basicPubSub.pyがあるのがわかります。これが今回使用する、AWS IoT CoreとMQTT通信するためのPythonファイルです。

その後、

```
cd aws-iot-sdk-python
sudo python setup.py install
```

でSDKをビルドします。これでAWS IoT Device SDK Pythonの初期設定は終わりです。

#4 エッジデバイスに証明書2つと鍵を渡す
FTP（File Transfer Protocol）のひとつであるFileZillaが便利なので使います。
Mac: https://filezilla-project.org/download.php?platform=osx
Windows: https://filezilla-project.org/download.php?platform=win64
FileZillaを使わない場合はMac,Linuxの場合はftp, scp, sftpコマンドなどでもいけます。

画面はこんな感じ。「Host」にはエッジデバイスのIPアドレス、「Port」には「22」(HTTPSポート)と入れて「Quickconnect」をクリック。![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1001699/f3f1e7a5-864b-ca7c-b8d2-9b6317f1b555.png)
こうなったら成功。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1001699/257d93c9-c3f6-3135-55c1-8d5a91a488f4.png)
￼
証明書2つと鍵はaws-iot-device-sdk-python/samples/basicPubSub/配下に入れます。ベストプラクティスではないかもしれませんが、今回は実験なのでとりあえず。


#5 Pythonファイルの編集

実際にIoT Coreと通信するためのPythonファイルを編集していきます。先程ダウンロードしたAWS IoT Device SDK for Pythonのフォルダの中にサンプルとなるPythonファイルがたくさん入っています（こういうサンプルファイルをスケルトンとも言います）。

Pythonファイルの編集はSSH上でnano等を使って編集しても良いし、PC上で編集したファイルをエッジデバイス上に（FileZilla等で）書き換えても大丈夫です。最終的にbasicPubSub.pyを動かしていくわけですが、ターミナル上で

```
python basicPubSub.py -e [AWS IoTのカスタムエンドポイント] -r [ルートCAのファイルパス] -c [デバイス証明書のファイルパス] -k [秘密鍵のファイルパス] 
```

という風に打つ必要があります。証明書2つと秘密鍵はBasicPubSub.pyと同じファイル配下にあるので、そのままファイル名を入力すれば大丈夫です。AWS IoTのカスタムエンドポイントはどこで確かめるかというと、AWSコンソールのIoT Coreのページに行って、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1001699/251a2a00-8421-a9f2-b55b-6ca063d0e431.png)
左にある「設定」をクリックします（これが超わかりにくい場所にあります。AWS IoTエンドポイントは「設定」にあります。もう一度繰り返します。AWS IoTのエンドポイントは「設定」の場所にあります。悪名高いAWSコンソールの中でもなかなかの凶悪さです）

```
a2v4hij6s98s19-ats.iot.us-east-1.amazonaws.com
```

みたいな感じで、「英数字.iot.あなたの設定したAWS IoTリージョン.amazonaws.com」という感じになっています。これをコピーして適当なところに保存しておきます。


次にいよいよPythonファイルを編集していきます。
PubSub.pyを開いて30行目くらいにそれぞれ入力する箇所があるので、4つとも入力していきます。![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1001699/a24a2664-61a8-3e2b-2e40-a7391b2bb69e.png)

※このPythonファイル内に、MQTTのトピックの設定とか、パブリッシュする頻度、PublishするJSONファイルの編集なども含まれていますが、今回は長くなりすぎるので省きます。

#6 Pythonファイルの実行
いよいよPythonファイルを実行してAWS IoT Coreにメッセージをパブリッシュしていきましょう。今回はパブリッシュするJSONファイルをいじっていないのでHello AWSみたいな味気ないメッセージですが、我慢してください（笑）

cdコマンドでBasicPubSub.pyがあるところまで行きます。その後、先程説明した

```
python basicPubSub.py -e [AWS IoTのカスタムエンドポイント] -r [ルートCAのファイルパス] -c [デバイス証明書のファイルパス] -k [秘密鍵のファイルパス] 
```

を打ちます（自分の場合は「python basicPubSub.py -e a2iw7bft7mqw59-ats.iot.us-east-1.amazonaws.com -r AmazonRootCA1.pem -c 9fd87ec2c7-certificate.pem.crt -k bfd901fa1f-private.pem.key」と言った感じになりました）。

成功すると、以下のような文字列が毎秒更新されていきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1001699/c0a6174c-2b17-c0e5-17e3-2ce14ce8abb6.png)
￼
#7 AWS IoT Coreでメッセージを確認
それに成功したら、AWSコンソールからAWS IoT Coreに行って、「テスト」から「MQTTテストクライアント」に行きます。トピックはbasicPubSub.py内でデフォルトで設定してある「sdk/test/Python」と入力し、「Subscribe」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1001699/65b96cba-eb40-d192-8d21-0942a7f48353.png)

サブスクライブできるとこんな感じ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1001699/53d31acb-4cc7-164f-4ce1-cbebf6f1a012.png)
￼
￼そして先程basicPubSub.pyの実行が成功していると、以下のように毎秒エッジデバイスからメッセージが届いているはずです。やった！![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1001699/17af5053-f3e1-a4e1-d119-9a1fa9488c49.png)
￼
#終わりに
これだけでもだいぶ長くて大変だったかもしれませんが、AWS IoTマスターの旅は始まったばかりです。ポケモンで言うとマサラタウンから出発して最初の草むらでコラッタと戦っているくらい。次回はトキワの森に行ってRule Engineを使ってIoTらしいことをやっていきたいと思います。

※間違いなどあればコメント欄で指摘していただけると幸いです。

※ちなみにこの記事を書くのには主にUdemyのStephen Borsayの「Exploring IoT」を参考にしました。

https://www.udemy.com/course/exploring-aws-iot/