IoT
Categories:
4 minute read
Introduction
AWS IoT provides cloud services to manage IoT devices and integrate them with other AWS services.
LocalStack Pro supports IoT Core, IoT Data, IoT Analytics. Common operations for creating and updating things, groups, policies, certificates and other entities are implemented with full CloudFormation support. The supported APIs are available on our API coverage page.
LocalStack ships a Message Queuing Telemetry Transport (MQTT) broker powered by Eclipse Mosquitto which supports both pure MQTT and MQTT-over-WSS (WebSockets Secure) protocols.
Getting Started
This guide is for users that are new to IoT and assumes a basic knowledge of the AWS CLI and LocalStack awslocal
wrapper.
Start LocalStack using your preferred method.
To retrieve the MQTT endpoint, use the DescribeEndpoint
operation.
$ awslocal iot describe-endpoint
{
"endpointAddress": "000000000000.iot.eu-central-1.localhost.localstack.cloud:4510"
}
Tip
LocalStack lazy-loads services by default. The MQTT broker may not be automatically available on a fresh launch of LocalStack. You can make aDescribeEndpoint
call to start the broker and identify the port.This endpoint can then be used with any MQTT client to publish and subscribe to topics. In this example, we will use the Hive MQTT CLI.
Run the following command to subscribe to an MQTT topic.
$ mqtt subscribe \
--host 000000000000.iot.eu-central-1.localhost.localstack.cloud \
--port 4510 \
--topic climate
In a separate terminal session, publish a message to this topic.
$ mqtt publish \
--host 000000000000.iot.eu-central-1.localhost.localstack.cloud \
--port 4510 \
--topic climate \
-m "temperature=30°C;humidity=60%"
This message will be pushed to all subscribers of this topic, including the one in the first terminal session.
Authentication
LocalStack IoT maintains its own root certificate authority which is regenerated at every run. The root CA certificate can be retrieved from http://localhost.localstack.cloud:4566/_aws/iot/LocalStackIoTRootCA.pem.
Tip
AWS provides its root CA certificate at https://www.amazontrust.com/repository/AmazonRootCA1.pem. This section contains information about CA certificates.When connecting to the endpoints, you will need to provide this root CA certificate for authentication. This is illustrated below with Python AWS IoT SDK,
import awscrt
import boto3
from awsiot import mqtt_connection_builder
region = 'eu-central-1'
iot_client = boto3.client('iot', region=region)
endpoint = aws_client.iot.describe_endpoint()["endpointAddress"]
endpoint, port = endpoint.split(':')
event_loop_group = io.EventLoopGroup(1)
host_resolver = io.DefaultHostResolver(event_loop_group)
client_bootstrap = io.ClientBootstrap(event_loop_group, host_resolver)
credentials_provider = awscrt.auth.AwsCredentialsProvider.new_static(
access_key_id='...',
secret_access_key='...',
)
client_id = 'example-client'
# Path to root CA certificate downloaded from `/_aws/iot/LocalStackIoTRootCA.pem`
ca_filepath = '...'
mqtt_over_wss = mqtt_connection_builder.websockets_with_default_aws_signing(
region=region,
credentials_provider=credentials_provider,
client_bootstrap=client_bootstrap,
client_id=client_id,
endpoint=endpoint,
port=port,
ca_filepath=ca_filepath,
)
mqtt_over_wss.connect().result()
mqtt_over_wss.subscribe(...)
If you are using pure MQTT, you also need to set the client-side X509 certificates and Application Layer Protocol Negotiation (ALPN) for a successful mutual TLS (mTLS) authentication. This is not required for MQTT-over-WSS since it does not use mTLS.
AWS IoT SDKs automatically set the ALPN when the endpoint port is 443. However, because LocalStack does not use this port, this must be done manually. For details on how ALPN works with AWS, see this page.
The client certificate and key can be retrieved using CreateKeysAndCertificate
operation.
The certificate is signed by the LocalStack root CA.
result = iot_client.create_keys_and_certificate(setAsActive=True)
# Path to file with saved content `result["certificatePem"]`
cert_file = '...'
# Path to file with saved content `result["keyPair"]["PrivateKey"]`
priv_key_file = '...'
tls_ctx_options = awscrt.io.TlsContextOptions.create_client_with_mtls_from_path(
cert_file, priv_key_file
)
tls_ctx_options.alpn_list = ["x-amzn-mqtt-ca"]
mqtt = mqtt_connection_builder._builder(
tls_ctx_options,
cert_filepath=cert_file,
pri_key_filepath=priv_key_file,
client_bootstrap=client_bootstrap,
client_id=client_id,
endpoint=endpoint,
port=port,
ca_filepath=ca_filepath,
)
mqtt.connect().result()
mqtt.subscribe(...)
Lifecycle Events
LocalStack publishes the lifecycle events to the standard endpoints.
$aws/events/presence/connected/clientId
: when a client connects$aws/events/presence/disconnected/clientId
: when a client disconnects$aws/events/subscriptions/subscribed/clientId
: when a client subscribes to a topic$aws/events/subscriptions/unsubscribed/clientId
: when a client unsubscribes from a topic
Currently the principalIdentifier
and sessionIdentifier
fields in event payload contain dummy values.
Registry Events
LocalStack can publish the registry events, if you enable it.
$ awslocal iot update-event-configurations \
--event-configurations '{"THING":{"Enabled": true}}'
You can then subscribe or use topic rules on the follow topics:
$aws/events/thing/<thingName>/created
: when a new thing is created$aws/events/thing/<thingName>/updated
: when a thing is updated$aws/events/thing/<thingName>/deleted
: when a thing is deleted
Topic Rules
It is possible to use actions with SQL queries for IoT Topic Rules.
For example, you can use the CreateTopicRule
operation to define a topic rule with a SQL query SELECT * FROM 'my/topic' where attr=123
which will execute a trigger whenever a message with attribute attr=123
is received on the MQTT topic my/topic
.
The following actions are supported: