AWS IoT に送られたデータを Firehose 経由で S3 に保存する

AWT IoT に送ったメッセージをS3に保存する際の設定について備忘録として残しておく。

メッセージ単位でファイルが作成されても管理に困るので、一定期間内に送られたメッセージを1つのファイルにまとめて保存し、時間経過と共にファイルを変えていくということをする。

基本的な流れは、AWS IoTで受信したメッセージを Firehose に送り、Firehoseに送られたデータを一定期間もしくは一定容量毎にS3のファイルに保存する。

ここでは、CO2センサーMH-z19の値をAWS IoTに送る に示したプログラムからのメッセージを対象とする。プログラムでは、次のトピックに測定データを送る。

iot/MACアドレス/update

MACアドレス部分はESP32のMACアドレスをC風の16進表記したものである。次がMACアドレス部を示した例である。

iot/0x30aea40b5cc4/update

ちなみに、上記のプログラムでは、次のトピックをsubscribeしてコマンド(リセット)を受け付ける。

iot/MACアドレス/control

S3の設定

メッセージを保存するファイルのためのバケットをあらかじめ作成しておくとする。

ここでは、iot.kunsen.net というバケットを作成する。

「+バケットを作成する」ボタンをクリックして作成を開始する。

バケット名に iot.kunsen.net を指定してから、「次へ」ボタンをクリックする。

必要に応じてプロパティに変更を加える。ここでは変更なしとしている。

「次へ」ボタンをクリックして次に進む。

設定の確認ができたら「バケットを作成」ボタンをクリックして作成する。

バケットが作成できれば次のような画面で確認できる。

AWS IoTの設定1

AWS IoT コンソールで ACT を選択する。

ルールを作成する。WriteAllToS3 というルール名とする。

トピックフィルターに iot/# を指定し、属性にはすべてという意味の * を指定する。

iot/# によってiot で始まるトピック名すべてが対象になるので、MACアドレスはなんであっても対象になる。特定のデバイスのみを対象にしたい場合には、MACアドレス部まで指定するようにすれば良い。たとえば iot/0x30aea40b5cc4/# とするか、トピック全体を指定してiot/0x30aea40b5cc4/update とする。

アクションとして「Amazon Kinesis Firehose ストリームにメッセージを送信する」を選択する。

ストリームを新規生成する場合(あらかじめ作成していない場合)には、「新しいリソースを作成する」ボタンをクリックしてFirehoseストリームを作成する。

Firehoseの設定

以下は初めてFirehoseのストリームを作成する場合である。

「Create Delivery Stream」ボタンをクリックしてストリームの作成を開始する。

Step 1: Name and source

作成する新しいDelivery Stream Nameを iot.to.S3 とする。

Source には、「Direct PUT or other sources」を選ぶ。

Nextボタンをクリックして次に進む。

Step 2: Process records

今回は単純に受信したデータを保存するだけなので、Transform source records with AWS Lambda の Record transformation は Disable としておく。

同様に、Convert record formatもDisableにする。

Next ボタンをクリックして次に進む。

Step 3: Choose destination

Select destination のDestination には、Amazon S3を選択する。

ここではメッセージを保存する S3 bucket が作成済みで iot.kunsen.net であるとする。

Prefix は、iotlog とする。

Step 4: Configure settings

Configure settingsは、ここではデフォルトを基本とする。

S3 buffer conditions の Buffer size は 5MB とし、このサイズを超えたら新しいファイルに保存されるようになる。Buffer interval は 300 seconds とし、5分毎に新しいファイルに保存されるようにする。

S3 compression and encryption は Disable とする。

Error logging は、不要ならば Disableとする。

IAM roleを設定するために Create new or choose ボタンをクリックする。

IAM Role設定

新しい IAM Role を作成するとする。

ロール名を iot_to_S3_firehose_delivery_role とする。

Nextボタンをクリックしてロールを作成する。

Configure settingsの完了

IAM Role の作成が終わると Configure settings の画面に戻るので、Nextボタンをクリックして次に進む。

Step 5: Review

設定の確認を行う。

確認ができたら Create Delivery Stream ボタンをクリックして、ストリームを作成する。

作成中は次のような画面になる。

作成が完了すると次のような画面になる。

以上で Firehose の設定ができたので、AWS IoT の設定に戻る。

AWS IoTの設定2

ストリームにはこれまでに作成した IoT-to-S3 を指定する。

区切り記号にはここでは Windows を選択する。他の区切りが良い場合には他の選択肢を選ぶ。

次に、Kinesis Firehose へのアクセスのためのロールの設定が必要となる。ここでは、そのようなロール設定が事前にされておらず、ここで作成とする。

IAM ロール名は IoT-to-firehose-access-role とする。

「新しいロールの作成」ボタンをクリックしてロールを作成する。

作成が終わったら、そのロールを 「このアクションを実行するためのAmazon Kinesis Firehose リソースへのAWS IoT アクセスを付与するロール」に選ぶ。

アクションの追加ボタンをクリックしてAWS IoTのアクション設定を行う。

アクション設定ができれば、次のような画面で確認ができる。

ルールの作成ボタンをクリックしてルールを作成する。

作成が終わると次のような画面で確認ができる。

動作確認

CO2センサーMH-z19の値をAWS IoTに送る に示したプログラムを動作させておくとS3にメッセージが保存されていく。

上記の設定では300秒経過しないとファイルが作成されないので、最初は少し待つ必要がある。

しばらくたってからS3 のコンソールから見ると次のようにファイルが追加されているのがわかる。

ファイルには次のようなメッセージが含まれる。

{"CO2":474,"Temperature":26,"Type":"MH-z19","Timestamp":"2018-08-14T16:17:18+09:00","MAC":"0x30aea40b5cc4"}
{"CO2":475,"Temperature":26,"Type":"MH-z19","Timestamp":"2018-08-14T16:17:34+09:00","MAC":"0x30aea40b5cc4"}
{"CO2":478,"Temperature":26,"Type":"MH-z19","Timestamp":"2018-08-14T16:17:50+09:00","MAC":"0x30aea40b5cc4"}
{"CO2":475,"Temperature":26,"Type":"MH-z19","Timestamp":"2018-08-14T16:18:06+09:00","MAC":"0x30aea40b5cc4"}
{"CO2":470,"Temperature":26,"Type":"MH-z19","Timestamp":"2018-08-14T16:18:22+09:00","MAC":"0x30aea40b5cc4"}
{"CO2":468,"Temperature":26,"Type":"MH-z19","Timestamp":"2018-08-14T16:18:38+09:00","MAC":"0x30aea40b5cc4"}
{"CO2":464,"Temperature":26,"Type":"MH-z19","Timestamp":"2018-08-14T16:18:54+09:00","MAC":"0x30aea40b5cc4"}
{"CO2":468,"Temperature":26,"Type":"MH-z19","Timestamp":"2018-08-14T16:19:10+09:00","MAC":"0x30aea40b5cc4"}
{"CO2":467,"Temperature":26,"Type":"MH-z19","Timestamp":"2018-08-14T16:19:26+09:00","MAC":"0x30aea40b5cc4"}
{"CO2":468,"Temperature":26,"Type":"MH-z19","Timestamp":"2018-08-14T16:19:42+09:00","MAC":"0x30aea40b5cc4"}
{"CO2":464,"Temperature":26,"Type":"MH-z19","Timestamp":"2018-08-14T16:19:58+09:00","MAC":"0x30aea40b5cc4"}
{"CO2":461,"Temperature":26,"Type":"MH-z19","Timestamp":"2018-08-14T16:20:14+09:00","MAC":"0x30aea40b5cc4"}
{"CO2":463,"Temperature":26,"Type":"MH-z19","Timestamp":"2018-08-14T16:20:30+09:00","MAC":"0x30aea40b5cc4"}
{"CO2":466,"Temperature":26,"Type":"MH-z19","Timestamp":"2018-08-14T16:20:46+09:00","MAC":"0x30aea40b5cc4"}
{"CO2":465,"Temperature":26,"Type":"MH-z19","Timestamp":"2018-08-14T16:21:02+09:00","MAC":"0x30aea40b5cc4"}
{"CO2":464,"Temperature":26,"Type":"MH-z19","Timestamp":"2018-08-14T16:21:18+09:00","MAC":"0x30aea40b5cc4"}
{"CO2":468,"Temperature":26,"Type":"MH-z19","Timestamp":"2018-08-14T16:21:34+09:00","MAC":"0x30aea40b5cc4"}
{"CO2":468,"Temperature":26,"Type":"MH-z19","Timestamp":"2018-08-14T16:21:50+09:00","MAC":"0x30aea40b5cc4"}
{"CO2":467,"Temperature":26,"Type":"MH-z19","Timestamp":"2018-08-14T16:22:06+09:00","MAC":"0x30aea40b5cc4"}