IoT Cloud Platforms — AWS IoT, Azure IoT & GCP IoT
In this tutorial, you'll learn about IoT Cloud Platforms. We cover key concepts, practical examples, and best practices to help you understand and apply this topic effectively.
Iot Cloud Platforms provide managed services for connecting, managing, and processing data from millions of IoT devices, with AWS IoT Core, Azure IoT Hub, and Google Cloud IoT Core each offering distinct approaches to device registry, message brokering, and rule processing.
What You'll Learn
You'll compare AWS IoT Core, Azure IoT Hub, and Google Cloud IoT (now part of Pub/Sub), implement device provisioning and authentication, configure message routing and rule engines, and benchmark platform costs for 10,000 devices.
Why Iot Cloud Platforms Matter
Managing device connections at scale is impossible without a cloud platform. At 10,000 devices sending 1KB every minute, you need to handle 14.4 million messages/day — requiring authentication, routing, storage, and monitoring. These platforms abstract the complexity. DodaTech's IoT security sensor network uses AWS IoT Core to manage 50,000+ devices across manufacturing plants.
Real-World Use Case
A logistics company tracks 5,000 shipping containers with temperature and location sensors. AWS IoT Core receives 11M messages/day, routes to DynamoDB for real-time tracking, and triggers Lambda alerts when temperature exceeds the cold-chain threshold. Manual tracking would require 15 staff — the IoT platform handles it with one engineer.
Platform Comparison
| Feature | AWS IoT Core | Azure IoT Hub | GCP IoT (Pub/Sub) |
|---|---|---|---|
| Device Registry | Thing Registry | Device Registry | Device Manager |
| Protocol | MQTT, HTTP, LoRaWAN | MQTT, AMQP, HTTP | MQTT, HTTP |
| Authentication | X.509, Cognito | SAS tokens, X.509 | JWT, X.509 |
| Message Routing | Rules Engine | Message Routing | Pub/Sub Push |
| Edge | Greengrass | IoT Edge | Edge TPU |
| Free Tier | 250K msgs/month | 8K msgs/day | 10GB/month |
AWS IoT Core Implementation
Device Provisioning
# Device provisioning with AWS IoT
import boto3
import json
import time
iot = boto3.client('iot')
def provision_device(device_id):
"""Create and register an IoT device."""
# Create thing
thing = iot.create_thing(
thingName=device_id,
thingTypeName='TemperatureSensor',
attributes={
'firmware_version': '2.1.0',
'location': 'factory-floor-a'
}
)
# Create certificate
cert = iot.create_keys_and_certificate(setAsActive=True)
# Attach policy
iot.attach_policy(
policyName='IoTPublishPolicy',
target=cert['certificateArn']
)
# Attach certificate to thing
iot.attach_thing_principal(
thingName=device_id,
principal=cert['certificateArn']
)
print(f"Device {device_id} provisioned")
print(f"Certificate ARN: {cert['certificateArn']}")
return {
'certificate_pem': cert['certificatePem'],
'private_key': cert['keyPair']['PrivateKey'],
'endpoint': iot.describe_endpoint(endpointType='iot:Data-ATS')['endpointAddress']
}
# Deprovision — important for device lifecycle
def decommission_device(device_id, cert_arn):
iot.update_certificate(
certificateId=cert_arn.split('/')[-1],
newStatus='INACTIVE'
)
iot.detach_thing_principal(
thingName=device_id,
principal=cert_arn
)
iot.delete_certificate(certificateId=cert_arn.split('/')[-1])
iot.delete_thing(thingName=device_id)
print(f"Device {device_id} decommissioned")
Expected output: Device is registered in AWS IoT with a certificate, policy attached, and ready to connect. Decommissioning properly cleans up all resources.
Rules Engine — Route to DynamoDB
-- AWS IoT SQL Rule
SELECT
device_id,
temperature,
humidity,
timestamp()
FROM 'sensors/+/telemetry'
WHERE temperature > 30.0
# Rule action — Lambda function
import json
import boto3
dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table('TemperatureAlerts')
def lambda_handler(event, context):
# Parse incoming IoT message
for record in event['records']:
payload = json.loads(record['data'])
item = {
'device_id': payload['device_id'],
'timestamp': int(time.time()),
'temperature': payload['temperature'],
'humidity': payload.get('humidity'),
'threshold_exceeded': True
}
table.put_item(Item=item)
print(f"Alert saved: {item['device_id']} at {item['temperature']}°C")
return {'statusCode': 200}
Expected output: Every high-temperature reading is automatically routed to DynamoDB and logged.
Azure IoT Hub Implementation
# Azure IoT Hub device SDK
from azure.iot.device import IoTHubDeviceClient, Message
import json
import asyncio
connection_string = "HostName=myhub.azure-devices.net;DeviceId=sensor-01;SharedAccessKey=..."
async def main():
client = IoTHubDeviceClient.create_from_connection_string(connection_string)
await client.connect()
# Device twin reported properties
reported_properties = {
'firmware': '2.1.0',
'battery_level': 85
}
await client.patch_twin_reported_properties(reported_properties)
# Send telemetry
while True:
telemetry = {
'device_id': 'sensor-01',
'temperature': 22.5,
'humidity': 55,
'timestamp': time.time()
}
msg = Message(json.dumps(telemetry))
msg.content_encoding = 'utf-8'
msg.content_type = 'application/json'
await client.send_message(msg)
print(f"Sent: {telemetry}")
# Handle direct method calls
client.on_method_request_received = handle_method
await asyncio.sleep(60)
await client.disconnect()
def handle_method(method_request):
if method_request.name == "reboot":
print("Rebooting device...")
return {"result": "rebooting"}
Expected output: Device connects to Azure IoT Hub, sends telemetry, reports twin properties, and handles direct method calls from the cloud.
GCP IoT (via Pub/Sub)
# Google Cloud Pub/Sub for IoT
from google.cloud import pubsub_v1
import json
project_id = "my-iot-project"
topic_id = "sensor-telemetry"
publisher = pubsub_v1.PublisherClient()
topic_path = publisher.topic_path(project_id, topic_id)
def publish_sensor_data(device_id, temperature, humidity):
data = json.dumps({
'device_id': device_id,
'temperature': temperature,
'humidity': humidity,
'timestamp': int(time.time())
}).encode('utf-8')
# Future — non-blocking publish
future = publisher.publish(
topic_path,
data,
device_id=device_id,
source='iot-sensor'
)
message_id = future.result()
print(f"Published: {message_id}")
return message_id
# Subscriber with Dataflow-style processing
def telemetry_callback(message):
data = json.loads(message.data.decode('utf-8'))
print(f"Received from {data['device_id']}: {data['temperature']}°C")
if data['temperature'] > 35:
# Route to alert topic
alert_topic = publisher.topic_path(project_id, "temperature-alerts")
publisher.publish(alert_topic, message.data)
message.ack()
Expected output: MQTT messages from IoT devices land in Pub/Sub, routed to appropriate subscribers based on content.
Mermaid Diagram: Multi-Platform Architecture
flowchart TD
subgraph Devices
A[Sensor 1]
B[Sensor 2]
C[Sensor 3]
end
subgraph AWS
D[AWS IoT Core]
E[Rules Engine]
F[DynamoDB]
G[Lambda]
end
subgraph Azure
H[IoT Hub]
I[Stream Analytics]
J[Cosmos DB]
end
subgraph GCP
K[Pub/Sub]
L[Dataflow]
M[BigQuery]
end
A --> D
B --> H
C --> K
D --> E
E --> F
E --> G
H --> I
I --> J
K --> L
L --> M
style Devices fill:#d4edda
style AWS fill:#ff9900
style Azure fill:#0078d4
style GCP fill:#4285f4
Cost Comparison (10K devices, 1 msg/min)
| Platform | Message Processing | Data Storage | Total Estimate |
|---|---|---|---|
| AWS IoT Core | $225/mo | $50/mo (DynamoDB) | ~$300/mo |
| Azure IoT Hub | $150/mo (S1 tier) | $40/mo (Cosmos DB) | ~$220/mo |
| GCP Pub/Sub | $130/mo | $60/mo (BigQuery) | ~$210/mo |
Common Cloud Platform Errors
1. Device Certificate Expiry
Problem: Devices disconnect when certificates expire. Fix: Implement automatic certificate rotation 30 days before expiry.
2. MQTT Connection Limits
Problem: Devices cannot connect (AWS default: 10K connections/account). Fix: Request limit increase or use Greengrass as local proxy.
3. Message Size Exceeded
Problem: AWS IoT max message is 128KB. Fix: Split large payloads or upload to S3 and send reference URL.
4. Rule Engine SQL Syntax
Problem: Incorrect SQL causes silent message drops. Fix: Test rules in AWS IoT console before deploying.
5. Device Twin Conflicts
Problem: Reported/desired properties conflict. Fix: Use idempotent update patterns and version tracking.
6. Cross-Region Latency
Problem: Devices in Asia connecting to US region (300ms+). Fix: Deploy device registry in nearest region; use global message routing if needed.
Practice Questions
What is the difference between device shadow and device twin? Device shadow (AWS) is a JSON document for device state. Device twin (Azure) adds tags, desired/reported properties, and query support.
How do you authenticate IoT devices securely? X.509 certificates are the standard. Device has private key; cloud holds CA. For constrained devices, use pre-shared keys or token-based auth.
What is a IoT rule engine? A serverless SQL-based processor that transforms and routes messages from the Message Broker to other services (DB, Lambda, S3).
How do you handle device disconnections? Implement exponential backoff retry (1s, 2s, 4s... up to 5 min). Use last will (MQTT) to notify cloud of unexpected disconnection.
What is OTA Firmware Update via IoT platform? Push new firmware through the platform using job management — AWS IoT Jobs or Azure Device Update.
Challenge
Build a multi-cloud IoT gateway that sends sensor data to both AWS IoT Core and Azure IoT Hub simultaneously. Implement failover — if one platform is unreachable, queue messages locally and retry. Measure failover time and data loss during a simulated outage.
Real-World Task
You need to migrate 2,000 devices from AWS IoT Core to Azure IoT Hub. Create a migration script that: reads devices from AWS, creates equivalent devices in Azure, generates new connection strings, and deploys firmware updates via OTA. Zero-downtime migration plan required.
Mini Project: IoT Device Manager CLI
import click
import boto3
from azure.iot.hub import IoTHubRegistryManager
@click.group()
def cli():
pass
@cli.command()
@click.option('--platform', default='aws')
@click.option('--device-id', required=True)
def provision(platform, device_id):
if platform == 'aws':
provision_aws(device_id)
elif platform == 'azure':
provision_azure(device_id)
@cli.command()
@click.option('--platform', default='aws')
@click.option('--device-id', required=True)
def decommission(platform, device_id):
if platform == 'aws':
decommission_aws(device_id)
elif platform == 'azure':
decommission_azure(device_id)
@cli.command()
@click.option('--platform', default='aws')
def list_devices(platform):
if platform == 'aws':
iot = boto3.client('iot')
things = iot.list_things()
for thing in things['things']:
print(f"{thing['thingName']} - {thing['thingTypeName']}")
Expected output: A CLI tool to manage IoT devices across platforms — provision, decommission, and list from the terminal.
Related Tutorials
- IoT Edge Computing — Process data locally before cloud
- IoT Communication Protocols — MQTT/CoAP for cloud connectivity
- IoT Security — Secure cloud-device communication
- Next: IoT Dashboard & Visualization — Data Analytics Guide
- Previous: IoT Sensors & Actuators — Complete Hardware Guide
Built by the developers of Doda Browser, DodaZIP, and Durga Antivirus Pro.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro