The basic building blocks of AWS IoT Core
The components you'll need to connect a device to AWS via MQTT
IoT Core is the service to use when you want to connect devices, usually something physical and small, to the cloud. The platform provides a lot of functionality via different resources and while having a lot of features is good it also makes it harder to understand what is needed to get started.
In this article, we'll discuss a few basic building blocks that together allow you to connect things to the cloud.
MQTT
MQTT is the industry-standard communication protocol that was designed for resource-constrained devices. It offers a pub/sub model where participants can publish messages to topics, and interested parties can subscribe to get real-time notifications.
A topic is an arbitrary path with levels separated by /
and the payload is the message sent to these topics. For example, a sensor might publish to
sensors/temperature
the current value from the temperature sensor, while another device can use the sensors/light
topic. What topics are used by the
devices and what they publish is up to the implementations.
MQTT works over TCP and TLS, but not HTTP. This means browsers can't directly connect to MQTT endpoints. IoT Core provides a WebSocket endpoint for this as a tunnel.
Certificate
When a device connects to IoT Core, AWS needs to identify it. Instead of relying on a username and a password, this is done by registering a certificate in advance. Then during the connection, AWS checks this certificate to see if the device should be allowed to connect.
A certificate always has a private key. This is known only to the device and keeping it private ensures that malicious parties can't impersonate it. Usually, the private key is added to the device via a hardware chip, called a secure element. This adds tamper-resistance, which means the private key can not be cloned. In effect, only who has the device itself can connect to IoT Core.
This setup is the standard for security. By adding physical protection to the private key and registering the certificate in advance means an attacker needs to steal the device to impersonate it.
Thing
A thing is AWS's notion of something that can connect to IoT Core and other components rely on having a thing per physical device.
A thing and a certificate needs to be associated, so that when a device connects AWS can first check the certificate then expose higher-level functionality to
it. This part complicates the flow a bit, as the assocation between the thing and the certificate is many-to-many. Because of this, the device needs to indicate
which thing it is, which is done by the clientId
of the MQTT connection:
const opt = {
host: IOT_ENDPOINT,
protocol: "mqtt",
clientId: THING_NAME, // <== clientId identifies the thing by its name
clean: true,
key: KEY,
cert: CERT,
ca: CA,
reconnectPeriod: 0,
};
const client = connect(opt);
IoT Policy
When a device connects, it has the ability to read and write data in all topics, even those for unrelated devices. Since usually the device is shipped to customers its security can be compromised. Leaving all of them able to read and change all data might pose a security problem.
This is where IoT policies come into play. A policy defines how devices can connect and what topics they can publish and subscribe to. With a tight enough policy it is possible to define walled gardens for each device and to provide access for only the information it needs.
Shadow
MQTT by default does not provide any structure to the topics, which means you need to define and enforce a naming rule. IoT Core shadows provides an opt-in standard structure that is based on best practices.
Shadows are organized as a reported and a desired state. The former is set by the device, and provides a way to send data to the cloud. Then the latter allows the cloud to manage the state of the device. For example, a temperature sensor writes to the reported state, while a light bulb reads from the desired one.
Shadows define their MQTT topics for the device to interact with. To read the current state, they can publish a message to
$aws/things/<thingName>/shadow/name/<shadowName>/get
then get back the response at $aws/things/<thingName>/shadow/name/<shadowName>/get/accepted
.
Opting in for shadows is a best practice for most apps.
Topic Rule
Topic rules are a mechanism for the cloud to react to messages published to MQTT topics. For example, it can run a Lambda function whenever a temperature sensor publishes a new value, or it can write the measurement directly to a DynamoDB table. With topic rules, you can define arbitrary event-driven processing for messages coming from devices.
A rule define a query in an SQL-like syntax that defines what topics and messages should trigger it and how to transform the data. Then the event targets define what service to call with the message.
SELECT *
FROM '$aws/things/+/shadow/name/+/update/documents'
WHERE isNull(previous) OR previous.state.reported.value <> current.state.reported.value