The Internet of Things on AWS – Official Blog

Bites of IoT – Rules Engine and Amazon SNS

Welcome to another installment in the Bites of IoT blog series.

In this bite, we will use the AWS IoT rules engine to select and route a message to Amazon Simple Notification Service (Amazon SNS). Specifically, we’ll send a text message to a phone number when someone rings a virtual doorbell.

Concepts Covered in This Bite

The rules engine is often the first point at which your IoT solution can take actions on a device’s messages (for example, message filtering, routing to other services, and even direct processing of messages in your solution).

By using  AWS IoT and Amazon SNS together, you can send near real-time notifications in response to changes in the physical world as reported by devices in your IoT solution. These notifications can be:

  • sent to system operators or technicians for human intervention.
  • added to your existing ticketing system.
  • used to kick off an automated workflow.

Configure the CLI

As with all Bites of IoT posts, we are using the AWS IoT ELF client available in AWS Labs on GitHub. If you aren’t familiar with the ELF, check out the first post in this series.

We’ll use the AWS CLI to create the Amazon SNS topic and AWS IoT rule. In addition to the permissions required by the AWS IoT ELF, you will need to configure the profile used by your CLI with, at minimum, the following permissions. Make sure to replace the value 012345678901 in the policy with your AWS account ID:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "sns:CreateTopic",
                "sns:SetTopicAttributes",
                "sns:Subscribe",
                "sns:Publish",
                "sns:DeleteTopic",
                "iot:CreateTopicRule",
                "iot:DeleteTopicRule",
                "iam:AttachRolePolicy",
                "iam:CreatePolicy",
                "iam:CreateRole",
                "iam:DetachRolePolicy",
                "iam:DeletePolicy",
                "iam:DeleteRole"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "iam:PassRole"
            ],
            "Resource": [
                "arn:aws:iam::012345678901:role/*"
            ]
        }
    ]
}

Create a Bites Directory

If you followed the steps in Getting Started, you should already have a local directory structure of ~/dev/aws-iot-elf (where “~” is shorthand for your computer user’s home directory).

Each Bite of IoT post will require the creation of local files. Start by creating your Bites directory. On Linux or Mac OS, execute the following commands:

cd ~/dev
mkdir bites
cd ~/dev/bites

Now, in your Bites directory, execute these commands to make a directory for the artifacts used in this post, and then change into that directory.

mkdir sns
cd ~/dev/bites/sns

Now that the basic dev environment is set up, let’s get into the details.

Create the SNS Topic

Create the Amazon SNS topic that the AWS IoT rules engine will be connecting with to send notifications. Use the following AWS CLI commands to create and name the topic. Remember to replace 012345678901 in the --topic-arn value with your AWS account ID.

aws sns create-topic --region us-west-2 --name door-alert
aws sns set-topic-attributes --region us-west-2 --topic-arn arn:aws:sns:us-west-2:012345678901:door-alert --attribute-name DisplayName --attribute-value DOORBELL

Note: The DisplayName value DOORBELL will appear as the “from” address when you receive a notification on your mobile phone.

Now subscribe your mobile phone to the topic using the following CLI command. Replace 1-012-345-6789 with your phone number. This command enables your mobile phone to receive the notification when the virtual doorbell rings.

aws sns subscribe --region us-west-2 --topic-arn arn:aws:sns:us-west-2:012345678901:door-alert --protocol sms --notification-endpoint 1-012-345-6789

You can use this command to validate the subscription:

aws sns publish --region us-west-2 --message "A Bite of Hello" --topic-arn arn:aws:sns:us-west-2:012345678901:door-alert

Create Permissions to Use Amazon SNS

Before we create the IoT rule, we need to create an IAM role that the AWS IoT rules engine will assume and use to securely publish a message to Amazon SNS.

The first step to creating the role is to make a trust policy that grants AWS IoT permission to assume the role. Copy and paste the following trust policy document into a temporary file named iot-role-trust.json:

{
    "Version":"2012-10-17",
    "Statement":[{
        "Effect": "Allow",
        "Principal": {
            "Service": "iot.amazonaws.com"
        },
        "Action": "sts:AssumeRole"
    }]
}

Run the following CLI command to create the role:

aws iam create-role --role-name iot_sns_role --assume-role-policy-document file://iot-role-trust.json

AWS IoT now needs permission to publish to the Amazon SNS topic we created. Copy and paste the following IAM policy document to create a file named iot-policy.json:

{
    "Version": "2012-10-17",
    "Statement": {
        "Effect": "Allow",
        "Action": "sns:Publish",
        "Resource": "arn:aws:sns:us-west-2:012345678901:door-alert"
    }
}

Run the following CLI command to create the policy:

aws iam create-policy --policy-name iot_sns_policy --policy-document file://iot-policy.json

Then run this CLI command to attach the policy to the role:

aws iam attach-role-policy --role-name iot_sns_role --policy-arn arn:aws:iam::012345678901:policy/iot_sns_policy

Create the AWS IoT Rule

Now we can set up the AWS IoT rule that will trigger a text alert when the bell rings. The rule will perform this task by sending every message that comes across the doorbell topic to Amazon SNS. Copy and paste the following rule definition into a file named sns-rule.json:

{
  "sql": "SELECT * FROM 'doorbell/+'",
  "description": "Sends a message to SNS when a message comes across the 'doorbell' topic",
  "actions": [
    {
      "sns": {
        "targetArn":"arn:aws:sns:us-west-2:012345678901:door-alert",
        "roleArn":"arn:aws:iam::012345678901:role/iot_sns_role",
        "messageFormat": "RAW"
      }
    }
  ],
  "ruleDisabled": false
}

Remember to replace 012345678901 in the rule with your AWS account ID.

Finally, use this CLI command to create the rule:

aws iot create-topic-rule --region us-west-2 --rule-name sendToSNS --topic-rule-payload file://sns-rule.json

Simulate the Doorbell

Everything is now ready to ask the ELF to push the virtual doorbell button. Use the following commands to switch to the AWS IoT ELF directory and get the latest version:

cd ~/dev/aws-iot-elf

git pull

Use this command to activate the ELF’s virtual environment:

source ~/dev/aws-iot-elf/venv/bin/activate

On Windows:

.\venv\Scripts\activate

Use this command to create a thing in the AWS IoT service to serve as our doorbell:

python elf.py --region us-west-2 create 1

The following command will now send a message on the topic as if the ELF pushed the virtual doorbell button.

python elf.py --region us-west-2 send --duration 1 --topic 'doorbell' 'Somebody is at the door!'

Very shortly, your mobile phone should receive a text message similar to this:

DOORBELL> {"msg": "Somebody is at the door!", "ts": "1468958915.41"}

Clean Up

You can use the following commands to clean up your environment:

python elf.py --region us-west-2 clean

aws iam detach-role-policy --role-name iot_sns_role --policy-arn arn:aws:iam::012345678901:policy/iot_sns_policy

aws iam delete-role --role-name iot_sns_role

aws iam delete-policy --policy-arn arn:aws:iam::012345678901:policy/iot_sns_policy

aws iot delete-topic-rule --region us-west-2 --rule-name sendToSNS

aws sns delete-topic --region us-west-2 --topic-arn arn:aws:sns:us-west-2:012345678901:door-alert

If you’d like to clean up the files created in this post, you can remove them from the ~dev/bites/sns directory.

Done!

In this bite, you’ve learned how to use AWS IoT and Amazon SNS together to send near real-time notifications in response to messages that come from a thing.

We hope you found this walk-through useful. Feel free to leave your feedback in the comments.

Stay tuned for the next post in the Bite of IoT series. Until then, may your success be swift and your solution scalable.