Device SDK の実装は適切か?
例 : AWS IoT Device SDK Python v2 (awsiotsdk==1.5.6)
実装例 (QoS1)
デバイス
AWS IoT Core
…
connect_future = mqtt_connection.connect() connect_future.result()
…
mqtt_connection.publish(
topic=”my/topic",
payload=’{“hello”: “world”}’, qos=mqtt.QoS.AT_LEAST_ONCE, )
…
connect_future = mqtt_connection.connect() connect_future.result()
…
publish_future, _ = mqtt_connection.publish(
topic=”my/topic",
payload=’{“hello”: “world”}’, qos=mqtt.QoS.AT_LEAST_ONCE, ) publish_future.result(timeout=5)
QoS=1
を指定しているが、ACK
を待たないQoS=1
を指定して、ACK
を待つ ペイロードのサイズは128KB
までhttps://docs.aws.amazon.com/ja_jp/general/latest/gr/iot-core.html
参考 : Basic Ingest を利用する場合
メリット
•
メッセージブローカーを経由しないために、メッセージ ングのコストが不要となる想定ユースケース
•
センサーからデータをクラウドへ上げるなど、送信した メッセージをsubscriberに送る必要がなく、ルール エンジンを発⽕できればよい使い⽅すでにご利⽤いただいているお客様向け
•
デバイス側の設定が可能であれば、IoT Coreの設 定はそのままで、デバイス側のpublish topicに ”$aws/rules/rule名”を追加するだけで利⽤
可能
•
ポリシーでも ”$aws/rules/rule名” をつけた トピックに対する Publish を許可するデバイス側からPublishするトピック
$aws/rules/{ルール名}/使いたいtopic
e.g.) $aws/rules/act-lambda/data/{device_name}
追加する$aws/rules/ルール名の3階層は、トピックの8階層の 制限または256⽂字合計制限の⽅にカウントされません。
ルール側のSQL句のtopic指定は、以下でよい data/{device_name}
https://docs.aws.amazon.com/ja_jp/iot/latest/developerguide/iot-basic-ingest.html
デバイス
AWS IoT Core
参考 : AWS Lambda などから Boto3 を利用する場合の注意点
Boto3 から AWS IoT データプレーン (publish, update_thing_shadow など ) を利用す る場合は、 endpoint_url として ATS エンドポイントの URL を指定 する
import boto3
iot_data = boto3.client(
"iot-data",
endpoint_url="https://xxxxx-ats.iot.<region>.amazonaws.com") iot_data.update_thing_shadow(
thingName="test-device", payload='{"state": {}}')
endpoint_url
でATS
エンドポイントを指定https://
を付けるhttps://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/iot-data.html
aws iot describe-endpoint --endpoint-type iot:Data-ATS
エンドポイントの確認方法 (AWS CLI)
Boto3 での設定方法
ルールがうまく動かない
問題の切り分けフロー
デバイス AWS IoT Core AWS サービス
AWS IoT Core
に 接続できないデバイスからの
(
への)
メッセージが届かない•
ネットワークの確認•
証明書・ポリシーの確認• Device SDK
の設定の確認Yes No
•
トピック・ポリシーの確認• Device SDK
の設定の確認Yes
ルールがうまく動かない
No
•
ルール・IAM
ロールの確認• AWS SDK
の設定の確認Yes
OK
No
ルールのログ・メトリクス呼び出し先サービスのログ・メトリクス
切り分け時の確認箇所 問題修正時の確認箇所
ルールがうまく動かない
問題の切り分け箇所
• AWS IoT Core
• AWS IoT のモニタリング
• CloudWatch ログ
• 呼び出し先サービス
• CloudWatch メトリクス
• CloudWatch ログ
確認するポイント
• AWS IoT Core
• ルールのクエリ
• アクションの設定
• ルールの IAM ロール
• エラーアクション
ルールの実行を確認する (AWS IoT Core 側 )
AWS IoT のモニタリング (CloudWatch メトリクス )
CloudWatch ログ 例 : RuleMatch
ルールが実行された回数
fields @timestamp, @message
| sort @timestamp desc
| filter eventType = ”RuleMatch"
{
"timestamp": "2021-02-25 09:56:05.744",
"logLevel": "INFO",
"traceId": "574e579f-2b16-0625-20d1-fc65f9506aea",
"accountId": ”123456789012",
"status": "Success",
"eventType": "RuleMatch",
“clientId”: “クライアントID",
“topicName”: “トピック名",
“ruleName”: “ルール名",
“principalId”: “証明書ID"
}
ロググループ
: AWSIotLogsV2
へのクエリ例ログが出ていない場合は、ルールのクエリを確認
ルールアクションの実行を確認する (AWS IoT Core 側 )
CloudWatch ログ
例 : RuleExecution fields @timestamp, @message
| sort @timestamp desc
| filter eventType = ”RuleExecution"
{"timestamp": "2021-02-25 09:57:49.101",
"logLevel": "INFO",
"traceId": "82af95b8-6831-d609-5c2e-f07344a406ff",
"accountId": "123456789012",
"status": "Success",
"eventType": "RuleExecution",
“clientId”: “クライアントID",
“topicName”: “トピック名",
“ruleName”: “ルール名",
“ruleAction”: “実行するアクション",
“resources”: { アクションの対象リソースの情報 },
“principalId”: “証明書ID"
}
{"timestamp": "2021-02-25 10:08:06.792",
"logLevel": "ERROR",
"traceId": "d74418c4-7386-855e-1c14-b89b6055dfbd",
"accountId": "123456789012",
"status": "Failure",
"eventType": "RuleExecution", (中略)
"details": "User: arn:aws:sts::123456789012:assumed-role/xxx-iot-rule-role/wVsRP81A is not authorized to perform: service:Action on resource: arn:aws:service: 123456789012 :type/name (Service: XXX;
Status Code: 400; Error Code: AccessDeniedException; Request ID:
f2d458a4-81ff-f3d7-aa65-21e2945e18ef; Proxy: null)"
}
例 : 成功時 例 : 失敗時
ロググループ
: AWSIotLogsV2
へのクエリ例IAM ロールの権限を確認
ルールアクションの実行を確認する ( 呼び出し先サービス側 )
CloudWatch メトリクス ( 例 : AWS Lambda)
関数の呼び出し回数
関数内でのエラー率
関数の実行時間 スロットルの発生数
関数の同時実行数
例えば、
AWS Lambda
であれば関数の同時 実行数や最大実行時間に上限があるルールの実行を確認する ( 呼び出し先サービス側 )
CloudWatch ログ ( 例 : AWS Lambda)
START RequestId: f02fb15c-2e21-4942-b777-7ac816efb042 Version: $LATEST
…
関数内で print や logging で出力したログ
…
END RequestId: f02fb15c-2e21-4942-b777-7ac816efb042 REPORT RequestId: f02fb15c-2e21-4942-b777-7ac816efb042 Duration: 272.18 ms Billed Duration: 273 ms Memory Size: 128 MB Max Memory Used: 54 MB
START RequestId: ecfc9219-6caa-454f-9be3-a9f5de033fbf Version: $LATEST
[ERROR] RuntimeError: my runtime error Traceback (most recent call last):
File "/var/task/lambda_function.py", line 9, in lambda_handler raise RuntimeError("my runtime error")
END RequestId: ecfc9219-6caa-454f-9be3-a9f5de033fbf REPORT RequestId: ecfc9219-6caa-454f-9be3-a9f5de033fbf
Duration: 432.48 ms Billed Duration: 433 ms Memory Size: 128 MB Max Memory Used: 51 MB Init Duration: 121.19 ms
例 : 成功時 例 : エラー発生時
fields @timestamp, @message
| sort @timestamp desc
| limit 20
ロググループ
: /aws/lambda/
関数名 へのクエリ例※ ログの出力順序は入れ替わる場合があります
ルールがうまく動かない
問題の切り分け箇所
• AWS IoT Core
• AWS IoT のモニタリング
• CloudWatch ログ
• 呼び出し先サービス
• CloudWatch メトリクス
• CloudWatch ログ
確認するポイント
• AWS IoT Core
• ルールのクエリ
• アクションの設定
• ルールの IAM ロール
• エラーアクション
ルールの確認ポイント
クエリは適切か?
トピックの絞り込み・条件
https://docs.aws.amazon.com/ja_jp/iot/latest/developerguide/iot-sql-reference.html
SELECT * FROM 'data/thermometer/+' WHERE temperature > 50
ルール実行対象のトピックは正しいか?
ワイルドカードは適切か?
ルール実行条件は正しいか?
ペイロードの
JSON
構造と合って いるか?呼び出し先サービスに渡すペイロード
SELECT device_id, temperature, timestamp() as server_timestamp FROM 'data/device-id'
後段処理に渡すペイロードは必要十分か?
{
”device_id": ”my-device-0001",
”temperature": 47.3,
”humidity": 32.0 }
デバイスからのペイロード例
ルールの確認ポイント
ルールアクションの設定は適切か?
アクション・エラーアク ションは間違っていないか
送信先のリソースは正しいか?
送信するペイロードの 設定は適切か?
ルールの確認ポイント
ルールの IAM ロールは適切か?
権限が不足している場合は、
ロールの更新をクリック
必要なポリシーがアタッチされる
ルールの確認ポイント
ルールアクション実行時に問題が発生した 場合に、エラーアクションをトリガーする 問題の例
•
ルールのIAM
ロールに必要な権限が不足 している•
呼び出し先サービスのスループットを超 える入力があるエラーアクションの例
• DynamoDB
への書き込みアクションに 失敗した時に、SQS
へ一時的にメッ セージを退避するエラーアクションに記録されるメッセージ例
https://docs.aws.amazon.com/ja_jp/iot/latest/developerguide/rule-error-handling.html
{“ruleName”: “ルール名",
“topic”: “トピック",
"cloudwatchTraceId": "a16bca98-e92e-a1eb-6685-bc00b96a3b40",
“clientId”: “クライアントID",
“base64OriginalPayload”: “元のメッセージのペイロード(Base64)",
"failures": [
{"failedAction": "DynamoDBv2Action",
"failedResource": ”MyTable",
"errorMessage": "DynamoDBv2 Put record failed. The error received was User:
arn:aws:sts::123456789012:assumed-role/MyRuleRole/r77DPsEZ is not authorized to perform:
dynamodb:PutItem on resource:
arn:aws:dynamodb:123456789012:table/MyTable (Service:
AmazonDynamoDBv2; Status Code: 400; Error Code:
AccessDeniedException; Request ID: …; Proxy: null). Message arrived on: my/topic, Action: dynamoDBv2, Table: MyTable"
} }]
必要に応じて エラーアクション が設定されているか?
問題の発見・調査のための Tips
まず監視すべき AWS IoT の CloudWatch メトリクス
• ルール / ルールアクションメトリクス
• ParseError JSON
パースのエラー• Action Failure
アクションの実行エラー• メッセージブローカーメトリクス
• AuthError
クライアントの認証エラー• ClientError AWS IoT
の仕様に反したメッセージにより 発生するエラー• ThrottleError AWS IoT
の制限を超えた際に発生 するエラートラブルシューティ ング用グループ
モニタリング
Logging: Warn
デバッグ
Logging: Debug
アカウントレベルLogging: Error
モノのグループに対するログレベルの設定
ログレベルの目安
• Error:
商用運用時• Warn:
負荷試験時• Info:
動作検証時• Debug:
開発時• Disabled:
IoT デバイスの 設定をセキュア
に保つ
異常な振る舞い
を検出する アラートを
受け取る セキュリティ の問題を修正
する
AWS IoT Device Defender による追加の統制
IoT デバイスの監査と異常検知
AWS IoT Device Defender でできること
• AWS IoT をセキュリティ観点から継続的に監視、発報
• 事前定義の項目に従って設定を 監査
(Device Defender Audit
)• 指定した内容を元にふるまいの 異常検知
(Device Defender Detect
)• AWS IoT コンソールのほか、各種 AWS サービス (CloudWatch 、 SNS) と 連携したアラート、問題の修正
【監査の実⾏例】 【異常検知の設定例】
セキュアトンネリングによる詳細なトラブルシューティング
数回のクリックで各デバイスにセキュアに接続し、
問題を診断して解決に向けたアクションを実施
トンネルのオープン
Destination local-proxy
リモートシェル
Source local-proxy
< / >