Amazon Web Services

2017/06/11更新

以下の記事でAWS IoTを使ったセンシングデータのSNS通知手順を示したが、AWS IoTの設定をGUI(ダッシュボード)でなくCLIで行う手順を示す。AWS IoT以外の設定は変わらないので割愛する。

関連資料・記事

Amazon SNS

Topic作成
% aws sns create-topic --name "mqtt_test"
{
    "TopicArn": "arn:aws:sns:ap-northeast-1:xxxxxxxxxxxx:mqtt_test"
}
通知先(Email)設定
% aws sns subscribe --topic-arn "arn:aws:sns:ap-northeast-1:xxxxxxxxxxxx:mqtt_test" --protocol email --notification-endpoint "xxx@yyy.com"
{
    "SubscriptionArn": "pending confirmation"
}

確認用のメールが届くので「Confirm subscription」をクリックしてこのメールアドレスを有効にするか、「Confirm subscription」のURLからToken="******"部分を抜き出してCLIで有効化する。

% aws sns confirm-subscription --topic-arn "arn:aws:sns:ap-northeast-1:xxxxxxxxxxxx:mqtt_test" --token "*******************************************"
{
    "SubscriptionArn": "arn:aws:sns:ap-northeast-1:xxxxxxxxxxxx:mqtt_test:************************************"
}

AWS IoT

ArduinoをThingとして登録
aws iot create-thing --thing-name "Arduino"
{
    "thingArn": "arn:aws:iot:ap-northeast-1:xxxxxxxxxxxx:thing/Arduino",
    "thingName": "Arduino"
}
センシングデータを処理するルールを設定

最初にルールにひも付けるIAMロールを作成する。

% vi role.json
{
  "Version":"2012-10-17",
  "Statement":[{
    "Effect": "Allow",
    "Principal": {
      "Service": "iot.amazonaws.com"
    },
    "Action": "sts:AssumeRole"
  }]
}

% aws iam create-role --role-name "mqtt_test_role" --assume-role-policy-document file://role.json
{
    "Role": {
        "AssumeRolePolicyDocument": {
            "Version": "2012-10-17",
            "Statement": [
                {
                    "Action": "sts:AssumeRole",
                    "Effect": "Allow",
                    "Principal": {
                        "Service": "iot.amazonaws.com"
                    }
                }
            ]
        },
        "RoleId": "*********************",
        "CreateDate": "2017-06-10T04:29:40.209Z",
        "RoleName": "mqtt_test_role",
        "Path": "/",
        "Arn": "arn:aws:iam::xxxxxxxxxxxx:role/mqtt_test_role"
    }
}

ロールが作成できたらルールを作成してひも付ける。

% vi rule.json
{
  "sql": "SELECT * FROM 'topic/test'",
  "ruleDisabled": false,
  "actions": [{
    "sns": {
      "targetArn": "arn:aws:sns:ap-northeast-1:xxxxxxxxxxxx:mqtt_test",
      "roleArn": "arn:aws:iam::xxxxxxxxxxxx:role/mqtt_test_role"
    }
  }]
}

% aws iot create-topic-rule --rule-name "sendEmail" --topic-rule-payload file://rule.json
ポリシーを作成
% vi policy.json
{
    "Version": "2012-10-17",
    "Statement": [{
        "Effect": "Allow",
        "Action": ["iot:*"],
        "Resource": ["*"]
    }]
}

% aws iot create-policy --policy-name "mqtt_policy" --policy-document file://policy.json
{
    "policyName": "mqtt_policy",
    "policyArn": "arn:aws:iot:ap-northeast-1:xxxxxxxxxxxx:policy/mqtt_policy",
    "policyDocument": "{\n    \"Version\": \"2012-10-17\",\n    \"Statement\": [{\n        \"Effect\": \"Allow\",\n        \"Action\": [\"iot:*\"],\n        \"Resource\": [\"*\"]\n    }]\n}\n",
    "policyVersionId": "1"
}
デバイス証明書の作成と有効化
% aws iot create-keys-and-certificate --set-as-active --certificate-pem-outfile cert.pem --private-key-outfile thing-private-key.pem
{
    "certificateArn": "arn:aws:iot:ap-northeast-1:xxxxxxxxxxxx:cert/********************************",
    "certificatePem": "-----BEGIN CERTIFICATE-----\n******\n-----END CERTIFICATE-----\n",
    "keyPair": {
        "PublicKey": "-----BEGIN PUBLIC KEY-----\n******\n-----END PUBLIC KEY-----\n",
        "PrivateKey": "-----BEGIN RSA PRIVATE KEY-----\n******\n-----END RSA PRIVATE KEY-----\n"
    },
    "certificateId": "********************************************************"
}
ポリシーおよびThingをデバイス証明書にアタッチ
% aws iot attach-principal-policy --policy-name "mqtt_policy" --principal "arn:aws:iot:ap-northeast-1:xxxxxxxxxxxx:cert/****************************************************************"

% aws iot attach-thing-principal --thing-name "Arduino" --principal "arn:aws:iot:ap-northeast-1:xxxxxxxxxxxx:cert/****************************************************************"

参考サイト

2017/06/09更新

AWS IoTでMQTTブローカーを作り、ArduinoでセンシングしたデータをPub/Sub通信してAmazon SNSでメール通知する手順を示す。

データの流れは以下の通り。

作業の流れは以下のようになる。

Amazon SNS

Topic作成
通知先(Email)設定

AWS IoT

ArduinoをThingとして登録
センシングデータを処理するルールを設定
ポリシーを作成
デバイス証明書の作成と有効化
ポリシーおよびThingをデバイス証明書にアタッチ

ここではAWS IoTの設定はGUI(ダッシュボード)を使う。CLIを使った場合の手順は以下に示す。

関連資料・記事

Arduino

センシング用の回路を作成
Arduinoでセンシングを行いAWS IoT上のMQTTブローカーにPublishするプログラムを用意

テスト

尚ここで使用するArduinoはUNOとするが、直接IP通信ができないため母艦としてLinux(Ubuntu 16.04)を使用し、Pub/Sub通信やセンシングを行うプログラムはRubyで作成する。

Amazon SNS

まずセンサーデータを通知する通知先を作成する。手順としては最初にTopicを作成してそれに実際のメールアドレスをひも付ける。

Topic作成

Amazon SNSのダッシュボードから[Topics] > [Create new topic]をクリックし、Topic nameに任意の名前を付けてTopicを作成する。(ここでは「mqtt_test」とする)

メールアドレスのひも付け

作成したTopicにチェックを付け[Actions] > [Subscribe to topic]をクリックする。

Protocolを「Email」としてEndpointに通知先のメールアドレスを指定する。

確認用のメールが届くので「Confirm subscription」をクリックしてこのメールアドレスを有効にする。

ダッシュボードの[Subscriptions]をクリックすると通知先が作成されているのが確認できる。

AWS IoT

通知先が作成できたらAWS IoTの設定に移る。

流れとしてはまずAWS IoT上にArduinoをThingとして登録し、次にセンシングデータを処理するルールを設定したうえでデバイス証明書とポリシーを作成してArduinoにひも付ける。

Thing作成

AWS IoTのダッシュボードから[Registry] > [Things]をクリックして[Create]をクリックする。

Thingに任意の名前を付けて[Create thing]をクリックする。(ここでは「Arduino」とする)

センシングデータを処理するルールを設定

[Rules]をクリックして[Create]をクリックする。

ルールに任意の名前を付け(ここでは「sendEmail」とする)、Message source欄のAttributeに取得対象として全てのデータを表す「*」を、Topic filterに購読するトピック(ここでは「topic/test」とする)をそれぞれ指定して[Add action]をクリックする。

アクションを選択する画面が表示されるので「Send a message as an SNS push notification」を選択し[Configure action]をクリックする。

「SNS target」で先ほど作成したTopic(ここでは「mqtt_test」)を選択し、「IAM role name」で[Create a new role]をクリックする。

IAMロール名を入力できるようになるので任意の名前を付け(ここでは「mqtt_test_role」とする)、[Create a new role]をクリックする。

「Configure action」画面に戻るので[Add action]をクリックする。

「Create a rule」画面で[Create rule]をクリックするとアクションが作成され、ルールの作成が完了する。

ポリシー作成

[Security] > [policies]をクリックし、[Create]をクリックする。

Nameに任意のポリシー名を入力し(ここでは「mqtt_policy」とする)、Thingからの操作を全て許可することとして[Action]に「iot:*」、[Resource ARN]に「*」を入力して[Effect]の[Allow]をチェックして[Create]をクリックする。これでポリシーが作成される。

デバイス証明書作成

[Security] > [Certificates]をクリックし、[Create]をクリックする。

一番上の[Create certificate]をクリックする。

証明書と鍵ペアが作成されるのでこのうち証明書(A certificate for this thing: xxxxx.cert.pem)と秘密鍵(A private key: xxxxx.private.key)をダウンロードして[Activate]をクリックする。これで証明書が有効になる。

ルート証明書も必要になるので入手しておく。この作業はAWS IoTのコンソールでできないのでコマンドで実行する。

% wget https://www.symantec.com/content/en/us/enterprise/verisign/roots/VeriSign-Class%203-Public-Primary-Certification-Authority-G5.pem -O rootCA.pem

ポリシーおよびThingをデバイス証明書にアタッチ

[Security] > [Certificates]をクリックし、先ほど作成した証明書の「・・・」をクリックして[Attach policy]を選択する。

作成済ポリシーをチェックして[Attach]をクリックする。

同様に先ほど作成した証明書の「・・・」をクリックして[Attach thing]を選択する。

作成済Thingをチェックして[Attach]をクリックする。

Arduino

AWS IoTの設定が終わったら残りはArduino側の設定となる。

Arduino IDEを動かす母艦はUbuntu 16.04とする。

最初にArduinoにセンサーを接続してセンシングを行う回路を作成する。ここでは温度センサーを使って室温を計測することとする。

またArduinoの母艦となるOS(ここではUbuntu 16.04)上にAWS IoTのMQTTブローカーに対してSubscribeを行うプログラムとセンサーからのデータを取得してPublishするプログラムをそれぞれ用意する。言語はここではRubyを使用する。

センシング用の回路を作成

温度センサーとして精度はあまり高くないものの安価に調達できるLM61BIZを使用する。

センサーのピンは3つで刻印面に向かって左から

+Vs(電源電圧)
Vout(出力電圧)
GND(グランド)

という配列になっているのでこれをArduinoの5V、A0、GNDにそれぞれ接続する。

結線イメージは以下のようになる。

関連資料・記事

Arduinoでセンシングを行いAWS IoT上のMQTTブローカーにPublishするプログラムを用意

まずRubyからArduinoを操作するためのarduino_firmataパッケージと、MQTTのPub/Sub通信を行うためのmqttパッケージをインストールする。

% sudo gem install arduino_firmata
% sudo gem install mqtt

次に温度センサーからの値を1秒おきに取得して値を温度に変換したうえで前回取得値と異なる場合はAWS IoT上のMQTTブローカーにPublishするプログラムを用意する。

% vi pub.rb
require 'rubygems'
require 'arduino_firmata'
require 'mqtt'

arduino = ArduinoFirmata.connect "/dev/ttyACM0"

client = MQTT::Client.connect(
           host: '<Thing ARN>',
           port: 8883,
           ssl: true,
           cert_file: '<証明書ファイル>',
           key_file: '<秘密鍵ファイル>',
           ca_file: 'rootCA.pem')

before_temp = 0

while true
  temp = arduino.analog_read 0
  temp = ((temp.to_f * 5 / 1024) - 0.6) * 100
  temp = temp.round
  if before_temp != temp
    puts temp
    before_temp = temp
    client.publish('topic/test', "temp = #{temp}")
  end
  sleep 1
end

arduino.close

関連資料・記事

テスト

上記で用意したプログラムを実行すると、温度が変わる度にAWS IoT上のMQTTブローカーに温度が送信(Publish)される。

% ruby pub.rb
22
22
22
23 <- 温度センサーに手を触れて温度を変化させる
23
23

AWS IoTはこのデータを受け取るとルール設定に従ってAmazon SNS経由でメール通知を行う。通知先には以下のようなメールが届く。

今回はデバイスから取得したデータをアウトプットするまでの一連の動きを見るためにシンプルな実装を行ったが、AWS IoTでは他にも目的に応じて様々な制御が可能である。

参考サイト

2017/7/10更新

対応バージョン: 10.12.5

macOS SierraにAWS CLI環境を構築する手順を示す。

準備

最初にMac App StoreからXcodeをインストールしておく。

AWS CLIインストール

AWS CLIのインストールにはPythonのパッケージマネージャであるpipコマンドを使用するのでpip -> AWS CLIの順でインストールする。

pipインストール
% sudo easy_install pip

% pip --version
pip 9.0.1 from /Library/Python/2.7/site-packages (python 2.7)
awscliインストール
% pip install awscli --upgrade --user

PATH環境変数に以下のパスを追加
$HOME/Library/Python/2.7/bin

% aws --version
aws-cli/1.11.117 Python/2.7.10 Darwin/16.6.0 botocore/1.5.80

JSON Lintインストール

AWS CLIにおけるJSONデータの表示・加工に便利なJSON Lintをインストールする。

JSON LintのインストールにはNode.js付属のnpmコマンドを使用するのでNode.js -> JSON Lintの順でインストールする。

nodebrewインストール
% curl https://raw.githubusercontent.com/hokaccha/nodebrew/master/nodebrew | perl - setup

PATH環境変数に以下のパスを追加
$HOME/.nodebrew/current/bin

% nodebrew selfupdate
Node.jsインストール
% nodebrew install latest

PATH環境変数に以下のパスを追加
$HOME/.nodebrew/node/v8.1.3/bin

% node -v
v8.1.3

% npm -v
5.0.3
JSON Lintインストール
% npm install jsonlint

PATH環境変数に以下のパスを追加
$HOME/node_modules/.bin

% jsonlint -v
1.6.2

% echo '{"key":"value"}' | jsonlint
{
  "key": "value"
}

初期設定

Access KeyとSecret Access Keyを設定してAWS CLIが使用できるようにする。

% aws configure list
      Name                 Value          Type  Location
      ----                 -----          ----  --------
   profile             <not set>          None  None
access_key             <not set>          None  None
secret_key             <not set>          None  None
    region             <not set>          None  None

% aws configure
AWS Access Key ID [None]: xxxxxxxxxxxxxxxxxx
AWS Secret Access Key [None]: xxxxxxxxxxxxxxxxxx
Default region name [None]: ap-northeast-1 <- 東京リージョンの場合
Default output format [None]: json <- 他にtable、textが指定可能。好みに応じて指定

% aws configure list
      Name                 Value          Type  Location
      ----                 -----          ----  --------
   profile             <not set>          None  None
access_key  ******************** shared-credentials-file
secret_key  ******************** shared-credentials-file
    region        ap-northeast-1   config-file  ~/.aws/config

設定は以下の2ファイルに格納されるが、それぞれのファイルの[default]の部分に一意の名前を付ければ複数の設定(プロファイル)を共存させられる。その場合、awsコマンドを実行する時に--profileに続けてプロファイル名を指定する。

$HOME/.aws/config

コマンド出力結果フォーマットとリージョン

[default]
output = json
region = ap-northeast-1
$HOME/.aws/credentials

認証情報

[default]
aws_access_key_id = xxxxxxxxxxxxxxxxxx
aws_secret_access_key = xxxxxxxxxxxxxxxxxx

動作確認

インスタンス一覧取得
% aws ec2 describe-instances | jq '.Reservations [] .Instances [] .InstanceId'
インスタンス起動
% aws ec2 start-instances --instance-ids i-xxxxxxxxxxxxxxxxx
インスタンス停止
% aws ec2 stop-instances --instance-ids i-xxxxxxxxxxxxxxxxx
インスタンス削除
% aws ec2 terminate-instances --instance-ids i-xxxxxxxxxxxxxxxxx
IAMユーザ取得
% aws iam list-users
{
    "Users": [
        {
            "UserName": "dev", 
            "Path": "/", 
            "CreateDate": "2017-07/10T04:34:38Z", 
            "UserId": "xxxxxxxxxxxxxxxxxxxxx", 
            "Arn": "arn:aws:iam::xxxxxxxxxxxx:user/dev"
        }
    ]
}

% aws iam get-user --query 'User.Arn'
"arn:aws:iam::xxxxxxxxxxxx:user/dev"

参考サイト

2017/08/12更新

対応バージョン: Aurora(MySQL-Compatible) 5.6.10a

Amazon Auroraで出力されるログはデフォルトで以下の3種類がある。
error/mysql-error-running.log{,.YYYY-MM-DD.nn}
error/mysql-error.log
external/mysql-external.log

Auroraではこれに加え、クエリログ(general_log)とスロークエリログ(slow_query_log)も出力することができる。

手順は以下の通りで、パラメータグループで設定することができる。尚、これら設定はAuroraインスタンスを再起動することなく動的に反映可能である。(反映にかかる時間は10秒程度)

出力先

まずログの出力先(log_output)がデフォルトで"TABLE"になっているので"FILE"に変更する。

続いて各ログの出力設定を行う。片方だけの設定も両方の設定もどちらも可能である。

クエリログ(general_log)

general_logの値を1(ON)に設定する。デフォルトは0(OFF)。

これにより以下のログが新たに出力されるようになる。

general/mysql-general.log

スロークエリログ(slow_query_log)

slow_query_logを1(ON)に設定する。デフォルトは0(OFF)。

さらにクエリが何秒以上かかった時にログを出力させるかをlong_query_timeで設定する。デフォルトは10(秒)で、0(秒)にすると遅延ありなしに関係なく全てのクエリがログに出力されるようになる。

これにより以下のログが新たに出力されるようになる。

slowquery/mysql-slowquery.log

参考サイト