Connecting Raspberry Pi Zero with Amazon Web Services IoT — Part I: Working with AWS IoT

goMake
7 min readAug 3, 2017

--

This post is by Morris Singer, who provides cloud infrastructure architecture expertise to GoMake.

This tutorial is part of a three-part series on using a Raspberry Pi Zero with Amazon Web Services (AWS) IoT. In the first part, I will walk through setting up Amazon IoT to communicate with the Pi. In the second part, I will change gears and work through provisioning the Raspberry Pi Zero. In the final part, I will walk through installing the AWS IoT Device SDK and running one of the sample application on the Pi that will demonstrate communication with AWS.

Before I get started, I’d like to take a step back and explore why this is even important. Perhaps some readers will be very familiar with all of the components involved and will look to this tutorial for some guidance in setting up the pieces. For others, however, particularly those new to IoT, some introduction to basic IoT systems architecture in general and in the context of AWS may be beneficial.

What is the Internet of Things

The Internet of Things (IoT) represents the growth of the Internet into a platform for providing connectivity between electronics, software, sensors, and actuators embedded into physical devices. IoT allows the physical world to be more directly integrated into the Internet, providing opportunities to improve efficiency, accuracy and control of our physical world via existing networks.

Designing and implementing IoT systems comes with numerous challenges. One of the main ones is the interdisciplinary expanse of the technical demands, which range from sensor design, hardware and electronics design and manufacture, low-level programming for resource-limited devices, complex security considerations, provisioning and orchestration, addressing limited connectivity and harsh deployment conditions, cloud infrastructure architecture and dev-ops activities, big data pipeline development, machine learning, and the development of back-end software systems.

Delegating some of these responsibilities to public cloud providers has made the design of IoT systems far more feasible both economically and in terms of technical complexity. Perhaps the most comprehensive set of cloud offerings in this space is available from AWS, and that is where this tutorial will focus.

On the opposite end of an IoT system, the implementation of sensors and actuators and the small computers that drive them can be simplified through the use of certain devices such as the Raspberry Pi, a $5 ARM processor that runs an open-source distribution of Linux.

As such, this tutorial will focus on these two ends: AWS IoT on one end, and the Raspberry Pi on the other. The tutorial will walk the reader through the intervening steps between these two ends and how to set them up so that they work properly, efficiently, securely, and cost-effectively.

What is AWS IoT

AWS IoT is a platform for providing bi-directional communication between Internet-connected devices and the cloud. It provides the following components:

  • Device Gateway: enables devices and applications to communicate with one another.
  • Message Broker: publish-subscribe mechanism over which devices communicate.
  • AWS Integration: seamless integration with other AWS offerings like Lambda, DynamoDB and S3.
  • Shadows: persistent object-based representations of device state and managed data.
  • Security: industry-standard encryption and request signing, mapped to entitlements across AWS’s comprehensive suite of infrastructure and software.

Prerequisits

This tutorial assumes that you have downloaded and installed the AWS CLI and that is is configured with the proper credentials for your AWS account or IAM user.

For more information on that step, see Installing the AWS Command Line Interface — AWS Command Line Interface.

Setting Up AWS IoT

Setting up AWS IoT can be divided into five broad steps. One must:

  1. Register a device (such as a Raspberry Pi) with the IoT service. Such devices are known as Things.
  2. Create a Certificate and key pair which a device can use to securely authenticate with the AWS IoT service.
  3. Create a Policy which allows an authenticated device to access a specific set of resources in AWS.
  4. Attach the Certificate to the Policy and to the Thing.
  5. Obtain the URL of the endpoint that Things should use to communicate with AWS IoT.

I will discuss each of these steps, individually, below.

Register a Device, Create a Thing

The first step is to create a new Thing. A thing is the most basic representation of a device (specific IoT hardware) in the AWS IoT service. In this case, it is the Raspberry Pi you’ll be working with later in this series.

To create a Thing, use the create-thing command:

aws iot create-thing —-thing-name=mything

The response you receive, if successful, includes both the name of the Thing and a unique identifer, called an ARN. For example, when running the above command, you may receive a response similar to the following:

{
“thingArn”: “arn:aws:iot:us-east-1:012345678901:thing/mything”,
“thingName”: “mything”
}

It may be useful to copy down the ARN for future reference as you continue with this process.

Create a Certificate and Key Pair

Security is provided by a mapping of a Thing to a Policy, and a mapping of Policy to specific Statements (which are, themselves, an association of an Action and (optionally) a specific ARN of a resource in AWS). Optionally, you can also map a Thing directly to a Certificate, which may provide some specific advantages depending on your use case.

Create the x.509 Certificate, Public Key, and Private Key; Download the root CA Certificate

Create and download a public key, private key, and certificate. These items are used during the authentication process and allow your Thing to communicate securely with AWS IoT.

To create these files, use the create-keys-and-certificate command:

aws iot create-keys-and-certificate — set-as-active —-certificate-pem-outfile=cert.crt —-public-key-outfile=pubkey.pem —-private-key-outfile=privkey.pem

The output will look similar to the following:

{
“certificateId”: “1c15fa7b78b08aa1c19e4548fa9a322242d624f4bc05d2e1d6a343af010c58a8”,
“certificatePem”: “——-BEGIN CERTIFICATE——-[CERTIFICATE CONTENTS] ——-END CERTIFICATE——-\n”,
“certificateArn”: “arn:aws:iot:us-east-1:012345678901:cert/1c15fa7b78b08aa1c19e4548fa9a322242d624f4bc05d2e1d6a343af010c58a8”,
“keyPair”: {
“PrivateKey”: “——-BEGIN RSA PRIVATE KEY——-[PRIVATE KEY CONTENTS]——-END RSA PRIVATE KEY——-\n”,
“PublicKey”: “ ——-BEGIN PUBLIC KEY——-[PUBLIC KEY CONTENTS]——-END PUBLIC KEY——-\n”
}
}

Retain this output for your records, as some of the information it contains will be needed in subsequent steps.

You will also need the VeriSign Class 3 Public Primary G5 root CA certificate, which you can download here.

Briefly, AWS IoT uses asymmetric cryptography to ensure that devices are allowed to communicate with AWS, and also to ensure that devices communicate with AWS and not an imposture. For more information, see:

Create a Policy

While an x.509 certificate authenticates a device, allowing it to communicate with AWS IoT, it is policies that allow access to resources on AWS, including within AWS IoT, such as subscribing or publishing to MQTT topics.

Any Thing that presents the certificate can have the actions specified in the attached policy. So, if you want your Thing to be able to publish to an MQTT topic, then you should attach a policy with that action to the certificate.

You should start by creating a policy. For the purposes of this post, the policy will be set with expansive entitlements within the iot space. For production applications, you will want to tune your policies so that the security is more finely grained.

Create a new file, mypolicy.json, with the following JSON data:

{
“Version”: “2012–10–17”,
“Statement”: [
{
“Effect”: “Allow”,
“Action”: “iot:*”,
“Resource”: “*”
}
]
}

Next, use that JSON document to create the policy on AWS IoT:

aws iot create-policy —-policy-name=mypolicy —-policy-document=”$(cat mypolicy.json)”

The response will look something like:

{
“policyName”: “mypolicy”,
“policyVersionId”: “1”,
“policyDocument”: “{\n \”Version\”: \”2012–10–17\”,\n \”Statement\”: [\n {\n \”Effect\”: \”Allow\”,\n \”Action\”: \”iot:*\”,\n \”Resource\”: \”*\”\n }\n ]\n}”,
“policyArn”: “arn:aws:iot:us-east-1:012345678901:policy/mypolicy”
}

Retain this output for now, as we will reference some of this information in subsequent steps.

For more information on structuring policies for AWS IoT, see Create an AWS IoT Policy — AWS IoT.

Attach the Certificate to the Thing

Locate the ARN of the certificate you created, above. Use the attach-thing-principal command to attach the certificate to the Thing, supplying the certificate ARN and the name of the Thing:

aws iot attach-thing-principal —-thing-name mything —-principal arn:aws:iot:us-east-1:012345678901:cert/1c15fa7b78b08aa1c19e4548fa9a322242d624f4bc05d2e1d6a343af010c58a8

You will get no response from executing this command unless there is an error.

Attach the Certificate to the Policy

Use the attach-principal-policy command to attach the certificate to the Policy, supplying the certificate ARN and the name of the Thing:

aws iot attach-principal-policy —-policy-name mypolicy —-principal arn:aws:iot:us-east-1:012345678901:cert/1c15fa7b78b08aa1c19e4548fa9a322242d624f4bc05d2e1d6a343af010c58a8

Obtain the IoT Endpoint

Your device will communicate with AWS IoT via an endpoint, which you can obtain using the describe-endpoint command:

aws iot describe-endpoint

The response will be similar to the following:

{
“endpointAddress”: “a28mxzifscn480.iot.us-east-1.amazonaws.com”
}

Retain this endpoint address, as you will need it to configure your device in subsequent steps.

Next Steps

In the next section, I will go through how to provision a Raspberry Pi Zero so that it is ready to communicate with the AWS IoT service, given the infrastructure that you deployed in the above steps.

--

--

goMake

Through project-based learning, goMake empowers students to build, launch, recover, and analyze data from high-altitude balloons.