[AWS IoT] Kinesis Firehoseに連携しLambdaまで繋げてみる – (2)AWS IoTの設定と動作確認
はじめに
前回からの続きです。今回はAWS IoTで受信したメッセージをKinesis Firehoseに渡す設定について書きたいと思います。
AWS IoTの設定
1.Thingの作成
最初にThingを作成します。これはコマンド一つです。
$ aws iot create-thing --thing-name t-honda-iot-thing { "thingArn": "arn:aws:iot:us-west-2:XXXXXXXXXXXX:thing/t-honda-iot-thing", "thingName": "t-honda-iot-thing" }
2.証明書の作成とキーの保存
証明書を作成し、キーを保存します。まずは証明書の作成し、後ほど使用するため結果をcert.jsonに出力します。
$ aws iot create-keys-and-certificate --set-as-active > cert.json
cert.json
{ "certificateArn": "XXXXXX", "certificatePem": "-----BEGIN CERTIFICATE-----\nXXXXXXXXX\n-----END CERTIFICATE-----\n", "keyPair": { "PublicKey": "-----BEGIN PUBLIC KEY-----\nXXXXXXXXXX\n-----END PUBLIC KEY-----\n", "PrivateKey": "-----BEGIN RSA PRIVATE KEY-----\nXXXXXXXXXX\n-----END RSA PRIVATE KEY-----\n" }, "certificateId": "XXXXXXXXXX" }
出力したcert.jsonよりPublicキー、Privateキーを取得します。Publicキーについては「iot_public_key.pem」というファイルを作成し、「keyPair」の「PublicKey」に書かれている値をコピーして保存します。Privateキーについては「iot_private_key.pem」というファイルを作成し、「PrivateKey」に書かれている値をコピーして保存します。
3.ポリシーの作成
ポリシーを作成します。ポリシーの詳細はiot_policy.jsonに記述しています。
$ aws iot create-policy --policy-name t-honda-iot-policy --policy-document file://iot_policy.json { "policyName": "t-honda-iot-policy", "policyArn": "arn:aws:iot:us-west-2:XXXXXXXXXXXX:policy/t-honda-iot-policy", "policyDocument": "{\n \"Version\": \"2012-10-17\", \n \"Statement\": [{\n \"Effect\": \"Allow\",\n \"Action\":[\"iot:*\"],\n \"Resource\": [\"*\"]\n }]\n}", "policyVersionId": "1" }
iot_policy.json
{ "Version": "2012-10-17", "Statement": [{ "Effect": "Allow", "Action":["iot:*"], "Resource": ["*"] }] }
4.証明書の紐付け
証明書をポリシーとThingに紐づけます。まずはポリシーとの紐付けです。以下のコマンドを実行し、--principalには作成した証明書のArnを、--policy-nameにはポリシーの名称を渡します。
$ aws iot attach-principal-policy --principal arn:aws:iot:us-west-2:XXXXXXXXXXXX:cert/XXXXXXXXXXXXXXXXXXXXX --policy-name t-honda-iot-policy
次にThingとの紐付けです。以下のコマンドを実行し、--thing-nameにはThingの名称を、--principalには作成した証明書のArnを渡します。
$ aws iot attach-thing-principal --thing-name t-honda-iot-thing --principal arn:aws:iot:us-west-2:XXXXXXXXXXXX:cert/XXXXXXXXXXXXXXXXXXXXX
5.ロールの作成
AWS IoTを実行するためのロールを作成します。
$ aws iam create-role --role-name t-honda-iot-role --assume-role-policy-document file://iot_assume_role_policy.json { "Role": { "AssumeRolePolicyDocument": { "Version": "2012-10-17", "Statement": [ { "Action": "sts:AssumeRole", "Principal": { "Service": "iot.amazonaws.com" }, "Effect": "Allow", "Sid": "" } ] }, "RoleId": "XXXXXXXXXXXXXXXXXXXX", "CreateDate": "2016-02-11T04:39:40.374Z", "RoleName": "t-honda-iot-role", "Path": "/", "Arn": "arn:aws:iam::XXXXXXXXXXXX:role/t-honda-iot-role" } }
iot_assume_role_policy.json
{ "Version": "2012-10-17", "Statement": [ { "Sid": "", "Effect": "Allow", "Principal": { "Service": "iot.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }
作成したロールにロールポリシーを付与します。ロールポリシーの詳細はiot_role_policy.jsonに定義し、Kinesis FirehoseへPutする権限を付与します。
aws iam put-role-policy --role-name t-honda-iot-role --policy-name t-honda-iot-role-policy --policy-document file://iot_role_policy.json
iot_role_policy.json
{ "Version": "2012-10-17", "Statement": { "Effect": "Allow", "Action": "firehose:PutRecord", "Resource": "arn:aws:firehose:us-west-2:XXXXXXXXXXXX:deliverystream/t-honda-kinesis-to-s3" } }
6.ルールの作成
ルールを作成します。iot_topic_rule_payload.jsonに詳細は定義し、「sql」では取得した全件を送信すること、送信先には前回作成したKinesis Firehoseの名称を指定します。
$ aws iot create-topic-rule --rule-name t_honda_iot_rule --topic-rule-payload file://iot_topic_rule_payload.json
iot_topic_rule_payload.json
{ "sql": "select * from 'topic'", "description": "", "actions": [ { "firehose": { "roleArn": "arn:aws:iam::XXXXXXXXXXXX:role/t-honda-iot-role", "deliveryStreamName": "t-honda-kinesis-to-s3" } } ], "ruleDisabled": false }
以上でAWS IoTの設定ができました。
動作確認
実際に動作を確認してみます。IoT端末の代わりとしてruby-mqttを使用します。
1.ruby-mqttで実行するソース
以下のRubyスクリプトでruby-mqttよりAWS IoTにメッセージを送信します。
publish_firehose.rb
require "mqtt" require "json" hash = { timestamp: Time.now.strftime("%Y-%m-%d %H:%M:%S"), column1: "100", column2: "200", column3: "300" } MQTT::Client.connect(host: "XXXXXXXXXX.iot.us-west-2.amazonaws.com", port: 8883, ssl: true, cert_file: "./pems/iot_cert.pem", key_file: "./pems/iot_private_key.pem", ca_file: "rootCA.pem") do |client| client.publish("topic", hash.to_json) end
cert_file、key_fileは上記の証明書作成時に作成したpemを指定してください。またルート証明書を以下のコマンドで取得し、ca_fileとして指定します。
$ wget https://www.symantec.com/content/en/us/enterprise/verisign/roots/VeriSign-Class%203-Public-Primary-Certification-Authority-G5.pem -O rootCA.pem
2.動作を確認する
以下のコマンドでRubyスクリプトを実行します。
$ bundle exec ruby publish_firehose.rb
S3のバケットにファイルが出力されていることを確認します。
ファイルの内容
{"timestamp":"2016-02-11 15:03:59","column1":"100","column2":"200","column3":"300"}
LambdaのログをCloudWatchにて確認します。
IoTクライアントから送信したメッセージがLambdaに届いたことが確認できました。
まとめ
前回と今回とでAWS IoT → Kinesis Firehose → S3 → Lambdaとメッセージを伝える仕組みを作る事ができました。LambdaではJavaのプログラムを実行しているため、データの加工やRedshiftへの登録など色々と応用ができるかと思います。AWS IoTを使用した案件などで何かの助けになれば幸いです。
参考サイト
[新機能]Amazon Kinesis FirehoseでS3にデータを送ってみた #reinvent
AWS LambdaのファンクションをJavaで書く(S3イベント処理編)
ステップ 3: イベントソースを追加する(イベントを発行するように Amazon S3 を設定する)
イベント通知の有効化
Providing AWS Credentials in the AWS SDK for Java
AWS IoTとRuby製MQTTクライアントでPub/Subしてみた