AWS IoT Integration
AWS IoT Core is a managed cloud service that acts as an MQTT message broker between IoT devices and the applications that consume their data. AWS IoT Integration connects ThingsBoard to AWS IoT Core over MQTT as a mutually authenticated client: it subscribes to a topic filter, decodes every message with an uplink converter, and stores the resulting telemetry and attributes in ThingsBoard.
Architecture
Section titled “Architecture”ThingsBoard connects to AWS IoT Core as an MQTT client, authenticating with a client certificate and private key issued by AWS IoT. It subscribes to the topic filter configured on the integration and receives every message that devices publish under it; the uplink converter decodes each message into telemetry and attributes, and ThingsBoard provisions the target device automatically on the first message. If a downlink converter is configured, the Rule Engine can also push messages back through that same connection.
Prerequisites
Section titled “Prerequisites”Before creating the integration, ensure:
- You have access to ThingsBoard PE or ThingsBoard Cloud with integration functionality enabled for your tenant.
- You have permissions to create integrations and data converters.
- You have an AWS account with AWS IoT Core enabled.
- Your account has permissions to create IoT policies, things, and certificates in that account.
- Outbound TCP port 8883 is open from the ThingsBoard server to your AWS IoT endpoint (
*.iot.{region}.amazonaws.com).
Configure AWS IoT
Section titled “Configure AWS IoT”Prepare the policy, thing, and certificates in the AWS IoT console before creating the integration in ThingsBoard. The connection uses mutual TLS: ThingsBoard authenticates with a client certificate and private key, and validates the broker with the Amazon Root CA certificate.
Create a Policy
Section titled “Create a Policy”A policy defines which IoT operations (Connect, Publish, Subscribe, Receive) the certificate is permitted to perform. See AWS’s IoT policies documentation for details.
- In the AWS IoT console, go to Security ⇾ Policies and click Create policy.
- Enter a Policy name (e.g.
tb_policy), then click JSON to switch the document editor to JSON mode. - Paste the policy document below, replacing
YOUR_REGIONandYOUR_AWS_IDwith your values. - Click Create.
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": ["iot:Publish", "iot:Receive"], "Resource": ["arn:aws:iot:YOUR_REGION:YOUR_AWS_ID:topic/*"] }, { "Effect": "Allow", "Action": ["iot:Subscribe"], "Resource": ["arn:aws:iot:YOUR_REGION:YOUR_AWS_ID:topicfilter/*"] }, { "Effect": "Allow", "Action": ["iot:Connect"], "Resource": ["arn:aws:iot:YOUR_REGION:YOUR_AWS_ID:client/*"] } ]}Create a Thing and Certificates
Section titled “Create a Thing and Certificates”A thing is the digital representation of a physical device in AWS IoT. ThingsBoard authenticates with the certificate attached to it. See AWS’s Create AWS IoT resources documentation for details.
- Go to All devices ⇾ Things and click Create things.
- Select Create single thing and click Next.
- Enter a Name for the thing (e.g.
tb-bridge-01) and click Next. - Select Auto-generate a new certificate (recommended) and click Next.
- Attach the policy you created and click Create thing.
- Download the required files:
- Device certificate (
*.pem.crt) - Private key (
*-private.pem.key) - Root CA certificate — download Amazon Root CA 1 (
AmazonRootCA1.pem)
- Device certificate (
- Click Done.
Get the Device Data Endpoint
Section titled “Get the Device Data Endpoint”Each AWS account has a unique device data endpoint — the MQTT broker hostname ThingsBoard connects to.
- In the AWS IoT console, click Settings in the left navigation sidebar.
- In the Device data endpoint section, copy the endpoint URL (e.g.
a2ljyhf3dvidme-ats.iot.us-east-1.amazonaws.com) — you will need it when creating the integration.
Required Connection Details
Section titled “Required Connection Details”Collect the values below before creating the ThingsBoard integration.
| Field | Value for this setup | Description |
|---|---|---|
| Endpoint | a2ljyhf3dvidme-ats.iot.us-east-1.amazonaws.com — from Settings ⇾ Device data endpoint | AWS IoT MQTT broker hostname |
| CA certificate | AmazonRootCA1.pem | Amazon Root CA 1, used to validate the broker |
| Device certificate | *.pem.crt | client certificate ThingsBoard authenticates with |
| Private key | *-private.pem.key | private key for the device certificate |
| Topic filter | tb/aws/iot/# | MQTT topic ThingsBoard subscribes to for incoming messages |
Set Up the AWS IoT Integration
Section titled “Set Up the AWS IoT Integration”To set up the AWS IoT integration, first create an uplink data converter to process incoming messages, then create and configure the integration.
Create the Uplink Data Converter
Section titled “Create the Uplink Data Converter”The uplink converter decodes incoming AWS IoT messages and maps them to the ThingsBoard data model. AWS IoT uses a generic uplink converter.
The decoder function receives:
payload— the JSON object decoded from the MQTT messagemetadata—integrationName, the MQTTtopicthe message arrived on, and any key-value pairs configured in the integration’s Metadata settings Sample payload (published to topictb/aws/iot/sensors/freezer-432):
{ "ts": 1718020800000, "temperature": 25.3, "humidity": 62.8, "battery": 78.5, "fwVersion": "1.4.2", "location": { "latitude": 37.7749, "longitude": -122.4194 }}- Go to Integrations center ⇾ Data converters.
- Click + Add data converter ⇾ Create new converter.
In the Add data converter dialog:
- Converter type — leave Uplink (selected by default).
- Integration type — in the search field, enter
AWS IoTand select AWS IoT from the list. - Name — enter a converter name, for example
AWS IoT Uplink Converter. - Main decoding configuration — a code editor with the function signature
function decoder(payload, metadata) {. Paste the decoder function shown below. By default the editor opens in TBEL; use the TBEL / JS toggle (upper right) to switch languages. - Click Add.
The decoder function used in this tutorial derives deviceType and deviceName from the last two MQTT topic segments (here sensors and freezer-432), so it works for any topic depth, then maps the payload to fwVersion/location attributes and temperature/humidity/battery telemetry:
// AWS IoT devices publish to an MQTT topic, which the integration always// provides in metadata. This example derives identity from the LAST two// topic segments, so it works for any topic depth://// tb/aws/iot/sensors/freezer-432// ^^^^^^^ ^^^^^^^^^^// type name//// Extract device information from the last two MQTT topic segments.var topicParts = metadata.topic.split("/");var n = topicParts.length;
// Use fallback values if the topic does not contain enough segments.var deviceName = n > 0 ? topicParts[n - 1] : "AWS IoT Device";var deviceType = n > 1 ? topicParts[n - 2] : "default";
// Decode the incoming payload to a JSON object.var data = decodeToJson(payload);
// Use the device timestamp if provided; otherwise, use the current server time.var ts = data.ts != null ? data.ts : Date.now();
// Map device properties to ThingsBoard attributes.var attributes = { fwVersion: data.fwVersion};
// Add location attributes if available.if (data.location != null) { attributes.latitude = data.location.latitude; attributes.longitude = data.location.longitude;}
// Map device measurements to ThingsBoard telemetry.var telemetry = { temperature: data.temperature, humidity: data.humidity, battery: data.battery};
// Return the converted uplink message.return { deviceName: deviceName, deviceType: deviceType, attributes: attributes, telemetry: { ts: ts, values: telemetry }};// AWS IoT devices publish to an MQTT topic, which the integration always// provides in metadata. This example derives identity from the LAST two// topic segments, so it works for any topic depth://// tb/aws/iot/sensors/freezer-432// ^^^^^^^ ^^^^^^^^^^// type name//// Extract device information from the last two MQTT topic segments.var topicParts = metadata.topic.split("/");var n = topicParts.length;
// Use fallback values if the topic does not contain enough segments.var deviceName = n > 0 ? topicParts[n - 1] : "AWS IoT Device";var deviceType = n > 1 ? topicParts[n - 2] : "default";
// Decode the incoming payload to a JSON object.var data = decodeToJson(payload);
// Use the device timestamp if provided; otherwise, use the current server time.var ts = data.ts != null ? data.ts : Date.now();
// Map device properties to ThingsBoard attributes.var attributes = { fwVersion: data.fwVersion};
// Add location attributes if available.if (data.location != null) { attributes.latitude = data.location.latitude; attributes.longitude = data.location.longitude;}
// Map device measurements to ThingsBoard telemetry.var telemetry = { temperature: data.temperature, humidity: data.humidity, battery: data.battery};
// Build the converted uplink message.var result = { deviceName: deviceName, deviceType: deviceType, attributes: attributes, telemetry: { ts: ts, values: telemetry }};
// Convert the incoming byte array to a string.function decodeToString(payload) { return String.fromCharCode.apply(String, payload);}
// Convert the incoming payload to a JSON object.function decodeToJson(payload) { return JSON.parse(decodeToString(payload));}
// Return the converted uplink message.return result;To adapt this converter to your device:
- Different topic structure — change the segment indices in
metadata.topic.split("/")to match the position of the device type and name in your topic path. - Device name from payload — replace
topicParts[4]with a payload field (e.g.data.deviceId) if the device name is carried in the message body rather than the topic. - Different telemetry fields — add or rename keys in the
telemetryobject to match your payload structure. - Static attributes — add device properties from your payload to the
attributesobject, for examplefirmwareVersion: data.fw. - Update-only keys — in Advanced decoding parameters, add attribute keys that should only be written when their value changes.
Create the AWS IoT Integration
Section titled “Create the AWS IoT Integration”- Go to Integrations center ⇾ Integrations and click +.
- Set Integration type to AWS IoT.
- Enable integration and Allow create devices or assets are on by default.
- Click Next.
- Uplink data converter:
- Click Select existing and choose the previously created
AWS IoT Uplink Converterfrom the list. - Click Next.
- Click Select existing and choose the previously created
- Downlink data converter:
- Leave empty and click Skip — the downlink converter can be added later if needed.
- Connection settings:
- AWS IoT Endpoint — your AWS IoT device data endpoint (e.g.
a2ljyhf3dvidme-ats.iot.us-east-1.amazonaws.com). - Credentials — for each file, click Browse file to upload it, or Use Secret storage to reference a stored secret:
- CA certificate file —
AmazonRootCA1.pem. - Certificate file — the device certificate (
*.pem.crt). - Private key file — the private key (
*-private.pem.key). Leave Private key password blank unless the key is encrypted.
- CA certificate file —
- Add a Topic filter (e.g.
tb/aws/iot/#) — the#wildcard matches all sub-topics. Select QoS level (default: At most once).
- AWS IoT Endpoint — your AWS IoT device data endpoint (e.g.
- Click Add to create the integration.
Credentials
Section titled “Credentials”AWS IoT authentication is always certificate-based (mutual TLS). Each file can be supplied with Browse file or referenced from Secret storage with Use Secret storage:
- CA certificate file — the Amazon Root CA 1 (
AmazonRootCA1.pem) certificate ThingsBoard uses to validate the AWS IoT broker. - Certificate file — the device certificate (
*.pem.crt) issued when you created the thing. - Private key file — the private key (
*-private.pem.key) for that certificate. - Private key password — optional password, only if the private key is encrypted. The certificate must have the policy attached and its status must be Active in the AWS IoT console. See AWS’s X.509 client certificates documentation for details.
Connection Settings
Section titled “Connection Settings”AWS IoT Endpoint
Your AWS IoT device data endpoint in the format {prefix}-ats.iot.{region}.amazonaws.com. Find it in the AWS IoT console under Settings ⇾ Device data endpoint. ThingsBoard connects to it over MQTT on port 8883.
Credentials
The client certificate, private key, and Amazon Root CA certificate used for the mutual-TLS MQTT connection. See Credentials above.
Topic Filters
The MQTT topics ThingsBoard subscribes to for incoming messages. Each topic filter has its own QoS, and you can add several with Add topic filter. Two wildcard types are supported:
- Single-level
+— matches one topic level, e.g.tb/aws/iot/+/telemetry. - Multi-level
#— replaces the rest of the topic and must be the last symbol, e.g.tb/aws/iot/#. Use a namespace dedicated to ThingsBoard rather than a bare#, so the integration only receives the traffic it should:
| Topic | Description |
|---|---|
tb/aws/iot/# | All messages published under the tb/aws/iot/ namespace |
tb/aws/iot/sensors/# | Only messages from devices of type sensors |
See AWS’s MQTT topics documentation for details.
QoS
The MQTT quality of service level for each topic filter:
0 - At most once— default; fire-and-forget delivery, no acknowledgement.1 - At least once— the broker redelivers until acknowledged; messages may be duplicated. AWS IoT Core does not support QoS 2.
Execute Remotely
When enabled, ThingsBoard generates an Integration key and Integration secret that allow the integration to run as a separate process outside the ThingsBoard cluster — useful when the AWS IoT endpoint is only reachable from a restricted network.
Advanced Settings
| Parameter | Default | Description |
|---|---|---|
| Protocol version | MQTT 3.1.1 | MQTT protocol version used for the broker connection. |
| Client ID | — | Optional. Leave empty for an auto-generated client ID. Most MQTT brokers reject multiple connections that share a client ID, so if you set one, make it unique. |
| Max bytes in message | 32368 | Maximum message payload size in bytes. Messages exceeding this limit are dropped. |
| Connection timeout (sec) | 10 | Seconds ThingsBoard waits for a broker response before marking the connection as failed. |
| Downlink topic pattern | ${topic} | Topic the integration publishes downlinks to. Supports ${...} substitution from message metadata. See Configure Downlink. |
| Description | — | Optional text description for the integration. |
| Metadata | — | Key-value pairs injected into every message as integrationMetadata in the converter script. |
Test Uplink
Section titled “Test Uplink”Send Test Uplink
Section titled “Send Test Uplink”Publish a message to the subscribed topic using the AWS IoT MQTT test client or the AWS CLI.
- In the AWS IoT console, go to MQTT test client ⇾ Publish to a topic.
- Enter the topic
tb/aws/iot/sensors/freezer-432. - Paste the JSON payload into the message body.
- Click Publish.
{ "ts": 1718020800000, "temperature": 25.3, "humidity": 62.8, "battery": 78.5, "fwVersion": "1.4.2", "location": { "latitude": 37.7749, "longitude": -122.4194 }}Requires the aws iot-data command. Replace the endpoint and topic if they differ:
aws iot-data publish \--topic "tb/aws/iot/sensors/freezer-432" \--cli-binary-format raw-in-base64-out \--payload '{"ts":1718020800000,"temperature":25.3,"humidity":62.8,"battery":78.5,"fwVersion":"1.4.2","location":{"latitude":37.7749,"longitude":-122.4194}}'Verify Integration Events
Section titled “Verify Integration Events”Go to Integrations center ⇾ Integrations, open the AWS IoT integration, and check the Events tab. One Uplink event appears with status OK. Click … in the Message column to inspect the raw payload and the topic received from the broker.
Verify Converter Events
Section titled “Verify Converter Events”Go to Integrations center ⇾ Data converters, click the uplink converter, and open its Events tab. Click … in the respective column to inspect each field:
- In — the raw payload passed to the converter.
- Out — the decoded result:
deviceName,deviceType,attributes(fwVersion, andlatitude/longitudewhen the payload includes alocation), andtelemetry(temperature, humidity, battery). - Metadata —
integrationNameand the MQTTtopicthe message arrived on.
Verify Device Provisioning
Section titled “Verify Device Provisioning”Go to Entities ⇾ Devices. The device freezer-432 of type sensors is automatically provisioned on the first message. Open it and check the Latest telemetry tab — you should see temperature, humidity, and battery — and the Attributes tab for fwVersion (and latitude/longitude if the payload included a location).
Configure Downlink
Section titled “Configure Downlink”A downlink sends a Rule Engine message — a shared attribute update, an RPC command, or any other message you route to the integration — from ThingsBoard to AWS IoT. The integration publishes it to the downlink topic configured on the converter, where any subscribed device receives it.
Create the Downlink Converter
Section titled “Create the Downlink Converter”The downlink converter encodes a Rule Engine message into the payload published to AWS IoT. AWS IoT uses a generic downlink converter.
The encoder function receives:
msg— the JSON message payload from the Rule EnginemsgType— the Rule Engine message type, e.g.ATTRIBUTES_UPDATEDorPOST_TELEMETRY_REQUESTmetadata— key-value pairs with additional message dataintegrationMetadata— key-value pairs from the integration’s Metadata settings
- Go to Integrations center ⇾ Data converters.
- Click + Add data converter ⇾ Create new converter.
- Converter type — switch the toggle to Downlink.
- Integration type — enter
AWS IoTin the search field and select it from the list. - Name — enter a converter name, for example
AWS IoT Downlink Converter. - Main encoding configuration — paste the encoder function shown below.
- Click Add.
// Encode downlink data from incoming Rule Engine message
// msg - JSON message payload downlink message json// msgType - type of message, for ex. 'ATTRIBUTES_UPDATED', 'POST_TELEMETRY_REQUEST', etc.// metadata - list of key-value pairs with additional data about the message// integrationMetadata - list of key-value pairs with additional data defined in Integration executing this converter
/** Encoder **/
var data = {};
// Process data from incoming message and metadatadata.v0 = msg.state;data.m0 = "att_upd_success";data.devSerialNumber = metadata['ss_serialNumber'];
// Result object with encoded downlink payloadvar result = { // downlink data content type: JSON, TEXT or BINARY (base64 format) contentType: "JSON", // downlink data data: JSON.stringify(data), // Optional metadata object presented in key/value format metadata: { type: "sensors/device/upload" }};
return result;// Encode downlink data from incoming Rule Engine message
// msg - JSON message payload downlink message json// msgType - type of message, for ex. 'ATTRIBUTES_UPDATED', 'POST_TELEMETRY_REQUEST', etc.// metadata - list of key-value pairs with additional data about the message// integrationMetadata - list of key-value pairs with additional data defined in Integration executing this converter
/** Encoder **/
var data = {};
// Process data from incoming message and metadatadata.v0 = msg.state;data.m0 = "att_upd_success";data.devSerialNumber = metadata['ss_serialNumber'];
// Result object with encoded downlink payloadvar result = { // downlink data content type: JSON, TEXT or BINARY (base64 format) contentType: "JSON", // downlink data data: JSON.stringify(data), // Optional metadata object presented in key/value format metadata: { type: "sensors/device/upload" }};
return result;To adapt this converter to your consumer:
- Different envelope — replace the
dataobject with whatever structure the device expects; onlycontentTypeanddataare required in the result. - Pass the payload through unchanged — return
data: JSON.stringify(msg)and drop the field mapping. - Non-JSON payload — set
contentTypetoTEXTfor a plain string, orBINARYwith a Base64-encoded string for raw bytes. - Extra message types — branch on
msgTypeto handle other Rule Engine message types you route to the integration.
Assign the Downlink Converter
Section titled “Assign the Downlink Converter”- Go to Integrations center ⇾ Integrations and open the AWS IoT integration.
- Click Toggle edit mode.
- In the Downlink data converter field, select
AWS IoT Downlink Converter. - Expand the connection Advanced settings and set the Downlink topic pattern to
tb/aws/iot/commands/${deviceName}— this publishes each command to a per-device topic under the same namespace as the uplink. - Click Apply changes.
Configure the Root Rule Chain
Section titled “Configure the Root Rule Chain”The integration does not send anything on its own — a rule chain must forward messages to it.
- Go to Rule chains and open the Root Rule Chain.
- In the node palette on the left, search for integration downlink (under Action) and drag it onto the canvas.
- In the Add rule node dialog, enter a Name (e.g.
Downlink to AWS IoT integration), select your AWS IoT integration, and click Add. - Connect the Message Type Switch node to the new node using the Post attributes and Attributes Updated relations, so downlinks trigger whenever shared attributes are created or updated.
- Click Apply changes.
Trigger a Downlink
Section titled “Trigger a Downlink”- In the AWS IoT console, go to MQTT test client ⇾ Subscribe to a topic, enter
tb/aws/iot/commands/#, and click Subscribe. - In ThingsBoard, go to Entities ⇾ Devices and open
freezer-432. - Open the Attributes tab, set the scope to Shared attributes, and click +.
- Enter key
powerState, keep type String, enter valueon, and click Add.
Adding the attribute generates an Attributes Updated message that reaches the integration downlink node. The encoded payload appears on the tb/aws/iot/commands/freezer-432 topic in the MQTT test client within a second or two.
Verify Downlink Delivery
Section titled “Verify Downlink Delivery”Check Downlink Converter Events
Go to Integrations center ⇾ Data converters, open the downlink converter, and check its Events tab. Click … in the respective column to inspect each field:
- In — the Rule Engine message passed to the encoder.
- Out — the encoded result:
contentType,data, andmetadata.
Check Downlink Subscribed Topic
Check the subscribed topic in the AWS MQTT test client — the downlink payload should appear:
Troubleshooting
Section titled “Troubleshooting”| Symptom | Likely cause | Fix |
|---|---|---|
| Integration status is not Active | Wrong Endpoint | Confirm it matches the AWS IoT device data endpoint exactly, in the form {prefix}-ats.iot.{region}.amazonaws.com. |
| Integration status is not Active | Certificate or private key mismatch | Verify the uploaded device certificate and private key belong together and match the thing in the AWS IoT console. |
| Integration status is not Active | Certificate inactive or policy not attached | In the AWS IoT console, confirm the certificate status is Active and the policy is attached to it. |
| Integration status is not Active | Port 8883 blocked | Open outbound TCP 8883 to *.iot.{region}.amazonaws.com, or run the integration remotely — see Remote Integration. |
| Messages published in AWS never arrive | Topic filter does not match | Ensure the integration’s topic filter covers the published topic — e.g. tb/aws/iot/# matches tb/aws/iot/sensors/freezer-432. |
| Messages published in AWS never arrive | Policy denies Subscribe / Receive | Confirm the policy allows iot:Subscribe and iot:Receive for the relevant topic filters. |
| Messages received but not decoded | Converter does not match the payload | Inspect Converter Events → In and adjust the decoder — especially the topic segment indices — to the actual message format. |
| Large messages dropped | Max bytes in message limit | Raise the limit in Advanced settings, keeping the AWS IoT 128 KB message ceiling in mind. |
| Device not created | Allow create devices or assets disabled | Open the integration, click the edit icon, and enable Allow create devices or assets. |
| Downlink produces no event | Rule chain never reaches the node | Check the relation feeding the integration downlink node and enable rule chain debug mode to trace the message. |
| Downlink encoded but nothing in AWS | Wrong Downlink topic pattern or subscription | Confirm the integration’s Downlink topic pattern resolves to the topic subscribed to in the MQTT test client (e.g. tb/aws/iot/commands/${deviceName} → tb/aws/iot/commands/freezer-432). |
See Also
Section titled “See Also”- Integrations Overview — how ThingsBoard connects to external platforms and how uplink/downlink flow works
- Uplink Data Converter — full decoder function reference: input parameters, output fields, and scripting patterns
- Downlink Data Converter — full encoder function reference
- Integration Downlink Rule Node — forward Rule Engine messages to an integration
- Remote Integration — run the integration outside the ThingsBoard server to reach a broker on a restricted network
- TBEL scripting reference — built-in functions and operators for writing converter scripts
- Rule Engine — how rule chains route messages to nodes like the Integration Downlink node
Was this helpful?