AWS IoT Retrieving SQS Messages from a Queue using an IoT Rule and a Lambda function

AWS IoT Rules have predefined rules for sending a message to an SQS Queue, but for some reason not to retrieve a message from a queue using an IoT rule (or does it? if you know how, leave me a comment). You can easily retrieve a message using a Lambda function using the AWS SDK apis though, and you can call a Lambda function using an IoT Rule, so let’s set that up.

To create an IoT Rule to call the Lambda function, which we’ll trigger with incoming MQTT messages on a topic called topic/checkForMessage:

Next, select an action from the long list of available actions, chose ‘Invoke a Lambda function’:

Select the Lambda function we want to call, in this case it’s one created earlier (it has to exist to show in the list, if not press ‘Create a new Resource’ to create one):

On the next summary screen press ‘Create Rule’ and you’re done:

To allow the IoT Rule to call the function, we need to grant the lambda:invokeFunction rule.

Per the docs, we can use the AWS CLI to add the permission like this:

aws lambda add-permission 
  --function-name "function_name" 
  --region "region" 
  --principal iot.amazonaws.com 
  --source-arn arn:aws:iot:us-east-2:account_id:rule/rule_name 
  --source-account "account_id" 
  --statement-id "unique_id" 
  --action "lambda:InvokeFunction"

To apply this to our function and rule, replace:

“function_name” : “LightsOnReceiveMessageFromQueue”

“region”: “us-east-1”

source-arn arn: aarn:aws:iot:full-arn-for-the-rule – see below

account_id: your-aws-account-id

rule_name: RetrieveSQSMessageFromQueue

“account_id”: “your-account-id”

“unique_id”: unique-id-for-this-permission

I’m not sure the AWS Console for IoT shows the ARN for IoT Rules anywhere in it’s pages, but you can easily list it with the AWS CLI, using:

$ aws iot list-topic-rules
{
    "rules": [
        {
            "ruleArn": "arn:aws:iot:us-east-1:your-account-id:rule/RetrieveSQSMessageFromQueue",
            "ruleName": "RetrieveSQSMessageFromQueue",
            "topicPattern": "topic/checkForMessage",
            "createdAt": 1511115896.0,
            "ruleDisabled": false
        }
    ]
}

Ok, plugging in my values into the aws cli statement I have a permission added.

This is it for the IoT Rule. To summarize, this allows us to:

  • respond to incoming messages from an AWS IoT device publishing a message to an MQTT topic called topic/checkForMessages
  • when a message arrives from the device on the topic, it triggers the IoT Rule we just created
  • the rule invokes an AWS Lambda to interact with an AWS SQS Queue to pull a message from a queue.

I’ll share more details on the implementation of the Lambda to interact with the SQS queue and the implementation of the node.js app on a Raspberry Pi in upcoming posts. You’re probably wondering what this is that I’m building? Check back for my followup posts to find out!

This is the second post in a series on AWS and IoT, the first is here: