Connecting your ESP32 to AWS IoT Core takes your IoT projects from local network experiments to enterprise-grade, globally accessible cloud applications. AWS IoT Core is Amazon’s managed cloud platform for IoT devices — it handles device authentication, message routing, data storage, and integration with the rest of the AWS ecosystem (Lambda, DynamoDB, S3, SNS, and more). For Indian makers and startups building IoT products, AWS IoT Core provides a professional, scalable foundation at a very affordable cost.
In this complete tutorial, we will walk through every step of connecting an ESP32 with a temperature sensor to AWS IoT Core — from creating the AWS certificates to publishing sensor data via MQTT and visualising it in AWS.
What is AWS IoT Core?
AWS IoT Core is a fully managed cloud service that lets connected devices securely interact with cloud applications and other devices. It can support billions of devices and trillions of messages, scaling automatically with your needs. For individual makers and small IoT projects, it operates on a pay-per-use model where the free tier covers 500,000 MQTT messages per month — more than enough for a single sensor publishing every 10 seconds.
Key features of AWS IoT Core:
- Mutual TLS authentication: Each device has a unique X.509 certificate. No username/password that can be stolen — much more secure than most IoT platforms.
- MQTT broker: Supports standard MQTT 3.1.1 and 5.0 protocol at scale.
- IoT Rules Engine: Route messages to DynamoDB, S3, Lambda, SNS, SQS, and other AWS services using SQL-like rules.
- Device Shadow: A JSON document that stores the last reported state of a device, allowing apps to query device state even when it is offline.
- AWS region ap-south-1 (Mumbai): Using the Mumbai region minimises latency for Indian projects.
Setting Up AWS IoT Core
Before writing any Arduino code, you need to create your device (called a “Thing”) in the AWS console:
- Log in to the AWS Management Console and navigate to IoT Core (search for it in the services menu).
- In the left sidebar, go to Manage → All devices → Things and click Create things.
- Select Create a single thing, give it a name (e.g.,
esp32-sensor-01), and click Next. - On the certificate page, select Auto-generate a new certificate.
- Create a new policy (or attach an existing one) — see the policy JSON below.
- Download all four files: device certificate, private key, public key, and the Amazon Root CA 1.
The IoT policy defines what your device is allowed to do. A basic policy that allows publishing and subscribing:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"iot:Connect",
"iot:Publish",
"iot:Subscribe",
"iot:Receive"
],
"Resource": "arn:aws:iot:ap-south-1:YOUR_ACCOUNT_ID:*"
}
]
}
Replace YOUR_ACCOUNT_ID with your 12-digit AWS account ID. For production, scope the Resource ARN to specific topic ARNs for tighter security.
Creating Device Certificates
AWS IoT Core uses mutual TLS — both the server and the device verify each other’s identity using certificates. You now have three certificate files that need to be embedded in your ESP32 sketch:
- Amazon Root CA 1: The root certificate that verifies AWS’s identity. Download from
https://www.amazontrust.com/repository/AmazonRootCA1.pem. - Device certificate (.pem.crt): Proves your ESP32’s identity to AWS.
- Private key (.pem.key): Used to sign TLS handshake messages. Never share this file.
Store these as C string constants in a header file called aws_certificates.h. Each line of the PEM file becomes a line in a multiline C string. This approach keeps sensitive credentials out of your main sketch file, making it safer to share your code (just exclude the certificates file from version control).
Ai Thinker NodeMCU-32S ESP32 Development Board – IPEX Version
The ideal ESP32 board for AWS IoT Core projects — 4MB flash stores TLS certificates comfortably, dual-core CPU handles TLS handshake without blocking sensor reads.
ESP32 Libraries for AWS IoT
You need two Arduino libraries:
- PubSubClient by Nick O’Leary: The standard Arduino MQTT client library. Install via Arduino Library Manager.
- ArduinoJson by Benoit Blanchon: For formatting sensor data as JSON payloads. Install via Arduino Library Manager.
The ESP32 Arduino core includes WiFiClientSecure natively, which handles TLS/SSL connections. You will use this as the underlying network client for PubSubClient.
Complete Arduino Code
Here is a complete, production-ready sketch that connects to AWS IoT Core and publishes sensor data every 10 seconds:
#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <PubSubClient.h>
#include <ArduinoJson.h>
#include "aws_certificates.h" // Contains rootCA, deviceCert, privateKey
// Wi-Fi credentials
const char* ssid = "YourWiFiSSID";
const char* password = "YourWiFiPassword";
// AWS IoT Core endpoint (from IoT Core → Settings → Device data endpoint)
const char* awsEndpoint = "XXXXXXXXXX.iot.ap-south-1.amazonaws.com";
const int awsPort = 8883;
// MQTT topics
const char* pubTopic = "esp32/sensors/data";
const char* subTopic = "esp32/sensors/commands";
WiFiClientSecure espClient;
PubSubClient mqttClient(espClient);
void messageReceived(char* topic, byte* payload, unsigned int length) {
Serial.print("Message on topic: ");
Serial.println(topic);
// Handle incoming commands here
}
void connectToAWS() {
espClient.setCACert(rootCA);
espClient.setCertificate(deviceCert);
espClient.setPrivateKey(privateKey);
mqttClient.setServer(awsEndpoint, awsPort);
mqttClient.setCallback(messageReceived);
Serial.print("Connecting to AWS IoT Core...");
while (!mqttClient.connected()) {
if (mqttClient.connect("esp32-sensor-01")) {
Serial.println(" connected!");
mqttClient.subscribe(subTopic);
} else {
Serial.print(".");
delay(1000);
}
}
}
void setup() {
Serial.begin(115200);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("nWi-Fi connected");
connectToAWS();
}
void publishSensorData(float temperature, float humidity) {
JsonDocument doc;
doc["deviceId"] = "esp32-sensor-01";
doc["temperature"] = temperature;
doc["humidity"] = humidity;
doc["timestamp"] = millis();
char payload[200];
serializeJson(doc, payload);
mqttClient.publish(pubTopic, payload);
Serial.println(payload);
}
void loop() {
if (!mqttClient.connected()) {
connectToAWS();
}
mqttClient.loop();
// Publish sensor data every 10 seconds
static unsigned long lastPublish = 0;
if (millis() - lastPublish > 10000) {
lastPublish = millis();
// Replace with actual sensor readings
publishSensorData(28.5, 65.0);
}
}
Adding Temperature and Humidity Sensors
The most common sensor additions for an AWS IoT project are temperature and humidity sensors. Here is how to integrate the popular DHT family:
DHT20 SIP Packaged Temperature and Humidity Sensor
The DHT20 is the upgraded version of DHT11/DHT22, using I2C interface for more reliable readings — perfect for AWS IoT Core sensor data projects.
BMP280 Barometric Pressure and Altitude Sensor I2C/SPI Module
Add barometric pressure and altitude data to your AWS IoT stream — useful for weather monitoring stations and smart HVAC control projects.
AWS IoT Rules and DynamoDB Storage
Once your ESP32 is publishing data to AWS IoT Core, you can use the Rules Engine to automatically store, process, or forward the data. Creating a rule to save every message to DynamoDB takes about 5 minutes in the AWS console:
- In IoT Core, go to Message routing → Rules and click Create rule.
- Give the rule a name and set the SQL query:
SELECT *, timestamp() as receivedAt FROM 'esp32/sensors/data' - Add a rule action: DynamoDB
- Create a new DynamoDB table (e.g.,
SensorData) withdeviceIdas the partition key andtimestampas the sort key. - Set the table name, partition key value (
${deviceId}), and sort key value (${timestamp()}). - Create or choose an IAM role that allows IoT Core to write to DynamoDB.
Now every MQTT message from your ESP32 is automatically archived in DynamoDB. You can query this data with AWS Lambda functions, visualise it in Amazon QuickSight, or build a web dashboard using AWS Amplify and API Gateway.
Monitoring with AWS IoT Core Console
The AWS IoT Core console includes an MQTT test client (under MQTT test client in the left menu) where you can subscribe to your topic and watch messages arrive in real time — very useful for debugging during development.
Frequently Asked Questions
How much does AWS IoT Core cost for a single ESP32 project?
The AWS free tier includes 500,000 MQTT messages per month. At 1 message per 10 seconds, a single ESP32 sends about 260,000 messages per month — well within the free tier. You only start paying once you scale beyond this. The ap-south-1 (Mumbai) region pricing is approximately $1 per million messages, making it extremely affordable even for commercial IoT products.
Can I use AWS IoT Core with the ESP8266?
Yes, but it is more difficult. The ESP8266 has less RAM and no hardware TLS acceleration, so TLS handshakes are slow (3-5 seconds) and may cause memory issues. The ESP32 is strongly recommended for AWS IoT Core due to its hardware TLS support and larger RAM. The Ai-Thinker ESP32-C3 modules are a good low-cost option.
What happens if the Wi-Fi drops?
The sketch includes reconnection logic in the loop. When the MQTT client detects disconnection, it calls connectToAWS() which re-establishes the TLS connection and re-subscribes to topics. For production devices, implement exponential backoff to avoid hammering the server during extended outages.
Is my sensor data secure on AWS IoT Core?
Yes. All communication uses TLS 1.2+ encryption. Each device has a unique certificate — compromising one device does not affect others. AWS IoT Core also supports thing policies that limit what each device can publish/subscribe to, preventing rogue devices from accessing other devices’ data.
Build Your AWS IoT Project Today
Get all the ESP32 boards and sensors you need for cloud-connected IoT projects at Zbotic — trusted by Indian makers and developers.
Add comment