[IoT Events] シンプルなハートビート監視をCloudFormationで作る
デバイスからの通信が一定時間無いときにデバイス切断と判断してメール送信する仕組み(ハートビート監視)をCloudFormationで作ってみました。
AWS IoT Eventsを使えば、LambdaやDynamoDBを使わずにハートビート監視ができます。
実際に案件等で使う場合、CloudFormationを使うことになるので、実際に作ってみました。
おすすめの方
- AWS IoT Eventsの雰囲気を知りたい方
- AWS IoT Eventsでハートビートを実現したい方
- AWS IoT EventsをCloudFormationで作成したい方
ハートビートの動作を決める
デバイスの動作
- 下記のトピックにハートビート用のデータを送信する
sample/<デバイスID>/heartbeat
- 2分毎に送信する
- ハートビート用のデータは下記とする(データが届いたかどうかで判断するため、EmptyでOK)
{}
クラウドの動作
- ハートビート用のタイマーがゼロになったとき、デバイス切断と判断してSNSトピックを発行する(メール送信する)
- デバイス切断状態でハートビート用のデータが届いたとき、デバイス接続が復旧したと判断してSNSトピックを発行する(メール送信する)
- デバイス接続状態でハートビート用のデータが届いたとき、ハートビート用のタイマーをReStartする
- ハートビート用のタイマーは5分とする
AWS IoT EventsをCloudFormationで作成する
CloudFormationテンプレート
下記を定義しています。
- メール通知用のSNSトピック
- IoTルール
- IoTルール用のIAMロール
- IoT Eventsの入力情報
- IoT Eventsの探知器モデル
- IoT Eventsの探知器モデル用のIAMロール
AWSTemplateFormatVersion: 2010-09-09 Description: IoT Events Heartbeat Sample Parameters: HeartbeatTimerDefaultSeconds: Type: String Default: 300 Resources: HeartbeatNotifyTopic: Type: AWS::SNS::Topic Properties: Subscription: - Endpoint: sample@example.com Protocol: email HeartbeatlTopicRule: Type: AWS::IoT::TopicRule Properties: RuleName: heartbeat_topic_rule TopicRulePayload: AwsIotSqlVersion: "2016-03-23" RuleDisabled: false Sql: >- SELECT topic(2) as deviceId, * as payload FROM 'sample/+/heartbeat' Actions: - IotEvents: InputName: !Ref HeartbeatEventsInput RoleArn: !GetAtt HeartbeatTopicRuleRole.Arn HeartbeatTopicRuleRole: Type: AWS::IAM::Role Properties: RoleName: heartbeat-topic-rule-role AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: Service: iot.amazonaws.com Action: sts:AssumeRole ManagedPolicyArns: - arn:aws:iam::aws:policy/AWSIoTEventsFullAccess HeartbeatEventsInput: Type: AWS::IoTEvents::Input Properties: InputName: HeartbeatInputData InputDefinition: Attributes: - JsonPath: deviceId HeartbeatDetectorModel: Type: AWS::IoTEvents::DetectorModel Properties: DetectorModelName: heartbeat-detector-model Key: deviceId EvaluationMethod: BATCH RoleArn: !GetAtt HeartbeatEventsDetectorModelRole.Arn DetectorModelDefinition: InitialStateName: Online States: - StateName: Online OnEnter: Events: - EventName: init_timer Condition: true Actions: - SetTimer: TimerName: HeartbeatTimer Seconds: !Ref HeartbeatTimerDefaultSeconds OnInput: Events: - EventName: reset_timer Condition: currentInput("HeartbeatInputData") Actions: - ResetTimer: TimerName: HeartbeatTimer TransitionEvents: - EventName: to_offline Condition: timeout("HeartbeatTimer") NextState: Offline - StateName: Offline OnEnter: Events: - EventName: send-mail-to-offline Actions: - Sns: TargetArn: !Ref HeartbeatNotifyTopic Payload: Type: STRING ContentExpression: "'デバイスの切断を検知しました。対象デバイスID: ${$input.HeartbeatInputData.deviceId}'" OnInput: TransitionEvents: - EventName: to_online Condition: currentInput("HeartbeatInputData") NextState: Online OnExit: Events: - EventName: send-mail-to-online Actions: - Sns: TargetArn: !Ref HeartbeatNotifyTopic Payload: Type: STRING ContentExpression: "'デバイスの接続が復旧しました。対象デバイスID: ${$input.HeartbeatInputData.deviceId}'" HeartbeatEventsDetectorModelRole: Type: AWS::IAM::Role Properties: RoleName: heartbeat-detector-model-role AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: Service: iotevents.amazonaws.com Action: sts:AssumeRole ManagedPolicyArns: - arn:aws:iam::aws:policy/AWSIoTEventsFullAccess - arn:aws:iam::aws:policy/AmazonSNSFullAccess
デプロイする
aws cloudformation deploy \ --template-file iot_events.yml \ --stack-name IoT-Events-Heartbeat-Sample-Stack \ --capabilities CAPABILITY_NAMED_IAM \ --no-fail-on-empty-changeset
デプロイされた探知器モデルを確認する
バッチリですね。
動作確認
1. データ送信すると、Online状態になる
- トピック: sample/d0001/heartbeat
{}
タイマーも5分後に設定されています。
2. 2分毎にデータ送信すると、Online状態のまま
- トピック: sample/d0001/heartbeat
{}
タイマーも更新(ReStart)されています。
3. 5分ほど放置すると、Offline状態になる
デバイス切断のメールも来ました。
4. データ送信すると、Online状態に戻る
- トピック: sample/d0001/heartbeat
{}
デバイス接続復旧のメールも来ました。