Hello,
I'm using an IoT rule to decode protobuf messages, and having trouble when this fails (e.g., the client has incorrectly packed data). I'm trying to set up an error action that deposits the error information to an S3 bucket, but I do not see any files created.
The smallest reproducible error I can make is this:
IoT Rule
{
"ruleArn": "arn:aws:iot:us-east-1:xxxxxxxx:rule/JMF_Test_Rule",
"rule": {
"ruleName": "JMF_Test_Rule",
"sql": "SELECT decode(*, \"base64\") as payload",
"description": "",
"createdAt": "2024-04-26T15:58:53-04:00",
"actions": [
{
"republish": {
"roleArn": "arn:aws:iam::xxxxxxx:role/service-role/jmf-test-role-for-republish",
"topic": "test/topic/here",
"qos": 0
}
}
],
"ruleDisabled": false,
"awsIotSqlVersion": "2016-03-23",
"errorAction": {
"s3": {
"roleArn": "arn:aws:iam::xxxxxxx:role/service-role/jmf-test-s3-error-role",
"bucketName": "test-bucket-name",
"key": "my-test-thing.err",
"cannedAcl": "bucket-owner-full-control"
}
}
}
}
Then, using the MQTT Test Client, I send any text message ("hello world!") to the topic $aws/rules/JMF_Test_Rule
(basic ingest). This fails, as I expect, because the incoming data is not valid base64. I know it fails because in CloudWatch I see this:
{
"timestamp": "2024-04-26 19:59:01.118",
"logLevel": "ERROR",
"traceId": "fcb72e63-3297-0556-2b0f-4031a809801c",
"accountId": "xxxxxxxxx",
"status": "Failure",
"eventType": "FunctionExecution",
"clientId": "iotconsole-79a92762-9ef6-4aba-add1-2be9272c9fbd",
"topicName": "$aws/rules/JMF_Test_Rule",
"ruleName": "JMF_Test_Rule",
"ruleAction": "Decode",
"resources": {},
"principalId": "ABCDEF",
"details": "Invalid parameters. Expected decode(*, $scheme, $[scheme parameters])"
}
{
"timestamp": "2024-04-26 19:59:01.122",
"logLevel": "ERROR",
"traceId": "fcb72e63-3297-0556-2b0f-4031a809801c",
"accountId": "xxxxxxxxx",
"status": "Failure",
"eventType": "RuleExecution",
"clientId": "iotconsole-79a92762-9ef6-4aba-add1-2be9272c9fbd",
"topicName": "$aws/rules/JMF_Test_Rule",
"ruleName": "JMF_Test_Rule",
"principalId": "ABCDEF",
"reason": "ExternFunctionException",
"details": "Function 'Decode' failed to execute for rule 'JMF_Test_Rule'. Invalid parameters. Expected decode(*, $scheme, $[scheme parameters])"
}
However, no files are created in the S3 bucket. I know that the error role has the proper permissions, because if I post valid base64 data, the rule will fail because jmf-test-role-for-republish
does not have permissions to publish to test/topic/here
, and then an error file is correctly created in the S3 bucket.
Am I doing something wrong on this?
Thank you,
Jonathan
That's disappointing! It would be very helpful to be able to catch these sorts of issues. I don't want to lose data - is my best option to decode the protobuf data within a lambda function directly, then, so I can handle errors and store data if it fails to decode? Or I guess add a rule action that stores all messages to S3, but that's wildly inefficient.
Hi. It's reasonably common to use Amazon Kinesis Data Firehose to save all incoming messages to S3, in a batched manner for efficiency: https://iotatlas.net/en/best_practices/aws/data_ingest/#save-ingested-data-to-durable-storage-before-processing and https://iotatlas.net/en/best_practices/aws/data_ingest/#cost_datalake. So you might do that to have all messages, including all faulty messages, saved for subsequent analysis and processing. And perhaps retain your existing rule for timely processing of good messages.