はじめに
今回はAWSのAWS IoT公式ハンズオンに沿ってIoTアプリケーションを作成してみました。ハンズオンで作成したアプリや環境などは、課金が発生しないように基本的にはクリーンアップしてしまうことが多いので、自分の備忘録としても記事として残しておきたいと思います。また、記載しながら理解した内容の整理などもできればよいなと思って記載してます。
参考サイト
-
AWS IoT Core 初級ハンズオン
本記事で利用している画像などは上記サイトから引用しています。
やってみる
では実際にハンズオンを開始していきます。ただ、ハンズオンを開始する前にAWS IoTについて基礎知識がない場合はこちらのブラックベルトを見ておくとかなりハンズオンの中身など理解度が深まると思います。
構築アーキテクチャ

アーキテクチャのポイントとしては以下のような点があると思います。
- 今回はIoTのdummy deviceとしてCloud9を利用する。
- IoTデバイス<>AWS IoT Coreの連携だけでなく、AWS IoT Coreと各AWSサービスの連携も行っており、より実運用に近いイメージでハンズオンが実施できる。
- AWS IoT Coreに連携されたデータを後続の各AWSサービス(AWS Lambda,Amazon S3)に連携する際にAmazon Kinesisサービスを用いてデータフローをより最適化している。
IoTデバイスとAWS IoT Coreが連携されたあと、より具体的には以下3つの機能を他AWSサービスと連携することで実現しています。
- Webアプリケーション(一番上の連携)
- ニアリアルタイムなデータの可視化(真ん中の連携)
- データレイク構築(一番下の連携)
IoTデバイス(Cloud9)のセットアップ
以下のようにCloud9を作成します。

Cloud9では以下のコマンドを順次実行します。
AWS IoT Device SDK Python v2をインストール
pip3 install --user awsiotsdk
必要なフォルダの作成と移動
mkdir -p ~/environment/dummy_client/certs/
cd ~/environment/dummy_client/
ダミーデバイス用のソースコードをダウンロード
wget https://awsj-iot-handson.s3-ap-northeast-1.amazonaws.com/aws-iot-core-workshop/dummy_client/device_main.py -O device_main.py
ちなみにこちらのダミーデバイス用のコードdevice_main.pyでは簡単には以下のような処理をしています。
- MQTTコネクション(IoTデバイスとAWS IoT Coreの間の通信プロトコル)を確立
- AWS IoT Coreへのダミーデータの送信
- AWS IoT Core側からのデバイス設定の変更を受け付ける
AWS IoT Coreのセットアップ
次にダミーデバイスと接続するAWS IoT Core側のセットアップです。
AWS IoTのエンドポイント確認
各セットアップの前に、ダミーデバイスとの接続の際に後々使うIoT Core側のエンドポイントを確認しておきます。AWS IoT>>Settingsから参照できます。

AWS IoTのログ設定
次にAWS IoTのログの設定を行います。INFOレベル以上のログがCloudWatchに配信されるように設定します。ロールは新規に作成します。

IoTポリシーの作成・設定
AWS IoT Core側にアタッチするポリシーを作成・設定します。AWS IoT>>Security>>Policiesから設定します。今回はハンズオン用なので、すべてのアクションを許可するポリシーを作成しています。

Things(モノ)の作成
このモノと呼ばれる部分ですが、AWS公式サイトでは以下のように説明されています。
"モノ" とは、特定のデバイスまたは論理エンティティを表します。物理的なデバイスやセンサー (電球や壁のスイッチなど) は、モノとして扱うことができます。
AWS IoT Core側から各デバイスなどを管理する際はこのモノという概念で管理していきます。ちなみに英語ではThingsですが、IoTを日本語ではモノのインターネットと訳すことが多いことからAWSではThingsをモノと呼んでいるんだと思います。
モノの名前を入力します。

次にデバイスシャドウでは「名前のないシャドウ(クラシック)」を選択します。デバイスシャドウにより、AWS IoT Coreと接続されたデバイスはその状態をAWS IoT Core側で管理する状態と同期することができます。以下のAWSの資料もわかりやすいです。



次にデバイス証明書を設定します。

(後ほど、ダミーデバイス側にも証明書を設定します。この設定によりデバイス側とAWS IoT Core側との間で認証が実施されます)
次にこちらの証明書を先ほど作成したPolicyにアタッチします。

その後上画像の「Create thing」をクリックすると画面がポップアップされるので、その画面から以下をダウンロードします。(但し、本ハンズオンではパブリックキーは利用しない)
- デバイス証明書
- パブリックキーファイル
- プライベートキーファイル
デバイスの設定
以降ではデバイスを起動し、AWS IoT Core側と接続していきます。
まずは先ほどダウンロードした証明書のプライベートキーファイルをCloud9側にアップロードします。

次にルートCA証明書をCloud9にダウンロードします。
cd ~/environment/dummy_client
wget https://www.amazontrust.com/repository/AmazonRootCA1.pem -O certs/AmazonRootCA1.pem
デバイスの起動
まずは以下のコマンドでデバイスを起動していきます。本コマンドを実行した時点で、このダミーデバイスはAWS IoT Core側と接続され、Pythonで記載されているようにメッセージを送信します。
cd ~/environment/dummy_client/
python3 device_main.py --device_name {ご自分の作ったモノ名} --endpoint {AWS IoTのendpoint_url}
device_main.pyでは以下のようにトピックが送信されています。BASE_TOPICにはdata/が入っています。

疎通の確認
ダミーデバイスから送信されているトピックを受信できているか、AWS IoT Core側で確認します。
AWS IoT>>Test>>MQTT test clientの画面で先ほどのTOPIC名を入力して受信(Subscribe)します。以下の画像のように、仮想的なデバイスから、クラウド(AWS IoT Core)へメッセージが送信されていることが確認できました。

デバイスシャドウの確認
次にAWS IoT Core側からデバイスを制御するために、先ほど作成したデバイスシャドウを用いて挙動を確認してみます。AWS Iot>>Manage>>Thingsからモノを選択し、Device Shadowsのタブをクリックし、作成したデバイスシャドウを選択するとDevice Shadow documentの画面が表示され、こちらのドキュメントを変更することで、デバイス側を制御できます。以下のように変更してみましょう。

reportedの値が5だったので、これまでは5秒間隔でメッセージが送信されていました。
desiredの値を2に変更したので、2秒間隔でメッセージを送信するよにデバイス側を操作しています。
先ほどと同じようにAWS IoT Coreの画面で受信メッセージを確認すると、timestampの間隔が2秒になっていることがわかります。

ここまででIoTデバイス(ダミーデバイス)とAWS IoT Coreとの基本的な接続やメッセージの送受信までの構築が完了しました!
IoTアプリケーションの作成
ここからはさらに深堀して、IoTデバイスとつながるアプリケーションの構築をしていきます。

Kinesis Data Streamsの作成
まずはKinesis Data Streamsの作成です。コンソールから簡単に作成できます。

DynamoDBの作成
DynamoDBもコンソールから作成します。テーブル名やパーティションキー、ソートキーなどは画像のように設定します。

IAMロールの設定
次にIAMロールを作成していきます。詳細な手順は公式ハンズオンを参照してください。今回は以下2つのロールを作成しました。
- Lambdaで利用するロール
-
AWSLambdaBasicExecutionRoleポリシー -
AmazonKinesisReadOnlyAccessポリシー -
AmazonDynamoDBFullAccessポリシー
-
- AWS IoT用のロール
-
AWSIoTThingsRegistrationポリシー -
AWSIoTLoggingポリシー -
AWSIoTRuleActionsポリシー
-
Lambdaの設定
python3.8でLambdaを作成していきます。Lambdaのトリガーには上記で作成したKinesis Data Streamsを設定します。

Lambdaの中身はハンズオンで用意されているこちらのコードを利用します。コードの中身で環境変数からDynamoDBのテーブル名を取得している箇所があるので、以下のように環境変数を設定します。

AWS IoT Core の設定
次にAWS IoT Coreの設定を実施し、AWS IoT Coreで受信するデータをKinesis Data Streamsに受け渡しできるよにします。AWS IoT>>Message routing>>Rulesからルールを以下のように作成します。こちらのルールもSQLライクのステートメントで記述できるので、とても使いやすいと感じました。

ちなみにこちらのRulesでは以下のように多様なAWSサービスとネイティブに統合できます。この辺りの各サービス間での接続のしやすさもAWSの使いやすいポイントだと思います。

ここまででダミーデバイスから送信されるメッセージをDynamoDBに格納するまでの部分が構築できました。各サービスのMonitoringから想定通りに動いていることも確認できました(確認部分は記事では割愛)。
API用のLambdaの設定
次にWebブラウザからコールされるAPI用のLambdaを設定していきます。このLambdaではDynamoDBに格納されている、ダミーデバイスからの情報を返却します。こちらのLambdaのコードも公式ハンズオンにて用意されているコードを利用していきます。先ほどのLambdaと同じように、環境変数にDynamoDBのテーブル名をセットして完了です。
API Gatewayの設定
APIGatewayの詳細な設定方法は公式ハンズオンから参照してください。RESTで上記で作成したLambdaを呼び出すAPIをデプロイすればOKです。

公式ハンズオンで用意されているhtmlファイルにAPI先を指定してページを開くと、以下のようにDynamoDBの中身を参照できることが確認できました!APIが挙動しています。

ニアリアルタイムなデータの可視化
Amazon OpenSearch Serviceを利用したこちらのハンズオン部分は、用意されているCloudFormationテンプレートを実行してスタックを作成していく流れになります。本記事では内容は割愛し、詳細は公式ハンズオンを参照ください。
データレイクの作成
ダミーデバイスから送信されるデータを溜めていくデータレイクを作成していきます。

尚、AWS IoT Coreから直接Amazon S3にデータを格納するような構成も可能ですが、データを数分おきにまとめて格納したり、圧縮してデータを格納したりするなどの設定がAmazon Kinesis Firehoseを挟むことで簡単じに実装できます。
S3バケットの作成
Kinesis Data Firehoseの設定
Amazon Kinesis>>Delivery streamsから作成していきます。

Bufferの設定や圧縮なども簡単に設定できます。

IoT ルールの作成
Kinesis Data Firehoseにメッセージを受け渡すルールをAWS IoT Coreに設定していきます。既存のKinesis Streamに加えて、Kinesis FIrehose streamへのアクションをルールに追加しました。

動作確認
S3バケットを確認すると、gzで圧縮されたデータが溜められているのが確認できました!データレイクも構築完了です。

おわりに
本ハンズオンを通して、AWS IoT Coreの基本的な使い方だけでなく、AWS IoT Coreと接続したWebアプリケーションの構築方法やデータレイクの構築方法なども具体的なイメージとともに学習できました。IoTアプリケーションと聞くと、業務アプリケーションと比べて難易度が高いイメージがありましたが、AWSの各サービスを連携して構築できることが実体験を通して理解できたのが何より大きかったです。
