AWS IoT Core: Complete Guide to Building Connected Device Solutions

AWS IoT Core: Building Connected Device Solutions

Cloud architecture diagram
Cloud architecture diagram

AWS IoT Core is a managed cloud platform that enables connected devices to securely interact with cloud applications and other devices. Whether you’re building smart home devices, industrial sensors, or fleet management systems, IoT Core provides the foundation for secure, scalable device connectivity.

IoT Core Architecture

Understanding the core components is essential for designing IoT solutions:

Component Purpose Key Features
Device Gateway Entry point for device connections MQTT, HTTPS, WebSocket support
Message Broker Pub/sub message routing Topic-based filtering, QoS levels
Rules Engine Process and route messages SQL-like queries, 20+ action types
Device Shadow Virtual device state Offline sync, desired vs. reported state
Registry Device identity management Thing types, groups, attributes

Device Authentication

IoT Core supports multiple authentication methods:

X.509 Certificates (Recommended)

Each device gets a unique certificate for mutual TLS authentication:

# Create a thing and certificates using AWS CLI

# 1. Create a thing
aws iot create-thing --thing-name "sensor-001"

# 2. Create keys and certificate
aws iot create-keys-and-certificate \
  --set-as-active \
  --certificate-pem-outfile "cert.pem" \
  --public-key-outfile "public.key" \
  --private-key-outfile "private.key"

# 3. Attach policy to certificate
aws iot attach-policy \
  --policy-name "SensorPolicy" \
  --target "arn:aws:iot:us-east-1:123456789:cert/abc123..."

# 4. Attach certificate to thing
aws iot attach-thing-principal \
  --thing-name "sensor-001" \
  --principal "arn:aws:iot:us-east-1:123456789:cert/abc123..."

IoT Policy Example

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "iot:Connect",
      "Resource": "arn:aws:iot:us-east-1:*:client/${iot:Connection.Thing.ThingName}"
    },
    {
      "Effect": "Allow",
      "Action": "iot:Publish",
      "Resource": "arn:aws:iot:us-east-1:*:topic/sensors/${iot:Connection.Thing.ThingName}/*"
    },
    {
      "Effect": "Allow",
      "Action": "iot:Subscribe",
      "Resource": "arn:aws:iot:us-east-1:*:topicfilter/commands/${iot:Connection.Thing.ThingName}"
    }
  ]
}

Publishing Data from Devices

Here’s a Python example using the AWS IoT Device SDK:

from awscrt import io, mqtt
from awsiot import mqtt_connection_builder
import json
import time

# Configuration
ENDPOINT = "xxxxxx-ats.iot.us-east-1.amazonaws.com"
CLIENT_ID = "sensor-001"
CERT_PATH = "./certs/cert.pem"
KEY_PATH = "./certs/private.key"
CA_PATH = "./certs/AmazonRootCA1.pem"

# Create MQTT connection
mqtt_connection = mqtt_connection_builder.mtls_from_path(
    endpoint=ENDPOINT,
    cert_filepath=CERT_PATH,
    pri_key_filepath=KEY_PATH,
    ca_filepath=CA_PATH,
    client_id=CLIENT_ID,
    clean_session=False,
    keep_alive_secs=30
)

# Connect
connect_future = mqtt_connection.connect()
connect_future.result()
print("Connected!")

# Publish sensor data
def publish_telemetry():
    while True:
        payload = {
            "device_id": CLIENT_ID,
            "timestamp": int(time.time()),
            "temperature": 23.5,
            "humidity": 65.2,
            "battery": 87
        }

        mqtt_connection.publish(
            topic=f"sensors/{CLIENT_ID}/telemetry",
            payload=json.dumps(payload),
            qos=mqtt.QoS.AT_LEAST_ONCE
        )

        print(f"Published: {payload}")
        time.sleep(10)

publish_telemetry()

IoT Rules Engine

The Rules Engine processes incoming messages and routes them to AWS services:

# Terraform: Create IoT Rule
resource "aws_iot_topic_rule" "sensor_rule" {
  name        = "process_sensor_data"
  enabled     = true
  sql         = "SELECT * FROM 'sensors/+/telemetry' WHERE temperature > 30"
  sql_version = "2016-03-23"

  # Send to Lambda for processing
  lambda {
    function_arn = aws_lambda_function.process_alert.arn
  }

  # Store in DynamoDB
  dynamodb {
    table_name     = aws_dynamodb_table.sensor_data.name
    hash_key_field = "device_id"
    hash_key_value = "${device_id}"
    range_key_field = "timestamp"
    range_key_value = "${timestamp}"
    payload_field   = "payload"
    role_arn        = aws_iam_role.iot_rule_role.arn
  }

  # Archive to S3
  s3 {
    bucket_name = aws_s3_bucket.sensor_archive.id
    key         = "telemetry/${device_id}/${timestamp}.json"
    role_arn    = aws_iam_role.iot_rule_role.arn
  }

  # Send alert to SNS for high temperature
  sns {
    target_arn = aws_sns_topic.alerts.arn
    role_arn   = aws_iam_role.iot_rule_role.arn
    message_format = "JSON"
  }
}

Device Shadows

Device Shadows maintain the last known state of devices, enabling offline synchronization:

🔄 Shadow State Model:

  • Reported: State reported by the device
  • Desired: State requested by applications
  • Delta: Difference between desired and reported
# Example shadow document
{
  "state": {
    "desired": {
      "power": "on",
      "temperature": 22
    },
    "reported": {
      "power": "off",
      "temperature": 24
    },
    "delta": {
      "power": "on",
      "temperature": 22
    }
  },
  "metadata": { ... },
  "version": 12,
  "timestamp": 1703520000
}

Fleet Provisioning

For mass device deployment, use Fleet Provisioning to automate certificate creation:

  • Claim Certificates: Shared bootstrap certificate for initial connection
  • Provisioning Templates: Define how devices are registered and configured
  • Pre-Provisioning Hooks: Lambda functions to validate devices before provisioning

IoT Core Pricing

Component Price (US East) Notes
Connectivity $0.08 per million minutes Connected device time
Messaging $1.00 per million messages First 1B messages/month
Rules Engine $0.15 per million rules triggered Per rule execution
Device Shadow $1.25 per million operations Update/get operations

Best Practices

  • Use unique certificates per device – Never share certificates across devices
  • Implement reconnection logic – Handle network failures gracefully
  • Use QoS 1 for critical data – Ensures at-least-once delivery
  • Partition topics wisely – Use hierarchical topics (sensors/{location}/{device})
  • Monitor with CloudWatch – Track connection counts, message rates, rule failures

Further Reading

🎯 Getting Started: Use the AWS IoT Console’s “Connect a device” wizard to quickly provision your first device with auto-generated certificates and sample code.

Jennifer Walsh

Jennifer Walsh

Author & Expert

Senior Cloud Solutions Architect with 12 years of experience in AWS, Azure, and GCP. Jennifer has led enterprise migrations for Fortune 500 companies and holds AWS Solutions Architect Professional and DevOps Engineer certifications. She specializes in serverless architectures, container orchestration, and cloud cost optimization. Previously a senior engineer at AWS Professional Services.

156 Articles
View All Posts