この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
はじめに
前回からの続きです。今回は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してみた