AWS IoT Coreのルールアクションには、エラー発生時に動作するエラーアクションがあります。 このエラーアクションの動作を確認したい場合には、ひと工夫が必要です。 本記事では、ルールアクションを強制的に失敗させて、エラーアクションの動作を確認してみました。
おすすめの方
- AWS IoT Coreのエラーアクションの動作を確認したい方
- AWS IoT CoreをCloudFormationで作成したい方
IoT Coreのルールアクションを失敗させる方法
IoTルールアクションを失敗させるためには、IoTルールアクションにアタッチされているIAMロールを失敗する内容で試します。
- Effect: AllowからDenyにする
- Action: 関係ない内容にする
- Resource: 関係ない内容にする
本記事では、Actionを関係ない内容にします。
IoT Ruleアクションとエラーアクションを作成する
CloudFormationテンプレート
前述したとおり、IoTルールアクション用のIAMロールの権限を「SNS」ではなく「DynamoDB」にしています。
iot.yaml
AWSTemplateFormatVersion: 2010-09-09
Description: IoT Rule Test
Resources:
SampleTable:
Type: AWS::DynamoDB::Table
Properties:
TableName: iot-rule-error-action-table
BillingMode: PAY_PER_REQUEST
AttributeDefinitions:
- AttributeName: awsUuid
AttributeType: S
- AttributeName: awsTimestamp
AttributeType: N
KeySchema:
- AttributeName: awsUuid
KeyType: HASH
- AttributeName: awsTimestamp
KeyType: RANGE
OkTopic:
Type: AWS::SNS::Topic
Properties:
Subscription:
- Endpoint: sample@example.com
Protocol: email
TestTopicRule:
Type: AWS::IoT::TopicRule
Properties:
RuleName: test_sample_topic_rule
TopicRulePayload:
AwsIotSqlVersion: "2016-03-23"
RuleDisabled: false
Sql: >-
SELECT
* as payloads
FROM
'test/aaa'
Actions:
- Sns:
TargetArn: !Ref OkTopic
RoleArn: !GetAtt TestTopicRuleRole.Arn
ErrorAction:
DynamoDB:
TableName: !Ref SampleTable
HashKeyField: awsUuid
HashKeyType: STRING
HashKeyValue: ${newuuid()}
RangeKeyField: awsTimestamp
RangeKeyType: NUMBER
RangeKeyValue: ${timestamp()}
RoleArn: !GetAtt TestTopicRuleErrorRole.Arn
TestTopicRuleRole:
Type: AWS::IAM::Role
Properties:
RoleName: test-sample-topic-rule-role
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service: iot.amazonaws.com
Action: sts:AssumeRole
ManagedPolicyArns:
# 本来はSNS Publish権限を付与するべきだが、失敗させるために、SNS以外の権限を付与している
- arn:aws:iam::aws:policy/AmazonDynamoDBFullAccess
TestTopicRuleErrorRole:
Type: AWS::IAM::Role
Properties:
RoleName: test-sample-topic-rule-error-role
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service: iot.amazonaws.com
Action: sts:AssumeRole
ManagedPolicyArns:
- arn:aws:iam::aws:policy/AmazonDynamoDBFullAccess
デプロイ
aws cloudformation deploy \
--template-file iot.yaml \
--stack-name IoT-Rule-Test-Stack \
--capabilities CAPABILITY_NAMED_IAM \
--no-fail-on-empty-changeset
エラーアクションの動作を確認する
IoT Coreにメッセージを送信する
トピック「test/aaa」に適当なメッセージを送信します。
CloudWatch LogsでIoT CoreのErrorログを確認する
Errorログがありました。通常のルールアクションが失敗しています。
{
"timestamp": "2022-11-15 03:30:05.593",
"logLevel": "ERROR",
"traceId": "a7d6d7a5-55ba-465f-cbdc-9811649979c0",
"accountId": "xxx",
"status": "Failure",
"eventType": "RuleExecution",
"clientId": "iotconsole-xxx",
"topicName": "test/aaa",
"ruleName": "test_sample_topic_rule",
"ruleAction": "SNSAction",
"resources": {
"TargetArn": "arn:aws:sns:ap-northeast-1:xxx:IoT-Rule-Test-Stack-OkTopic-YXI8X6qb4MbD"
},
"principalId": "xxx",
"details": "User: arn:aws:sts::xxx:assumed-role/test-sample-topic-rule-role/OlNaFMWi is not authorized to perform: SNS:Publish on resource: arn:aws:sns:ap-northeast-1:xxx:IoT-Rule-Test-Stack-OkTopic-YXI8X6qb4MbD because no identity-based policy allows the SNS:Publish action (Service: AmazonSNS; Status Code: 403; Error Code: AuthorizationError; Request ID: e999d0c2-88ee-5d01-a70e-8b2f8113b1b3; Proxy: null)"
}
DynamoDBテーブルを確認する
IoT Coreのエラーアクションで保存されたデータがありました。
{
"awsUuid": "3ae9926b-830d-421e-bb10-7c1e83048802",
"awsTimestamp": 1668483005471,
"payload": {
"base64OriginalPayload": "ewogICJtZXNzYWdlIjogIkFXUyBJb1Qg44Kz44Oz44K944O844Or44GL44KJ44Gu5oyo5ou2Igp9",
"base64TransparentProperties": "eyJmb3JtYXRfaW5kaWNhdG9yIjoiVU5TUEVDSUZJRURfQllURVMifQ==",
"clientId": "xxx",
"cloudwatchTraceId": "a7d6d7a5-55ba-465f-cbdc-9811649979c0",
"failures": [
{
"errorMessage": "Failed to publish SNS topic. The error received was User: arn:aws:sts::xxx:assumed-role/test-sample-topic-rule-role/OlNaFMWi is not authorized to perform: SNS:Publish on resource: arn:aws:sns:ap-northeast-1:xxx:IoT-Rule-Test-Stack-OkTopic-YXI8X6qb4MbD because no identity-based policy allows the SNS:Publish action (Service: AmazonSNS; Status Code: 403; Error Code: AuthorizationError; Request ID: e999d0c2-88ee-5d01-a70e-8b2f8113b1b3; Proxy: null). Message arrived on: test/aaa, Action: sns, Target Arn: arn:aws:sns:ap-northeast-1:xxx:IoT-Rule-Test-Stack-OkTopic-YXI8X6qb4MbD",
"failedAction": "SNSAction",
"failedResource": "arn:aws:sns:ap-northeast-1:xxx:IoT-Rule-Test-Stack-OkTopic-YXI8X6qb4MbD"
}
],
"ruleName": "test_sample_topic_rule",
"topic": "test/aaa"
}
}
「base64OriginalPayload」をBase64デコードすると、次の内容でした。
{
"message": "AWS IoT コンソールからの挨拶"
}
さいごに
IoT Coreのエラーアクション動作を確認しました。すでに本番稼働しているシステムでIAMロールの権限を変更する場合は、タイミングやアフターケアなどに気をつけてください。