The Internet of Things on AWS – Official Blog
Route messages across multiple accounts with AWS IoT Core and Amazon SQS
Introduction
In this blog, we explain how to route AWS IoT Core messages from one or more ingestion accounts to Amazon Simple Queue Service (Amazon SQS) in a data account. It is a common pattern to have IoT telemetry ingested into one account and then require it to be shipped to another account for further processing. For example, when an organization hosts devices in multiple accounts and the data being ingested is classified as both sensitive and operational. Sensitive data needs to be kept in the original collection account but operational data needs to be relayed to another account monitored by an operations team.
You will learn how to configure AWS IoT rules for cross-account access to route MQTT topic data sets into Amazon SQS. Rules for AWS IoT give your devices the ability to interact with AWS services. You can use rules to support tasks such as augmenting or filtering data from a device, writing data to database, publishing messages to Amazon SQS and more. For a complete list of tasks you can perform, please refer to the Rules for AWS IoT section of the AWS IoT Core Developer Guide.
Solution Overview
In this solution, you will first create an Amazon SQS queue in the data account and grant permissions to the ingestion account to publish to it . Next, you will create AWS IoT rules and send messages to them to test.
- Create an Amazon SQS queue called
iot-data
in the data account and allow publishing to this queue from the ingestion account. - In the ingestion account:
a. Create an Identity and Access Management (IAM) role with a policy that allows publishing to Amazon SQS in the data account.
b. Create an IAM role with a policy that allows a republish action for errors encountered when publishing to the SQS queue. - Create an IoT rule in the ingestion account to evaluate messages from a topic called
data/private
and send them to the data account SQS queue. The rule will have an error action that republishes messages to theerror/rules
topic for troubleshooting. - Publish messages to the MQTT topic
data/private
and verify the messages are visible in the data account SQS queue.
Solution Diagram
Solution Instructions
Prerequisites
- Two AWS accounts
- Administrator privileges in both accounts
- AWS Command Line Interface (AWS CLI)
Create an SQS queue in the data account
- Create a file named
queue_attributes.json
with the following content.{ "MessageRetentionPeriod": "259200" }
- With the AWS CLI configured for the data account and using the
create-queue.json
file, create an SQS queue callediot-data
.aws sqs create-queue \ --queue-name iot-data \ --attributes file://queue_attributes.json
- Record the QueueURL from the output as that will be needed in the next section.
- To grant permissions for the Amazon SQS queue resource to be accessed by the ingestion account, run the add-permission command. Be sure to update the account numbers accordingly.
aws sqs add-permission \ --queue-url https://sqs.<data account region>.amazonaws.com/<data account ID>/iot-data \ --label IoTSendMessage \ --aws-account-ids <ingestion account ID> \ --actions SendMessage
Create the AWS Identity and Access Management (IAM) role and policy for cross-account publishing to SQS
In order to publish to the SQS queue from the data account, you first need to allow that action.
- Create a file named
iot_policy.json
with the following content:{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "iot.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }
- With the AWS CLI configured for the ingestion account, run the following command to create a role called
iot-cross-sqs-allow
and attach the trust policy to allow it to interact with IoT.aws iam create-role \ --role-name iot-cross-sqs-allow \ --assume-role-policy-document file://iot_policy.json
- Review the output and ensure it is correct:
{ "Role": { "Path": "/", "RoleName": "iot-cross-sqs-allow", "RoleId": "XXXXXXXXXXXXXXXXXXXXX", "Arn": "arn:aws:iam::XXXXXXXXXXXX:role/iot-cross-sqs-allow", "CreateDate": "2022-09-07T05:05:58+00:00", "AssumeRolePolicyDocument": { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "iot.amazonaws.com" }, "Action": "sts:AssumeRole" } ] } } }
- Create a file called
allow_send_cross_sqs.json
with the following content. For the resource ARN, be sure to update with the region and account ID of the data account.{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "sqs:SendMessage", "Resource": "arn:aws:sqs:<data account region>:<data account ID>:iot-data" } ] }
- Add this custom inline policy to the role you created in the previous step by using the following command:
aws iam put-role-policy \ --role-name iot-cross-sqs-allow \ --policy-name new-iot-cross-sqs-policy \ --policy-document file://allow_send_cross_sqs.json
Create the AWS IAM role and policy to allow republishing of errors
When republishing messages with an AWS IoT rule, permissions need to be properly set to allow this action.
- With the AWS CLI configured for the ingestion account and using the same file created earlier, create a new role called
iot-republish
:aws iam create-role \ --role-name iot-republish \ --assume-role-policy-document file://iot_policy.json
- Review the output and ensure it is correct:
{ "Role": { "Path": "/", "RoleName": "iot-republish", "RoleId": "XXXXXXXXXXXXXXXXXXXXX", "Arn": "arn:aws:iam::XXXXXXXXXXXX:role/iot-republish", "CreateDate": "2022-09-07T05:24:36+00:00", "AssumeRolePolicyDocument": { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "iot.amazonaws.com" }, "Action": "sts:AssumeRole" } ] } } }
- Next create a file called
allow_republish.json
with the following content. Please note that this policy restricts publishing to topic names starting with errors. Be sure to update with the region and account ID of the ingestion account.{ "Version": "2012-10-17", "Statement": { "Effect": "Allow", "Action": "iot:Publish", "Resource": "arn:aws:iot:<ingestion account region>:<ingestion account ID>:errors/*" } }
- Add the policy just created as an inline policy to the
iot-republish
role:aws iam put-role-policy \ --role-name iot-republish \ --policy-name iot-republish \ --policy-document file://allow_republish.json
Create an IoT rule in the ingestion account to evaluate messages and republish errors
Next, we will create the IoT rule that will route messages to the SQS queue in the and also republish any messages that encounter an error to a topic named error/rules
.
- Create a file named
ingestion_rule.json
with the following content. Be sure to update thequeueURL
androleArn
values with those received in previous steps.{ "sql": "SELECT * FROM 'data/private'" , "description": "Cross-account publishing of messages to SQS.", "ruleDisabled": false, "awsIotSqlVersion": "2016-03-23", "actions": [{ "sqs": { "roleArn": "<iot-cross-sqs-allow role ARN>", "queueUrl": "https://sqs.<data account region>.amazonaws.com/<data account ID>/iot-data", "useBase64": true } }], "errorAction": { "republish": { "roleArn": "<iot-republish role ARN>", "topic": "error/rules", "qos": 0 } } }
- With the AWS CLI configured for the ingestion account, create an IoT rule for the publishing of message to SQS in the data account:
aws iot create-topic-rule \ --rule-name "cross_account_sqs_publish" \ --topic-rule-payload file://ingestion_rule.json
Publish messages and verify they are visible in the data account SQS queue
To test the solution, you can publish a message to AWS IoT Core and see if it arrives successfully in the data account SQS queue.
- From the ingestion account, use the AWS IoT MQTT client to subscribe to the
data/private
anderror/rules
topics. - Continuing with the AWS MQTT IoT client, publish a message to the
data/private topic
with a sample payload:{ "message": "Hello, world", "clientType": "MQTT client" }
- Retrieve messages from the SQS queue and review the output by configuring the AWS CLI for the data account and running the following command.
aws sqs receive-message \ --queue-url https://sqs.<data account region>.amazonaws.com/<data account ID>/iot-data
The Body parameter of the output may be Base64 encoded. If so, you will need to decode it to see the contents of the published message
- If messages are not being received in the SQS queue, check the error/rules topic subscription for error messages related to delivery from the AWS MQTT IoT client in the ingestion account.
Cleaning Up
It is good practice to clean up any resources you no longer want to use. Cleaning up AWS resources prevents your account from incurring any further charges.
- Delete the SQS queue:
aws sqs delete queue \ --queue-url https://sqs.<data account region>.amazonaws.com/<data account ID>/iot-data
- Delete the
iot-cross-sqs-all
IAM role:aws iam delete-role-policy \ --role-name iot-cross-sqs-all \ --policy-name iot-cross-sqs-all aws iam delete-role --role-name iot-cross-sqs-all
- Delete the
iot-republish
role:aws iam delete-role-policy \ --role-name iot-republish \ --policy-name iot-republish aws iam delete-role --role-name iot-republish
- Delete the
cross_account_sqs_publish
topic rule:aws iot delete-topic-rule \ --rule-name cross_account_sqs_publish
Conclusion
In this blog we explained how to route AWS IoT messages from an ingestion account to Amazon SQS in a data account. We have shown you one pattern that allows for segmentation of a sensitive device and operational data within separate accounts. For further examples on how to perform cross-account message routing with other AWS services, please check out the related documentation in the AWS Developer Guide.
Authors
Steve Krems is a Specialist Solution Architect for IoT at Amazon Web Services (AWS). Prior to this role, Steve spent 18 years in the semiconductor industry in Information Technology management roles with a focus on cloud migration and modernization. |
Kai-Matthias Dickman is a Specialist Solution Architect for IoT at Amazon Web Services (AWS). He enjoys working with developers and decision makers at large enterprises to drive the adoption of AWS IoT services. Kai has in-depth knowledge of IoT and cloud and works in this role with global customers ranging from start-up to enterprises to enable them to build IoT solutions with the AWS Eco system. |