Ingest Pipeline
After Phase 2 TERRAFORM
HashiCorp Terraform — provisions shared infrastructure (IoT rules fan-out, Lambda, DynamoDB, API Gateway, Amplify). apply, device MQTT messages follow two parallel paths: CloudWatch Logs
Amazon CloudWatch Logs — stores IoT rule output for Phase 1 verification (`/aws/iot/esp32-demo/telemetry` and `/events`). (Phase 1 verification preserved) and DYNAMODB
Amazon DynamoDB — persists telemetry and event records after Lambda ingest in Phase 2. ingest (new in Phase 2).
For module paths, see Stack Source Layout.
Data flow
Section titled “Data flow”ESP32 MQTT publish → IoT Core → esp32_demo_telemetry_rule / esp32_demo_events_rule ├─→ CloudWatch Logs (/aws/iot/esp32-demo/telemetry|events) └─→ lambda_processor (handler.py) └─→ DynamoDB telemetry or events tableTopic patterns match the payload contract
JSON schema for telemetry (`type=connectivity`) and event (`type=button`, `event=press`) MQTT messages. :
devices/+/telemetrydevices/+/events
Processor Lambda (handler.py)
Section titled “Processor Lambda (handler.py)”Source: terraform/modules/lambda_processor/src/handler.py
Responsibilities:
- Normalize — parse IoT rule event JSON (device payload)
- Validate — require
device_id,ts,type - Classify —
type=button→ events table; otherwise telemetry - Timestamp — use
tswhen positive; iftsis0or missing, seteffective_tsto ingest time andts_fallback_used=true - Dedupe —
record_idfrom SHA-256 of payload; conditional write avoids duplicate keys - Write —
put_itemto telemetry or events table
Stored item shape (simplified):
device_id,record_id,record_type(telemetryorevent)effective_ts,ts_original,ts_fallback_used,ingest_tspayload— full MQTT JSON body
DynamoDB tables
Section titled “DynamoDB tables”Both tables use the same key design (from modules/dynamodb):
- Primary key:
device_id(hash) +record_id(range) - GSI
device_ts_idx:device_id+effective_ts— used by the query Lambda for latest/recent reads
Table names come from Terraform outputs telemetry_table_name and events_table_name.
Verify ingest
Section titled “Verify ingest”After the device is publishing and Terraform is applied:
TELEMETRY_TABLE="$(terraform -chdir=terraform output -raw telemetry_table_name)"EVENTS_TABLE="$(terraform -chdir=terraform output -raw events_table_name)"aws dynamodb scan --table-name "$TELEMETRY_TABLE" --max-items 5aws dynamodb scan --table-name "$EVENTS_TABLE" --max-items 5See Terraform Provisioning for the full apply workflow.