Building a Smart Factory IoT Platform: AWS + Terraform + OPC UA + AI
Introduction
This is Part 2 of my IoT pipeline series. In Part 1, I covered the hardware setup — wiring the DHT22 sensor to a Raspberry Pi 5 and confirming sensor readings.
In this post I'll cover connecting the Pi to AWS, storing data in DynamoDB, adding AI-powered anomaly detection with Lambda, provisioning infrastructure with Terraform, and finally adding an OPC UA industrial protocol layer.
Part 1: Connecting to AWS IoT Core
I created an IoT Thing (rpi-dht22-seoul-001) in the AWS Console and attached a least-privilege IoT Policy. AWS generates X.509 certificates during this process (a device certificate, private key, and Root CA), which I transferred to the Pi using scp.
The endpoint address is retrieved via CLI:
aws iot describe-endpoint --endpoint-type iot:Data-ATS --region ap-northeast-2
The main script (sensor_to_aws.py) uses the AWS IoT SDK's mtls_from_path() to establish an MQTT connection over TLS port 8883, authenticated with the X.509 certificates. Every 60 seconds it reads the sensor and publishes a JSON message to sensors/dht22/data.
I verified live data in the MQTT test client in the AWS Console.
Part 2: Storing Data in DynamoDB
I set up an IoT Rules Engine rule to automatically write every incoming message to a DynamoDB table (dht22-sensor-data, partition key: device_id, sort key: timestamp).
Troubleshooting: DynamoDB vs DynamoDBv2
The first attempt used the "DynamoDB" action type, which bundled all fields into a single payload column. Switching to DynamoDBv2 fixed this immediately, writing each field as a clean separate column:
device_id | timestamp | humidity | temperature
rpi-dht22-seoul-001 | 1772548058 | 32.1 | 22.8
This was the only significant issue encountered in the entire cloud setup.
Part 3: Infrastructure as Code with Terraform
All AWS resources were then codified into Terraform — IoT Core, DynamoDB, IAM roles, Lambda, and EventBridge — split across five .tf files.
Since some resources already existed from manual setup, I imported them first:
terraform import aws_dynamodb_table.sensor_data dht22-sensor-data
terraform import aws_iot_thing.dht22 rpi-dht22-seoul-001
The full infrastructure can now be reproduced in any AWS region with:
terraform init
terraform apply
I also replaced root account usage with a dedicated IAM user (terraform-admin) following least-privilege principles.
Part 4: AI Anomaly Detection with Lambda
An AWS Lambda function runs every 5 minutes via EventBridge, performing Z-score statistical analysis on the last 24 hours of sensor data:
Z = (current value - mean) / standard deviation
Readings with a Z-score above 2 are flagged as anomalies and stored in a separate anomaly-alerts DynamoDB table. This simulates the kind of predictive maintenance logic used in real factory monitoring systems — detecting abnormal equipment behaviour before it becomes a failure.
Test result from the Lambda console:
{
"severity": "NORMAL",
"temp_z_score": 0.3,
"hum_z_score": 0.84,
"anomalies": []
}
Part 5: OPC UA Industrial Protocol Layer
To make the project genuinely industrial-grade, I added an OPC UA layer. OPC UA is the standard communication protocol used in smart factories — it structures data in a factory hierarchy following ISA-95:
Factory_Seoul → ProductionLine_A1 → Equipment_EnvMonitor_01 → Sensors
Two scripts run on the Pi:
- opcua_server.py: reads the DHT22 and exposes data as a structured OPC UA object tree with equipment metadata and status logic (RUNNING / WARNING / ALARM)
- opcua_client.py: navigates the hierarchy, reads sensor values, and forwards them to AWS IoT Core via MQTT with an enriched industrial payload including equipment_id, location, and protocol: OPC-UA
This is the same edge gateway pattern used in real manufacturing environments for connecting field devices to cloud infrastructure.
Final Architecture
DHT22 Sensor
↓
OPC UA Server (ISA-95 hierarchy)
↓ opc.tcp
OPC UA Client (protocol translation)
↓ MQTT/TLS + X.509
AWS IoT Core → DynamoDB
↓ EventBridge (every 5 min)
Lambda (Z-score anomaly detection)
↓
anomaly-alerts DynamoDB table
All infrastructure → Terraform → GitHub
Key Takeaways
- Use DynamoDBv2 (not DynamoDB) in IoT Rules Engine for clean separate columns
- Always run terraform plan before terraform apply to preview changes safely
- OPC UA with ISA-95 hierarchy transforms a basic sensor project into an industrial-grade platform
- Z-score anomaly detection requires no ML framework: simple statistics are effective for time-series sensor data
Full source code: github.com/h3566652/Edge-Cloud-Gateway-Project
Kyoungmin Park | LinkedIn