AWS IoT本番運用Vol2|Events×Analytics×TwinMaker×Fleet

目次

§1 なぜ IoT Vol2 か — IoT階層 (Edge/Connect/Event/Analyze/Digital Twin) + IoT二部作開始ナビ

AWS IoT の世界は、単純なデバイス接続にとどまらない。センサーデータがクラウドに届いた後、「何が起きたか」を検知し、「何を意味するか」を分析し、「どう見えるか」を可視化し、「移動体から何を収集するか」を管理する層が必要になる。

Vol1 では IoT Core / Greengrass / SiteWise / Device Defender を用いたデバイス接続・データ収集の基盤を構築した。本 Vol2 では、その上位層として IoT Events / IoT Analytics / IoT TwinMaker / IoT FleetWise の 4 サービスを本番運用パターンで解説する。

IoT 6層アーキテクチャ全景

AWS IoT のサービス群は以下の 6 層に分類できる。

+-------------------------------------------------------+
|  Layer 6: Mobility (モビリティ層)  |
|  IoT FleetWise -- 車両データ収集・Signal catalog  |
+-------------------------------------------------------+
|  Layer 5: Digital Twin (デジタルツイン層)|
|  IoT TwinMaker -- 3D可視化・Entity階層・GenAI統合 |
+-------------------------------------------------------+
|  Layer 4: Analyze (分析層)|
|  IoT Analytics -- Pipeline・Datastore・Notebook分析  |
+-------------------------------------------------------+
|  Layer 3: Event (イベント層)  |
|  IoT Events -- Detector Model・State machine・Actions|
+-------------------------------------------------------+
|  Layer 2: Connect (接続層) Vol1 担当  |
|  IoT Core・Greengrass・SiteWise・Device Defender  |
+-------------------------------------------------------+
|  Layer 1: Edge (エッジ層) Vol1 担当|
|  Greengrass Edge Runtime・ローカル処理・OTA |
+-------------------------------------------------------+

Vol1 は Layer 1-2 を担当した。本 Vol2 は Layer 3-6 を一気に解説する。

Vol1 との差別化と縦深化の関係

Vol1 (デバイス接続層) は「デバイスをつなぐ」基盤を扱った。本 Vol2 (イベント・分析・デジタルツイン・モビリティ層) は「つながったデータを活かす」上位層に特化する。

観点Vol1Vol2
主役サービスIoT Core / Greengrass / SiteWise / Device DefenderIoT Events / IoT Analytics / IoT TwinMaker / IoT FleetWise
データの流れセンサー → クラウド収集収集後 → 検知・分析・可視化・車両管理
対象スタック接続・認証・プロビジョニング状態検知・ETL・3D可視化・CAN信号
前提スキルIoT デバイス設定・MQTTVol1 読了 + AWS 基礎

Vol1 基盤が完成しているチームが Vol2 に進む構成となっている。Vol1 未読者は先に IoT本番運用 Vol1 を読了することを推奨する。

本記事の対象読者

  • IoT Core/Greengrass による接続基盤を構築済みの SRE
  • Detector Model / State machine による複雑イベント検知を実装したいエンジニア
  • 工場・プラントの 3D デジタルツインを TwinMaker で構築したい IoT アーキテクト
  • 車両・モビリティ系データパイプラインを FleetWise で設計したいチーム

本記事の 4 大テーマ

本記事は §2-§5 の 4 本柱を主軸に構成する。

  1. §2 IoT Events — Detector Model と State machine でデバイス故障パターンをイベント検知
  2. §3 IoT Analytics — Channel/Pipeline/Datastore/Notebook でテレメトリデータを分析基盤化
  3. §4 IoT TwinMaker — Workspace/Entity/Scene/GenAI Connector で 3D デジタルツイン構築
  4. §5 IoT FleetWise — Signal catalog/Vehicle model/Campaign/Edge agent で車両データ収集
IoT本番運用シリーズ Vol1 ↔ Vol2 二部作ナビ

本記事は AWS IoT 本番運用シリーズ第2巻です。デバイス接続の基盤を Vol1 で構築し、その上位となるイベント検知・分析・デジタルツイン・モビリティの 4 層を本 Vol2 で完全解説します。

Vol1 → Vol2 の流れ: IoT Core でデバイスを接続し、ルールエンジンで IoT Events に転送 → Detector Model で状態管理 → IoT Analytics で分析 → TwinMaker で可視化 → FleetWise で車両管理。

本 Vol2 の章構成: §2 IoT Events (State machine/Multi-detector) → §3 IoT Analytics (Pipeline/Datastore/Notebook) → §4 IoT TwinMaker (Entity/Scene/GenAI) → §5 IoT FleetWise (Signal catalog/Campaign/Edge agent) → §6 詰まり7選 → §7 アンチパターン演習 → §8 全軸クロスリンクナビ

IoT Vol1 (デバイス接続層): IoT Core × Greengrass × SiteWise × Device Defender 完全ガイド

Vol2 が解決する 4 つの課題

IoT 本番運用で「Vol1 の基盤を構築したがここで詰まっている」という典型的なケースを整理する。

課題1: 機器故障の複雑なイベント検知

IoT Core のルールエンジンは「温度 > 80℃ なら SNS 送信」のような単一条件アラートに向いている。しかし「5 分間で 3 回連続閾値超過」「Normal → Warning → Critical という状態遷移管理」など、複数メッセージにまたがる状態管理はルールエンジン単独では実装が複雑になる。IoT Events の Detector Model がこの問題を解決する。

課題2: テレメトリデータの分析基盤構築

大量のセンサーデータを S3 に保存したはよいが、データ品質が悪い (欠損値・外れ値)、変換・エンリッチメントが必要、Athena クエリのパフォーマンスが悪い、Notebook 分析したい ―― このような分析基盤の課題に対し、IoT Analytics の Pipeline/Channel/Datastore/Dataset/Notebook が一気に解決する。

課題3: 設備の 3D デジタルツイン可視化

工場・プラントの設備をリアルタイムで 3D 可視化したい。CAD データを活かしつつ、センサーデータをリアルタイムにオーバーレイしたい。GenAI と統合して異常箇所を自然言語で問い合わせたい ―― こういった要件に対し、IoT TwinMaker の Workspace/Entity/Scene/GenAI Connector が対応する。

課題4: 車両・モビリティデータの大規模収集

コネクテッドカー・建機・物流車両の CAN バス信号を効率的に収集したい。全データを送信するとコストが莫大になる。エッジ側でフィルタリングしクラウドへは必要なシグナルのみ送りたい ―― IoT FleetWise の Signal catalog/Campaign/Edge agent がこの課題に対応する。

IoT サービス間のデータフロー

Vol1 の基盤 (IoT Core/Greengrass) と Vol2 の上位層がどのようにデータを連携するか、全体のデータフローを示す。

[デバイス/センサー]
  |
  | MQTT/HTTPS
  v
[IoT Core] ← Greengrass がエッジでブリッジ
  |
  +--[ルールエンジン]--> [IoT Events]: 状態管理・アラート
  |  |
  |  v
  |  [SNS/SQS/Lambda] : 通知・後続処理
  |
  +--[ルールエンジン]--> [IoT Analytics]: データ収集・変換
  |  |
  |[Datastore/S3]
  |  |
  |[SageMaker Notebook]
  |
  +--[SiteWise]--------->[IoT TwinMaker]: 3Dデジタルツイン
  |  |
  |[Scene/GenAI Connector]
  |
[FleetWise Edge Agent]-------->[IoT FleetWise]: 車両データ収集
|
 [Signal catalog/Campaign]
|
 [Timestream/S3]

本記事の読み方

各章は独立して参照できる設計だ。ただし、初回読了時は §2 → §3 → §4 → §5 の順番で読むことを推奨する。

  • SRE / 運用エンジニア: §2 (イベント検知) と §6 (詰まり7選) を優先
  • データエンジニア: §3 (IoT Analytics) と §7 (アンチパターン演習) を優先
  • IoT アーキテクト: §2-§5 を全章通読した上で §8 のクロスリンクナビを参照
  • モビリティ/車両担当: §5 (IoT FleetWise) から読み始めて §2-§3 に戻る

次節 §2 では、IoT Events の Detector Model を軸に、フルマネージドなイベント検知・応答パターンを解説する。


§2 IoT Events 本番運用 — Detector Model × State machine × Input × Actions × Multi-detector

IoT Events とは

AWS IoT Events はフルマネージドなイベント検知・応答サービスだ。IoT Core や他のソースから届くセンサーデータストリームを監視し、デバイスの状態遷移 (故障・閾値超過・復旧) を Detector Model として定義することで、複雑なイベント検知ロジックをサーバーレスに実行できる。

独自の状態遷移ロジックを Lambda で実装する場合と比べ、IoT Events は以下の点で優位性を持つ。

  • State machine ネイティブ: 状態 (State) と遷移条件 (Condition) を JSON/Terraform で宣言的に定義
  • Multi-detector: デバイスごとに独立したインスタンスを自動管理。10,000 台規模でも追加実装不要
  • マネージドスケール: デバイス数増加に対してインフラ管理不要
  • 組み込みアクション: SNS / SQS / Lambda / IoT Core / DynamoDB / Firehose へのアクションを設定済みコネクタで接続

Detector Model のコア概念

Detector Model は以下の 4 要素で構成される。

Detector Model
+-- State (状態)
|+-- OnEnter Actions  : 状態に入ったとき実行するアクション
|+-- OnInput Events: 状態内でのイベント定義 (条件 + アクション + 遷移先)
|+-- OnExit Actions: 状態を出るとき実行するアクション
+-- Input
|+-- IoT Core ルールエンジン / BatchPutMessage / HTTP API から送信
+-- Key (Multi-detector キー)
|+-- deviceId 等のフィールドでインスタンスを分割
+-- Role ARN
 +-- IoT Events が SNS / Lambda / DynamoDB 等を呼び出す権限

State (状態): 機器の現在の状態を表す。例: Normal / Warning / Critical / Recovery

Event (イベント): 状態内で評価する条件と、条件が真のときに実行するアクション・遷移先の組み合わせ。

Condition: $input.SensorInput.temperature > 80.0 のような式言語 (IoTEvents expression) で記述。

Variable: Detector Model 内部に保持できる変数。カウンタや累積値の管理に使用する。

State machine 設計パターン

典型的な機器監視の State machine を例示する。

状態遷移図 (工場設備温度監視)

[Normal] ---- temp > 80 ----> [Warning]
  |
[Normal] <---- temp < 75 ------+
 |
 +--- temp > 95 ---> [Critical]
 |
[Recovery] <---- temp < 75 ------------+
 |
 +--- (30秒継続) ---> [Normal]

設計のポイントは「状態数を最小化すること」だ。State machine は直感的だが、状態数が増えると遷移条件が指数的に複雑化する。実務では以下を意識する。

  • 状態は 5-7 個以内に抑える
  • Condition 式は AND/OR の入れ子を 2 段階以内
  • Variable を活用して State 数を削減 (例: エラー回数カウンタで State 分岐を減らす)

Input 設計

IoT Events への入力は 3 経路から選択する。

入力経路ユースケース設定方法
IoT Core ルールエンジン既存 MQTT トピックから転送Rule Action: iotEvents
BatchPutMessage API複数メッセージを一括送信SDK / CLI
HTTP API (PutMessage)単一メッセージを直接送信REST API

本番では IoT Core ルールエンジン経由 が最も一般的だ。ルールの SQL で必要なフィールドのみ抽出し、Input スキーマに合わせてシェーピングする。

SELECT
  topic(3) AS deviceId,
  temperature,
  pressure,
  timestamp() AS ts
FROM 'factory/+/sensors/data'
IoT Events 全体アーキテクチャ
図01: IoT Events の Detector Model × State machine × Input × Actions 統合構成

Actions 設計

Detector Model の各 State で設定できる Action は以下の通り。

Action 種別用途実装コスト
SNS メッセージ送信運用チームへのアラート通知
SQS メッセージ送信非同期後続処理キュー
Lambda 関数呼び出しカスタムロジック実行
IoT Core メッセージ発行デバイスへのコマンド送信
DynamoDB 書き込み状態変化ログ永続化
Firehose 送信S3 への状態変化ストリーミング
IoT Events タイマー設定一定時間後にイベント発火
変数リセット内部カウンタ初期化

アクションの 冪等性 は設計上の必須要件だ。IoT Events は at-least-once 保証のため、同一アクションが複数回呼ばれる可能性がある。Lambda 側で DynamoDB 条件付き書き込みを使うなど、冪等性を担保する実装が必要になる。

Multi-detector によるスケーリング

Multi-detector は IoT Events の最大の特徴の一つだ。Detector Model に key (例: deviceId) を設定すると、デバイスごとに独立した Detector インスタンスが自動生成される。

Multi-detector 概念図

DeviceID: sensor-001 --> Detector Instance [sensor-001] (状態: Normal)
DeviceID: sensor-002 --> Detector Instance [sensor-002] (状態: Warning)
DeviceID: sensor-003 --> Detector Instance [sensor-003] (状態: Critical)
 ...
DeviceID: sensor-N--> Detector Instance [sensor-N](状態: Normal)

インスタンスは初回メッセージ到達時に自動作成され、タイムアウトまたは明示的な削除で消滅する。10,000 台規模でも追加のスケーリング設定は不要だ。

課金単位: インスタンスの評価回数 (メッセージ処理数) とインスタンス時間。インスタンス数が増えるほど費用が線形増加する点に注意する。

Terraform による Detector Model 定義

resource "aws_iotevents_input" "sensor_input" {
  name = "SensorTemperatureInput"

  definition {
 attribute {
json_path = "deviceId"
 }
 attribute {
json_path = "temperature"
 }
 attribute {
json_path = "pressure"
 }
  }
}

resource "aws_iotevents_detector_model" "temperature_monitor" {
  name= "TemperatureMonitor"
  role_arn  = aws_iam_role.iotevents_role.arn
  evaluation_method  = "SERIAL"

  definition {
 initial_state_name = "Normal"

 state {
state_name = "Normal"

on_input {
  events {
 event_name = "CountWarning"
 condition  = "$input.SensorTemperatureInput.temperature > 80"
 actions {
set_variable {
  variable_name = "warningCount"
  value= "$variable.warningCount + 1"
}
 }
  }
  transition_events {
 event_name = "WarningTransition"
 condition  = "$input.SensorTemperatureInput.temperature > 80"
 next_state = "Warning"
 actions {
sns {
  target_arn = aws_sns_topic.iot_alerts.arn
  payload {
 content_expression = "'Warning: Device ' + $input.SensorTemperatureInput.deviceId + ' temperature exceeded 80C'"
 type= "STRING"
  }
}
 }
  }
}
 }

 state {
state_name = "Warning"

on_enter {
  events {
 event_name = "LogWarningEntry"
 actions {
dynamo_d_bv2 {
  table_name = aws_dynamodb_table.device_states.name
  payload {
 content_expression = "{'deviceId': $input.SensorTemperatureInput.deviceId, 'state': 'Warning'}"
 type= "JSON"
  }
}
 }
  }
}

on_input {
  transition_events {
 event_name = "RecoverNormal"
 condition  = "$input.SensorTemperatureInput.temperature < 75"
 next_state = "Normal"
 actions {
sns {
  target_arn = aws_sns_topic.iot_alerts.arn
  payload {
 content_expression = "'Recovered: Device ' + $input.SensorTemperatureInput.deviceId"
 type= "STRING"
  }
}
 }
  }

  transition_events {
 event_name = "EscalateCritical"
 condition  = "$input.SensorTemperatureInput.temperature > 95"
 next_state = "Critical"
 actions {
lambda {
  function_arn = aws_lambda_function.emergency_handler.arn
  payload {
 content_expression = "{'deviceId': $input.SensorTemperatureInput.deviceId, 'action': 'EMERGENCY_SHUTDOWN'}"
 type= "JSON"
  }
}
 }
  }
}
 }

 state {
state_name = "Critical"

on_input {
  transition_events {
 event_name = "RecoverFromCritical"
 condition  = "$input.SensorTemperatureInput.temperature < 75"
 next_state = "Normal"
  }
}
 }
  }
}

IoT Core ルールエンジンとの連携設定

resource "aws_iot_topic_rule" "forward_to_events" {
  name  = "ForwardToIoTEvents"
  enabled  = true
  sql= "SELECT topic(3) AS deviceId, temperature, pressure, timestamp() AS ts FROM 'factory/+/sensors/data'"
  sql_version = "2016-03-23"

  iot_events {
 input_name = aws_iotevents_input.sensor_input.name
 role_arn= aws_iam_role.iot_rule_role.arn
 batch_mode = false
 message_id = "$${topic(3)}"
  }
}

message_iddeviceId を指定することで、Multi-detector のキーと一致させ、デバイスごとのインスタンスルーティングを確立する。

CloudWatch 連携によるモニタリング

IoT Events は以下のメトリクスを CloudWatch に自動送信する。

メトリクス名説明
DetectorModels/Errors  Detector Model 評価エラー数
DetectorModels/Messages処理メッセージ数
DetectorModels/ThrottledMessages スロットリング数
Inputs/Messages  Input 受信メッセージ数

推奨アラーム設定:

resource "aws_cloudwatch_metric_alarm" "iotevents_errors" {
  alarm_name = "IoTEvents-DetectorModel-Errors"
  comparison_operator = "GreaterThanThreshold"
  evaluation_periods  = 1
  metric_name= "Errors"
  namespace  = "AWS/IoTEvents"
  period  = 60
  statistic  = "Sum"
  threshold  = 0
  alarm_actions = [aws_sns_topic.iot_alerts.arn]

  dimensions = {
 DetectorModelName = aws_iotevents_detector_model.temperature_monitor.name
  }
}
IoT Events 本番設計 3鉄則

鉄則1: State machine は最小化せよ
State 数は 5-7 個以内を目安とする。State 数が増えると遷移条件の組み合わせが爆発し、テストと保守コストが激増する。Variable でカウンタ管理を行い、State 分岐を最小化する設計パターンを標準とすること。

鉄則2: Multi-detector キー設計を最初に決定せよ
key フィールドはデプロイ後に変更できない。デバイス粒度 (deviceId) にするか、グループ粒度 (deviceGroup) にするかをデプロイ前に確定する。誤ったキー設計は State machine の再作成を要求する。

鉄則3: Action は冪等に設計せよ
IoT Events は at-least-once 保証のため、同一メッセージが複数回処理される可能性がある。Lambda / DynamoDB 書き込みは条件付き式で冪等性を担保すること。SNS 通知の重複は通知抑制ロジックで吸収する。

IoT Events 採用判断チェックリスト

以下の条件が 2 つ以上該当する場合、IoT Core ルールエンジン単独より IoT Events の採用を推奨する。

  • デバイスの「状態」が複数あり、状態遷移ロジックが必要な場合 (Normal → Warning → Critical → Recovery)
  • 連続する複数のメッセージにまたがる条件判定が必要な場合 (5 分間で 3 回閾値超過を検知)
  • デバイスごとに独立した状態追跡が必要な場合 (100 台以上のデバイス個別管理)
  • 状態変化に応じた異なるアクション (SNS/Lambda/DynamoDB) を宣言的に管理したい場合
  • ルールエンジン SQL では表現できない複雑なイベント相関が必要な場合

単一閾値アラートのみであれば、IoT Core ルールエンジン + CloudWatch Alarms で十分な場合が多い。

次節 §3 では、収集されたテレメトリデータを分析基盤に取り込む IoT Analytics の Pipeline/Datastore/Notebook パターンを解説する。


§3 IoT Analytics 本番運用 — Pipeline × Channel × Datastore × Dataset × SQL × Notebook分析

AWS IoT Analytics は、IoT デバイスから収集した大量の時系列データを処理・保存・分析するためのフルマネージドサービスだ。IoT Core の Rules Engine から直接メッセージを受信し、Pipeline でデータ変換・エンリッチメントを施した後、Datastore に蓄積する。Dataset の SQL クエリや SageMaker Notebook との連携で、機械学習パイプラインや時系列予測まで完結した分析基盤を構築できる。

§3-1. IoT Analytics アーキテクチャ概要

IoT Analytics のデータフローは Channel → Pipeline → Datastore → Dataset の 4 コンポーネントで構成される。

IoT Core (MQTT)
 │
 ▼
Channel ─────────────────────────────────────── メッセージ取込口
 │  MQTT Rule → IoT Analytics Action
 │  バッチ入力 (BatchPutMessage API) 対応
 │  S3 ソース (過去データ一括インジェスト) 対応
 │
 ▼
Pipeline ────────────────────────────────────── データ変換・エンリッチ
 │  Activities (最大 25 個まで連鎖可能):
 │  ① channelActivity(入力チャネル指定)
 │  ② filterActivity (不要メッセージ除去)
 │  ③ mathActivity(温度単位変換 / 計算フィールド追加)
 │  ④ selectAttributesActivity (必要フィールドのみ抽出)
 │  ⑤ deviceRegistryEnrichActivity (Device Registry メタデータ付与)
 │  ⑥ addAttributesActivity(静的フィールド付加)
 │  ⑦ removeAttributesActivity (不要フィールド削除)
 │  ⑧ lambdaActivity (カスタム変換 / 外部 API 呼出)
 │  ⑨ datastoreActivity (出力先 Datastore 指定)
 │
 ▼
Datastore ───────────────────────────────────── 圧縮・パーティション保存
 │  Service-managed S3 / Customer-managed S3 を選択
 │  ファイル形式: JSON or Parquet
 │  保持期間: unlimited / 日数指定
 │
 ▼
Dataset ─────────────────────────────────────── 分析用データセット生成
 SQL クエリ実行 (Presto 互換)
 Container 実行 (SageMaker ECR イメージ)
 スケジュール実行 / デルタウィンドウ
 SageMaker Notebook から直接アクセス可

この直線型パイプラインが IoT Analytics の核心だ。デバイスからのメッセージを Channel で受け取り、Pipeline で変換・エンリッチし、Datastore に蓄積する。Dataset の SQL で時系列集計・異常値抽出・ML 用特徴量生成が一気に実現する。

§3-2. Channel 設計 — IoT Core/MQTT 連携

Channel は IoT Analytics へのメッセージ取込口だ。IoT Core の Rules Engine に以下の Action を定義することで、MQTT トピックからのメッセージを直接 Channel に流し込む。

{
  "sql": "SELECT * FROM 'factory/+/sensor/temperature'",
  "actions": [
 {
"iotAnalytics": {
  "channelName": "iot_sensor_channel",
  "roleArn": "arn:aws:iam::123456789012:role/IoTAnalyticsRole"
}
 }
  ]
}

バッチ入力と S3 ソース: リアルタイム MQTT 以外に、BatchPutMessage API を使ったバッチ投入や、S3 バケットに蓄積済みの CSV/JSON をソースとする構成も選べる。大量の過去データを一括インジェストする際は BatchPutMessage と S3 ソースを組み合わせるのが効果的だ。

Terraform による Channel 定義:

resource "aws_iotanalytics_channel" "sensor" {
  name = "iot_sensor_channel"

  channel_storage {
 service_managed_s3 {}
  }

  retention_period {
 number_of_days = 90
  }

  tags = {
 Environment = "production"
  }
}

§3-3. Pipeline Activity 設計 — 変換チェーンの構築

Pipeline は複数の Activity を連鎖させてデータを変換する。Activity の順序設計が性能とコストを大きく左右する。filterActivity を最前列に配置して不要メッセージを早期除去することが、後続 Activity の処理コスト削減の基本だ。

実践的な Activity チェーン例: 工場センサーから届く生データに対し、デバイスメタデータ付与・単位変換・不要フィールド削除を行う Pipeline:

resource "aws_iotanalytics_pipeline" "sensor_pipeline" {
  name = "sensor_transform_pipeline"

  pipeline_activities {
 channel {
name= "channelActivity"
channel_name = aws_iotanalytics_channel.sensor.name
next= "filterActivity"
 }
  }

  pipeline_activities {
 filter {
name= "filterActivity"
filter = "temperature > -50 AND temperature < 200"
next= "mathActivity"
 }
  }

  pipeline_activities {
 math {
name= "mathActivity"
attribute = "temperature_celsius"
math= "(temperature - 32) * 5 / 9"
next= "deviceRegistryEnrichActivity"
 }
  }

  pipeline_activities {
 device_registry_enrich {
name = "deviceRegistryEnrichActivity"
attribute  = "device_info"
thing_name = "$${iot:thingName}"
role_arn= aws_iam_role.iot_analytics.arn
next = "selectAttributesActivity"
 }
  }

  pipeline_activities {
 select_attributes {
name = "selectAttributesActivity"
attributes = [
  "device_id",
  "temperature_celsius",
  "humidity",
  "timestamp",
  "device_info"
]
next = "datastoreActivity"
 }
  }

  pipeline_activities {
 datastore {
name  = "datastoreActivity"
datastore_name = aws_iotanalytics_datastore.sensor.name
 }
  }
}

Lambda Activity の使いどころ: 標準 Activity で対応できない複雑な変換 (外部 REST API 呼出し、暗号化処理、独自スコアリング) は lambdaActivity を使う。ただし Lambda Activity はメッセージ 1 件ごとに Lambda を同期呼出しするため、高頻度メッセージ環境ではコストと遅延が急増する。バッチ処理可能な変換は前後の Activity で前処理してから Lambda に渡し、呼出回数を最小化する設計が必須だ。

§3-4. Datastore 設計 — 保存形式とストレージ選定

Datastore は分析の性能とコストを決定するコンポーネントだ。Service-managed S3 と Customer-managed S3 の選択、および JSON/Parquet のファイル形式選択が最も重要な設計判断になる。

Service-managed S3 vs Customer-managed S3:

項目Service-managed S3Customer-managed S3
設定工数最小 (即時利用可)S3 バケット + IAM 設定必要
コスト制御AWS 管理 (最適化不可)S3 Lifecycle / Intelligent-Tiering 適用可
データ所有権AWS 管理完全自社管理
KMS 暗号化AWS Managed KeyCustomer Managed Key 指定可
Athena 直接クエリ不可Glue Catalog 連携で可能

本番環境では Customer-managed S3 を推奨する。データ保持コストを S3 Intelligent-Tiering や Glacier で最適化でき、Athena からの直接クエリも可能になる。

Terraform による Datastore (Parquet / Customer-managed S3):

resource "aws_iotanalytics_datastore" "sensor" {
  name = "sensor_datastore"

  datastore_storage {
 customer_managed_s3 {
bucket  = aws_s3_bucket.iot_analytics.bucket
key_prefix = "sensor-data/"
role_arn= aws_iam_role.iot_analytics.arn
 }
  }

  file_format_configuration {
 parquet_configuration {
schema_definition {
  columns {
 name = "device_id"
 type = "string"
  }
  columns {
 name = "temperature_celsius"
 type = "double"
  }
  columns {
 name = "humidity"
 type = "double"
  }
  columns {
 name = "timestamp"
 type = "string"
  }
}
 }
  }

  retention_period {
 number_of_days = 365
  }
}

Parquet 形式を選ぶと、列指向ストレージにより Dataset の SQL クエリで必要な列だけをスキャンできるため、大量データ環境でのクエリコストが大幅に低下する。スキーマが安定した本番 IoT データでは Parquet + Customer-managed S3 が標準的な選択だ。

§3-5. Dataset — SQL クエリと Container 実行

Dataset は Datastore のデータに対して SQL クエリを実行し、分析用データセットを生成するコンポーネントだ。スケジュール実行とデルタウィンドウを組み合わせることで、定期的な差分抽出が可能になる。

resource "aws_iotanalytics_dataset" "daily_anomaly" {
  name = "daily_anomaly_dataset"

  actions {
 action_name = "SqlAction"
 query_action {
sql_query = <<-SQL
  SELECT
 device_id,
 AVG(temperature_celsius)  AS avg_temp,
 MAX(temperature_celsius)  AS max_temp,
 MIN(temperature_celsius)  AS min_temp,
 COUNT(*)AS message_count
  FROM sensor_datastore
  WHERE __dt >= current_date - interval '1' day
  GROUP BY device_id
  HAVING MAX(temperature_celsius) > 80
OR MIN(temperature_celsius) < -10
SQL
filter {
  delta_time {
 offset_seconds= -3600
 time_expression  = "from_iso8601_timestamp(timestamp)"
  }
}
 }
  }

  triggers {
 schedule {
expression = "cron(0 6 * * ? *)"
 }
  }

  content_delivery_rules {
 destination {
s3_destination_configuration {
  bucket= aws_s3_bucket.iot_analytics.bucket
  key= "datasets/daily_anomaly/!{iotanalytics:scheduleTime}.json"
  role_arn = aws_iam_role.iot_analytics.arn
}
 }
  }
}

Container Dataset — SageMaker 統合: 機械学習モデルを使った予測・分類を Dataset 生成に組み込む場合は Container Dataset を使う。SageMaker でトレーニング済みのモデルを ECR イメージとして指定し、Dataset 生成時に ML 推論を実行できる。時系列予測 (DeepAR / Prophet) や異常スコアリングをパイプラインに組み込む際に有効だ。

IoT Analytics パイプライン
図02: IoT Analytics の Channel × Pipeline × Datastore × Dataset × Notebook 統合分析基盤

§3-6. Notebook 連携 — SageMaker Jupyter 統合

IoT Analytics は SageMaker Jupyter Notebook と直接統合できる。Notebook から boto3iotanalytics クライアントで Dataset のデータを読み込み、時系列分析・異常検知・予測モデル構築をインタラクティブに実施できる。

import boto3
import pandas as pd
import json
import urllib.request

client = boto3.client("iotanalytics", region_name="ap-northeast-1")

response = client.get_dataset_content(
 datasetName="daily_anomaly_dataset"
)

# Dataset content は S3 presigned URL で提供される
url = response["entries"][0]["dataURI"]
with urllib.request.urlopen(url) as f:
 data = [json.loads(line) for line in f.readlines()]

df = pd.DataFrame(data)
print(df.describe())

時系列分析の代表的なパターンは以下の 3 通りだ。

① トレンド分析:
デバイスごとの温度移動平均 (window=24h) を計算し、
基準値からの乖離 (> 2σ) を異常候補としてフラグ付け

② 季節性分解:
statsmodels の seasonal_decompose で
日次・週次サイクルを分離し、残差成分で異常検知

③ 予測モデル構築:
Prophet / DeepAR で時系列予測を実行し、
実測値が予測範囲を外れた時点をアラート対象に設定

SageMaker Autopilot と Container Dataset を組み合わせると、特徴量エンジニアリングから ML モデル構築・推論まで IoT Analytics パイプライン内で完結できる。

§3-7. コスト設計

IoT Analytics はメッセージ処理量とストレージ量で課金される。

主要課金モデル (ap-northeast-1 目安):
Channel 取込: 約 $0.08 / GB (最初の 10 GB/月は無料枠あり)
Pipeline 処理: 約 $0.05 / GB
Datastore 保存: Customer-managed S3 の場合は S3 コストのみ
Dataset SQL クエリ: スキャン量ベースで課金 (Parquet で最大 90% 削減可)

Reserved capacity は月間 1 TB 以上の処理を継続的に行う場合に有効で、最大 70% のコスト削減効果がある。Parquet 形式 + Customer-managed S3 + S3 Intelligent-Tiering を組み合わせると、大規模環境での総保有コストを大幅に圧縮できる。

🔥 IoT Analytics 本番設計 3鉄則

① Pipeline activity 最小化: Activity を追加するほどメッセージあたりの処理コストが増加する。filterActivity を最前列に配置して不要メッセージを早期除去し、後続 Activity の呼出回数を削減することが基本だ。lambdaActivity は標準 Activity で代替不可能な処理のみに限定する。高頻度メッセージ (1 秒あたり 100 件超) で lambdaActivity を使うと、Lambda 課金が Pipeline 費用を超えるケースがあるため、バッチ可能な変換は必ず標準 Activity に置き換えよ。

② Datastore 保持期間の明示設計: unlimited に設定すると S3 コストが無制限に増加する。本番運用では分析要件 (コンプライアンス保管期間・ML 学習データ必要期間) を事前確認し、日数を明示的に設定すること。Customer-managed S3 + S3 Lifecycle で Glacier 移行ルールを追加すると、長期保管コストをさらに 60〜80% 削減できる。

③ Dataset 定期実行コスト管理: Dataset の SQL クエリはスキャン量に応じて課金される。デルタタイム (delta_time) フィルタを必ず設定し、差分データのみをスキャンするよう制限する。スキャン量が多い Dataset は Parquet 形式 + 列射影 (selectAttributesActivity で必要フィールドのみ Datastore に保存) の組み合わせで 90% 以上のコスト削減効果が見込める。

⚠️ IoT Analytics コーデック選択チェックリスト (JSON vs Parquet / SQL vs Container Dataset)

JSON を選ぶ条件

  • スキーマが頻繁に変わる (センサー種類の追加・変更が月次以上)
  • 1 日のメッセージ数が 10 万件未満でクエリ頻度が低い
  • ネスト構造のある JSON を変換コストなしでそのまま保存したい

Parquet を選ぶ条件 (本番推奨)

  • スキーマが安定している (センサー種類・フィールドが本番稼働後に確定)
  • 1 日のメッセージ数が 100 万件超で Dataset SQL のスキャンコストが課題
  • 列射影でアクセス頻度の低いフィールドをスキャン除外してコスト削減したい

SQL Dataset を選ぶ条件

  • 集計・フィルタリング・JOIN が主目的 (KPI 計算 / 日次レポート)
  • スケジュール実行の差分抽出 (delta_time) で定期バッチ処理を実施したい
  • S3 配信で下流システム (Athena / QuickSight) にデータを渡したい

Container Dataset を選ぶ条件

  • SageMaker のトレーニング済みモデルで推論 (異常スコアリング / 予測) が必要
  • Python スクリプトによる複雑なデータ変換が必要 (SQL では表現不可)
  • 時系列予測 (ARIMA / Prophet / DeepAR) を定期実行したい

IoT Analytics でデータを蓄積・分析する仕組みが整ったら、次はデジタルツインの中核となる IoT TwinMaker でリアルタイム 3D 可視化と GenAI 連携を実装する。


§4 IoT TwinMaker 本番運用 — Workspace × Entity × Component × Scene × GenAI Connector

AWS IoT TwinMaker は、物理的な施設・機器・プロセスのデジタルツインをクラウド上で構築するフルマネージドサービスだ。工場の製造ライン、ビルのインフラ設備、データセンターのサーバーラックなど、現実世界の「状態」をリアルタイムにモデル化し、3D Viewer での可視化・異常検知・運用意思決定を支援する。IoT SiteWise や Timestream に蓄積されたリアルタイムデータと 3D モデルを紐付けることで、「グラフで異常を検知し、3D ビューで対象機器を瞬時に特定する」オペレーション体験が実現できる。

§4-1. IoT TwinMaker アーキテクチャ概要

IoT TwinMaker の論理構造は Workspace → Entity → Component → Scene の 4 層で構成される。

Workspace ────────────────────────────────────── 最上位リソースグループ
 │  リージョン×アカウント単位で分離
 │  S3 バケット (3D モデル / メタデータ保存先)
 │  IAM ロール (データソースへのアクセス権)
 │
 ├── Entity ──────────────────────────────── 現実世界のオブジェクト表現
 ││  例: FactoryLine_A / Machine_001 / Sensor_T01
 ││  階層構造: Factory → Line → Machine → Sensor
 ││  親子関係で物理的な包含関係をモデル化
 ││
 │└── Component ────────────────────────── データソース接続定義
 │ │  ComponentType: データスキーマ定義 (再利用可能な型)
 │ │  データソースコネクタ:
 │ │ IoT SiteWise (リアルタイム Asset Property)
 │ │ Timestream(カスタム時系列データ)
 │ │ S3  (静的メタデータ / 設計図)
 │ │ Lambda (カスタムデータソース)
 │ └── プロパティ値がリアルタイムで参照される
 │
 └── Scene ────────────────────────────────── 3D ビジュアライゼーション
  │  GLTF モデルファイル (S3 に保存)
  │  Tag/Cesium (Entity を 3D シーンにオーバーレイ)
  │  OverlayWidget (温度 / 圧力 / 状態ゲージ)
  └── GenAI Connector (Bedrock Claude 連携)

§4-2. Workspace 設定

Workspace は IoT TwinMaker の最上位リソースグループだ。Workspace ごとに S3 バケットと IAM ロールを設定する。IAM ロールにはデータソース (SiteWise / Timestream) へのアクセス権を付与する。

resource "aws_s3_bucket" "twinmaker" {
  bucket = "iot-twinmaker-workspace-prod"
}

resource "aws_iottwinmaker_workspace" "factory" {
  workspace_id = "factory-digital-twin"
  s3_location  = aws_s3_bucket.twinmaker.arn
  role= aws_iam_role.twinmaker_workspace.arn
  description  = "工場ラインデジタルツイン"

  tags = {
 Environment = "production"
  }
}

resource "aws_iam_role" "twinmaker_workspace" {
  name = "iottwinmaker-workspace-role"

  assume_role_policy = jsonencode({
 Version = "2012-10-17"
 Statement = [{
Action = "sts:AssumeRole"
Effect = "Allow"
Principal = { Service = "iottwinmaker.amazonaws.com" }
 }]
  })
}

resource "aws_iam_role_policy" "twinmaker_workspace" {
  name = "iottwinmaker-workspace-policy"
  role = aws_iam_role.twinmaker_workspace.id

  policy = jsonencode({
 Version = "2012-10-17"
 Statement = [
{
  Effect = "Allow"
  Action = [
 "s3:GetObject", "s3:PutObject",
 "s3:DeleteObject", "s3:ListBucket"
  ]
  Resource = [
 aws_s3_bucket.twinmaker.arn,
 "${aws_s3_bucket.twinmaker.arn}/*"
  ]
},
{
  Effect = "Allow"
  Action = [
 "iotsitewise:GetPropertyValue",
 "iotsitewise:GetPropertyValueHistory",
 "iotsitewise:GetAssetPropertyValue"
  ]
  Resource = "*"
},
{
  Effect = "Allow"
  Action = [
 "timestream:Select",
 "timestream:DescribeTable",
 "timestream:ListMeasures"
  ]
  Resource = "*"
}
 ]
  })
}

§4-3. Entity / Component 階層設計 — デジタルツインモデリング

Entity は物理オブジェクトのクラウド表現だ。Component は Entity に付属するデータソース接続定義を持ち、IoT SiteWise・Timestream・S3・Lambda のいずれかからリアルタイムデータを取得する。ComponentType でスキーマを先に定義し、各 Entity の Component で再利用するのが設計の基本だ。

ComponentType 定義:

resource "aws_iottwinmaker_component_type" "temperature_sensor" {
  workspace_id= aws_iottwinmaker_workspace.factory.workspace_id
  component_type_id = "TemperatureSensor"
  description = "温度センサーコンポーネント型"

  property_definitions {
 property_name = "temperature"
 data_type {
type = "DOUBLE"
 }
 is_time_series = true
  }

  property_definitions {
 property_name = "sensorId"
 data_type {
type = "STRING"
 }
 is_required_in_entity = true
  }

  functions {
 function_name = "dataReader"
 implemented_by {
lambda {
  arn = aws_lambda_function.twinmaker_data_reader.arn
}
 }
  }
}

Entity 階層定義 (Factory → Line → Machine):

resource "aws_iottwinmaker_entity" "factory_a" {
  workspace_id = aws_iottwinmaker_workspace.factory.workspace_id
  entity_id = "FactoryLine-A"
  entity_name  = "製造ライン A"
  description  = "第1工場 製造ラインA"
}

resource "aws_iottwinmaker_entity" "machine_001" {
  workspace_id  = aws_iottwinmaker_workspace.factory.workspace_id
  entity_id  = "Machine-001"
  entity_name= "プレス機 001"
  parent_entity_id = aws_iottwinmaker_entity.factory_a.entity_id

  components {
 component_name = "TemperatureSensor"
 component_type_id = aws_iottwinmaker_component_type.temperature_sensor.component_type_id

 properties {
property_name = "sensorId"
value {
  string_value = "sensor-T001"
}
 }
  }
}

データソースコネクタとして IoT SiteWise を使う場合、ComponentType の functions.dataReader に AWS マネージドコネクタ com.amazon.iotsitewise.connector を指定すると、SiteWise Asset Property との直接バインドが可能だ。Lambda 実装を書かずに SiteWise のリアルタイム値を Entity プロパティとして参照できるため、SiteWise 既存ユーザーにとって最も省力な構成になる。

§4-4. Scene 設計 — 3D Viewer × GLTF × OverlayWidget

Scene は 3D ビジュアライゼーションの定義だ。GLTF 形式の 3D モデルファイルを S3 にアップロードし、Scene 定義で Entity との紐付けと OverlayWidget を設定する。Scene 定義は JSON 形式で S3 に保存する。

{
  "version": "1.0",
  "unit": "meters",
  "nodes": [
 {
"id": "factory-node",
"name": "製造ライン A",
"transform": {
  "position": [0, 0, 0],
  "rotation": [0, 0, 0],
  "scale": [1, 1, 1]
},
"components": [
  {
 "type": "ModelRef",
 "uri": "s3://iot-twinmaker-workspace-prod/models/factory_line_a.gltf",
 "modelType": "GLTF"
  },
  {
 "type": "Tag",
 "valueDataBinding": {
"dataBindingContext": {
  "entityId": "Machine-001",
  "componentName": "TemperatureSensor",
  "propertyName": "temperature"
}
 }
  }
]
 }
  ],
  "rootNodeIndexes": [0]
}

OverlayWidget: 温度・圧力・回転数などのリアルタイム値を 3D モデル上にゲージ表示できる。警告閾値を超えると Widget の色が赤に変わる設定が可能で、オペレーターが 3D ビューを見るだけで設備状態を把握できるインターフェースになる。

IoT TwinMaker 構成図
図03: IoT TwinMaker の Workspace × Entity × Component × Scene × GenAI Connector 統合構成

§4-5. GenAI Connector — TwinMaker × Bedrock 連携

AWS IoT TwinMaker の GenAI Connector は Bedrock の Claude モデルとデジタルツインを統合し、自然言語でのデータ問い合わせと異常検知支援を実現する機能だ。

自然言語クエリの仕組み:

① オペレーター: 「昨日から機械 001 の温度が高い原因は何か」と自然言語で入力
② GenAI Connector が TwinMaker の Entity/Component スキーマを Claude に渡す
③ Claude が適切な時系列クエリを生成し、
Timestream / SiteWise からデータを取得
④ Claude が取得データを解析し、
根本原因候補を自然言語でオペレーターに回答

IAM 権限設定 — Bedrock InvokeModel 追加:

resource "aws_iam_role_policy" "twinmaker_bedrock" {
  name = "twinmaker-bedrock-policy"
  role = aws_iam_role.twinmaker_workspace.id

  policy = jsonencode({
 Version = "2012-10-17"
 Statement = [
{
  Effect = "Allow"
  Action = [
 "bedrock:InvokeModel",
 "bedrock:InvokeModelWithResponseStream"
  ]
  Resource = "arn:aws:bedrock:ap-northeast-1::foundation-model/anthropic.claude-3-5-sonnet-20241022-v2:0"
}
 ]
  })
}

異常検知支援として、Dataset で生成した日次異常レポートを Claude に渡し「通常範囲から逸脱しているセンサーと考えられる原因」を自然言語レポートとして出力するパターンが実用的だ。Lambda でレポートを定期実行し、結果を SNS 経由で担当者にメール通知する構成が本番でよく使われる。

§4-6. Grafana 連携 — IoT TwinMaker Grafana Plugin

IoT TwinMaker Grafana Plugin を使うと、Grafana ダッシュボードに TwinMaker の 3D Scene を埋め込み、時系列グラフと 3D ビューを同一画面に表示できる。

Grafana データソース設定:

{
  "name": "IoT TwinMaker",
  "type": "grafana-iot-twinmaker-datasource",
  "jsonData": {
 "workspaceId": "factory-digital-twin",
 "assumeRoleArn": "arn:aws:iam::123456789012:role/grafana-twinmaker-role",
 "defaultRegion": "ap-northeast-1"
  }
}

Grafana パネルで entityIdcomponentNamepropertyName を指定すると、Entity のリアルタイムプロパティをグラフ表示できる。3D Scene Panel と時系列グラフパネルを組み合わせると、「グラフで異常を検知 → 3D ビューで対象機器を特定 → GenAI Connector で原因分析」という一気通貫のオペレーションダッシュボードが完成する。

§4-7. コスト設計

IoT TwinMaker は Workspace 数・Entity 数・Scene 閲覧時間で課金される。

主要課金モデル (ap-northeast-1 目安):
Workspace: 約 $10.00 / 月 (Workspace 単位で固定費発生)
Entity: 約 $0.01 / Entity / 月 (最初の 10 Entity は無料枠あり)
Scene 閲覧: セッション時間ベースで課金 (分単位)
データソースクエリ: 各データソース (SiteWise/Timestream) の課金に加算

本番運用では Entity の粒度設計がコストを左右する。センサー 1 つを 1 Entity にすると 1,000 センサー規模で月額 $10 の Entity 費用になるが、設備 (Machine) を Entity とし各センサーを Component にまとめると Entity 数を大幅に削減できる。物理的な機器単位を Entity 粒度の基本とし、センサーは Component として集約するアーキテクチャが最もコスト効率が高い。

🔥 IoT TwinMaker よくある設定ミス

① Entity 階層設計の誤り — 粒度が細かすぎる: センサーを 1 つずつ Entity として登録すると、数千センサー規模で Entity 課金が急増する。正解は Machine や Asset を Entity 単位とし、センサーを Component にまとめること。Component は 1 つの Entity に複数定義でき、各 Component に複数のプロパティも持てる。Entity 数は設計フェーズで試算し、月額コストを予算に含めること。

② Scene のパフォーマンス劣化 — 無最適化 GLTF のアップロード: CAD から直接エクスポートした GLTF は数百 MB になることがある。この状態で Scene に設定すると 3D Viewer の初回読込が 30 秒超になる。ポリゴン数削減 (1 モデルあたり 50 万ポリゴン以下を目安)、テクスチャ圧縮 (KTX2/Basis Universal 形式)、LOD (Level of Detail) の 3 段階設定を施した最適化済み GLTF を使うこと。大規模施設は建屋・フロア・ラインごとに GLTF を分割し、表示範囲に応じた遅延読込を実装する設計が有効だ。

③ GenAI Connector 権限エラー — Bedrock リソースポリシー未確認: GenAI Connector を有効化しても Bedrock の呼出が 403 になる場合、Workspace IAM ロールの bedrock:InvokeModel 権限だけでなく、使用する Bedrock モデルのモデルアクセス許可 (Bedrock コンソール → モデルアクセス) も有効化する必要がある。特に Claude 3 系モデルを東京リージョン (ap-northeast-1) 以外から呼び出す場合はクロスリージョン推論 (Cross-region inference) の設定も確認すること。

✅ IoT TwinMaker 採用判断チェックリスト

以下の条件を確認し、3 項目以上 Yes なら IoT TwinMaker の積極採用を推奨する。

  • □ 物理設備・施設の 3D モデル (GLTF/CAD) が存在する、または作成可能
  • □ オペレーターが設備状態を「場所」と「状態」の両方で把握する必要がある
  • □ IoT SiteWise / Timestream にリアルタイムデータが蓄積されている
  • □ 設備の階層関係 (建屋→フロア→ライン→機器) をモデル化したい
  • □ 自然言語での設備状態問い合わせ (GenAI Connector) を活用したい
  • □ Grafana と統合し時系列グラフ + 3D ビューを同一画面で提供したい

採用を見送る条件: 単純な時系列グラフダッシュボードのみが目的なら Grafana + Timestream 直接接続で十分だ。IoT TwinMaker は 3D ビジュアライゼーションと Entity 階層モデリングに価値があるため、そのユースケースが明確でない場合はオーバースペックになる。また、3D モデルが存在しない・作成コストが高い環境ではまず §3 の IoT Analytics + Grafana による 2D ダッシュボードから着手し、将来的な TwinMaker 移行を計画するアプローチが現実的だ。

IoT Analytics でデータを蓄積・分析し、IoT TwinMaker で 3D デジタルツインとして可視化する基盤が整った。次の §5 では、コネクテッドビークル向けのデータ収集基盤 IoT FleetWise の本番設計を解説する。


§5 IoT FleetWise 本番運用 — Vehicle model × Signal catalog × Campaign × Edge agent ★山場2

AWS IoT FleetWise は、車両・産業機械の OBD-II / CAN bus データを大規模にクラウド収集するフルマネージドサービスだ。
車両側に Edge Agent を組み込み、Signal Catalog で定義した信号を Campaign で選択収集し、S3 / Timestream に送信する。
従来の自前テレマティクス基盤では、CAN バスデコーダー実装・接続断時バッファ管理・スケール対応が個別開発となり運用コストが高騰していた。
FleetWise はこれらをマネージドレイヤーで吸収し、「何の信号をどの条件で収集するか」というビジネスロジックに集中できる設計思想を持つ。

主要ユースケース:
– 自動車メーカー: OBD-II 診断データ (エンジン温度・RPM・燃費) の大規模フリート収集
– 建設・農業機械: CAN bus センサーデータ (油圧・負荷・位置) の予兆保全分析
– 商用トラック: 走行距離・ブレーキ圧・タイヤ空気圧の遠隔モニタリング
– EV フリート: バッテリー SOC・充電ステータス・熱管理データのリアルタイム収集

IoT FleetWise 構成図
図04: IoT FleetWise の Vehicle model × Signal catalog × Campaign × Edge agent 統合車両データ収集構成


IoT FleetWise 公式ドキュメント

5-1. Signal Catalog 設計 — 信号定義の組織標準化

Signal Catalog は FleetWise の中核となる信号ライブラリだ。OBD-II / CAN / アクチュエーター信号を一元定義し、
Vehicle Model や Campaign から参照される。VSS (Vehicle Signal Specification) 準拠の階層構造で管理する。

信号タイプ:

タイプ説明
SENSORセンサー読み取り値 (読み取り専用)エンジン温度、車速、RPM
ACTUATORアクチュエーター制御値スロットル開度、EV 充電指示
ATTRIBUTE車両静的属性VIN、型式、製造年

VSS 準拠の階層構造例:

Vehicle
├── Speed # 車速 (km/h)
├── Powertrain
│├── Engine
││├── Speed  # エンジン RPM
││├── Coolant.Temperature# 冷却水温度 (°C)
││└── Oil.Temperature # エンジンオイル温度 (°C)
│└── FuelSystem
│ └── SupplyPressure  # 燃料供給圧力 (kPa)
├── Chassis
│├── Brake.PedalPosition # ブレーキペダル踏み込み量 (%)
│└── Axle.Row1.Wheel.Tire.Pressure  # タイヤ空気圧 (kPa)
└── Body.Lights.Beam.Low.IsActive # ロービーム ON/OFF

Terraform: Signal Catalog 作成:

resource "aws_iotfleetwise_signal_catalog" "fleet" {
  name  = "vehicle-signal-catalog"
  description = "OBD-II / CAN bus 信号カタログ"

  node {
 branch {
fully_qualified_name = "Vehicle"
description = "車両ルートノード"
 }
  }
  node {
 branch {
fully_qualified_name = "Vehicle.Powertrain.Engine"
 }
  }
  node {
 sensor {
fully_qualified_name = "Vehicle.Speed"
description = "車速"
unit  = "km/h"
data_type= "DOUBLE"
min= 0.0
max= 300.0
 }
  }
  node {
 sensor {
fully_qualified_name = "Vehicle.Powertrain.Engine.Speed"
description = "エンジン回転数"
unit  = "rpm"
data_type= "DOUBLE"
min= 0.0
max= 8000.0
 }
  }
  node {
 sensor {
fully_qualified_name = "Vehicle.Powertrain.Engine.Coolant.Temperature"
description = "冷却水温度"
unit  = "celsius"
data_type= "DOUBLE"
min= -40.0
max= 130.0
 }
  }
}

Signal Catalog の設計原則: OBD-II PID コードと VSS 名称のマッピングは社内標準ドキュメントで管理し、
チーム横断で統一する。信号定義は後から変更しにくいため、初期設計に時間をかけることが長期運用コスト削減に直結する。

5-2. Vehicle Model — 車両モデル定義とネットワークインターフェース

Vehicle Model は Signal Catalog のサブセットを使用する車両テンプレートだ。
ネットワークインターフェース (CAN bus / OBD-II) と信号デコード方式を定義する。

ネットワークインターフェース種別:

タイプ説明適用ケース
OBD_INTERFACEOBD-II ポート経由標準診断データ (汎用車種対応)
CAN_INTERFACECAN bus 直接接続高速リアルタイムデータ (エンジン制御)
CUSTOM_DECODINGカスタムデコーダープロプライエタリプロトコル

Terraform: Vehicle Model 定義 (OBD-II デコーダー付き):

resource "aws_iotfleetwise_vehicle_model" "standard_vehicle" {
  name= "standard-vehicle-model"
  description  = "標準乗用車モデル (OBD-II)"
  signal_catalog_arn = aws_iotfleetwise_signal_catalog.fleet.arn

  model_manifest_actions = ["ACTIVE"]

  network_interfaces {
 interface_id = "obd-interface-1"
 type= "OBD_INTERFACE"
 obd_interface {
name= "obd-main"
request_message_id = 2015
 }
  }

  signal_decoders {
 fully_qualified_name = "Vehicle.Speed"
 type  = "OBD_SIGNAL"
 interface_id= "obd-interface-1"
 obd_signal {
pid_response_length = 2
service_mode  = 1
pid  = 13
scaling = 1.0
offset  = 0.0
start_byte = 0
byte_length= 1
bit_mask_length  = 8
bit_right_shift  = 0
 }
  }

  signal_decoders {
 fully_qualified_name = "Vehicle.Powertrain.Engine.Speed"
 type  = "OBD_SIGNAL"
 interface_id= "obd-interface-1"
 obd_signal {
pid_response_length = 2
service_mode  = 1
pid  = 12
scaling = 0.25
offset  = 0.0
start_byte = 0
byte_length= 2
bit_mask_length  = 16
bit_right_shift  = 0
 }
  }

  signal_decoders {
 fully_qualified_name = "Vehicle.Powertrain.Engine.Coolant.Temperature"
 type  = "OBD_SIGNAL"
 interface_id= "obd-interface-1"
 obd_signal {
pid_response_length = 2
service_mode  = 1
pid  = 5
scaling = 1.0
offset  = -40.0
start_byte = 0
byte_length= 1
bit_mask_length  = 8
bit_right_shift  = 0
 }
  }
}

Vehicle Model のバージョン管理戦略: 信号デコーダーの変更は Vehicle Model の新バージョン作成が必要だ。
既存 Campaign への影響を最小化するため、旧バージョンと並行稼働させるブルー/グリーン移行を採用する。

5-3. Campaign 設計 — データ収集ジョブと収集モード選択

Campaign はいつ・どの信号を・どこに送るかを定義するデータ収集ジョブだ。
TIME_BASED (一定間隔収集) と TRIGGER_BASED (条件トリガー) の 2 モードがある。

収集モード比較:

モード特性適用ケースコスト傾向
TIME_BASED一定間隔で全信号収集走行ログ・安全性監査高 (データ量大)
TRIGGER_BASED条件成立時のみ収集異常検知・コスト最適化低 (選択的)

Terraform: Campaign 定義 (TRIGGER_BASED — 冷却水温度異常検知):

resource "aws_iotfleetwise_campaign" "engine_anomaly" {
  name= "engine-anomaly-detection"
  description  = "冷却水温度 100°C 超過時のエンジン異常収集"
  signal_catalog_arn = aws_iotfleetwise_signal_catalog.fleet.arn
  target_arn= aws_iotfleetwise_fleet.main.arn
  collection_scheme  = "TRIGGER_BASED"

  trigger_config {
 condition_based_collection_scheme {
condition_expression = "$variable.`Vehicle.Powertrain.Engine.Coolant.Temperature` > 100.0"
trigger_mode= "RISING_EDGE"
condition_language_version = 1
 }
  }

  signals_to_collect {
 name = "Vehicle.Speed"
 minimum_sampling_interval_ms = 500
  }
  signals_to_collect {
 name = "Vehicle.Powertrain.Engine.Coolant.Temperature"
 minimum_sampling_interval_ms = 250
  }

  data_destination_configs {
 timestream_config {
timestream_table_arn = aws_timestreamwrite_table.vehicle_data.arn
execution_role_arn= aws_iam_role.fleetwise_timestream.arn
 }
  }

  post_trigger_collection_duration = 30000

  approval_status = "APPROVE"
}

Terraform: Campaign 定義 (TIME_BASED — 通常走行ログ / S3 送信):

resource "aws_iotfleetwise_campaign" "normal_driving_log" {
  name= "normal-driving-log"
  collection_scheme  = "TIME_BASED"
  signal_catalog_arn = aws_iotfleetwise_signal_catalog.fleet.arn
  target_arn= aws_iotfleetwise_fleet.main.arn

  time_based_collection_scheme {
 period_ms = 30000
  }

  signals_to_collect {
 name = "Vehicle.Speed"
 minimum_sampling_interval_ms = 1000
  }

  data_destination_configs {
 s3_config {
bucket_arn  = aws_s3_bucket.vehicle_data.arn
prefix= "driving-logs/"
data_format = "JSON"
storage_compression_format = "GZIP"
 }
  }

  approval_status = "APPROVE"
}

Campaign 設計の要点: minimum_sampling_interval_ms で Edge Agent の過剰サンプリングを防ぐ。
S3 行き (長期保存・Athena 分析) と Timestream 行き (リアルタイム分析) を用途別に Campaign 分割するのが
運用ベストプラクティスだ。承認 (APPROVE) 後はフリート全車両へ Over-The-Air で自動配信される。

5-4. Edge Agent — 車両組み込みと接続断時動作

AWS IoT FleetWise Edge Agent はオープンソース (Apache 2.0) の C++ 実装だ。
Raspberry Pi / NXP i.MX / Renesas R-Car など Linux ベースの車載 ECU にビルドして組み込む。

Edge Agent 主要機能:

機能説明
CAN bus 読み取りsocketCAN 経由でリアルタイム読み取り
OBD-II 通信ISO 15765-4 準拠のポーリング
ローカルバッファ接続断時に SQLite でキューイング
Campaign 同期クラウドから Campaign 定義を自動受信・適用
mTLS 接続AWS IoT Core エンドポイントへの相互認証

接続断時のデータフロー:

[通常時]
Edge Agent → IoT Core (mTLS) → Campaign 定義に従いリアルタイム送信

[接続断時]
Edge Agent → SQLite ローカルバッファ (persistencyPartitionMaxSize 上限まで蓄積)
 ↓ 再接続成功
Edge Agent → IoT Core → バッファ分を FIFO 順に送信
 ↓ バッファ上限超過
Edge Agent → 古いデータから自動破棄 (Eviction policy: OLDEST_FIRST)

Edge Agent 主要設定 (config.json の staticConfig 抜粋):

{
  "staticConfig": {
 "bufferSizes": {
"encodedSignalBufferSize": 10000,
"rawCANFrameBufferSize": 10000
 },
 "persistency": {
"persistencyPath": "/var/aws-iot-fleetwise/",
"persistencyPartitionMaxSize": 524288000
 },
 "mqttConnection": {
"endpointUrl": "YOUR_ENDPOINT.iot.ap-northeast-1.amazonaws.com",
"clientId": "${VIN}",
"collectionSchemeListTopic": "$aws/iotfleetwise/vehicles/${VIN}/collection_schemes",
"decoderManifestTopic": "$aws/iotfleetwise/vehicles/${VIN}/decoder_manifests",
"canDataTopic": "$aws/iotfleetwise/vehicles/${VIN}/signals",
"certificate": "/etc/aws-credentials/certificate.pem.crt",
"privateKey": "/etc/aws-credentials/private.pem.key",
"rootCA": "/etc/aws-credentials/AmazonRootCA1.pem"
 }
  }
}

接続断対応の設計指針:
persistencyPartitionMaxSize: 典型的な接続断時間 × 想定データ量で算出 (例: トンネル 5 分 × 1 MB/分 = 最低 5 MB)
– バッファ上限は車載ストレージ容量の 20% 以内に収める
– VIN を ClientId に使用し、車両ごとの接続を一意に識別する
– 再接続後のバースト送信レートは IoT Core のスロットリング設定で制御する

5-5. Timestream 連携 + Grafana リアルタイム分析

IoT FleetWise → Amazon Timestream の連携で、車両データを時系列データベースに格納しリアルタイム分析できる。

Terraform: Timestream テーブルと IAM ロール:

resource "aws_timestreamwrite_database" "vehicle_db" {
  database_name = "vehicle-telemetry"
}

resource "aws_timestreamwrite_table" "vehicle_data" {
  database_name = aws_timestreamwrite_database.vehicle_db.database_name
  table_name = "vehicle-signals"

  retention_properties {
 memory_store_retention_period_in_hours  = 24
 magnetic_store_retention_period_in_days = 365
  }
}

resource "aws_iam_role" "fleetwise_timestream" {
  name = "fleetwise-timestream-role"
  assume_role_policy = jsonencode({
 Version = "2012-10-17"
 Statement = [{
Effect = "Allow"
Principal = { Service = "iotfleetwise.amazonaws.com" }
Action = "sts:AssumeRole"
 }]
  })
}

resource "aws_iam_role_policy" "fleetwise_timestream" {
  role = aws_iam_role.fleetwise_timestream.id
  policy = jsonencode({
 Version = "2012-10-17"
 Statement = [{
Effect= "Allow"
Action= ["timestream:WriteRecords", "timestream:DescribeEndpoints"]
Resource = aws_timestreamwrite_table.vehicle_data.arn
 }]
  })
}

Timestream クエリ例 (Grafana パネル向け):

SELECT
  time,
  measure_value::double AS coolant_temp_celsius
FROM "vehicle-telemetry"."vehicle-signals"
WHERE
  measure_name = 'Vehicle.Powertrain.Engine.Coolant.Temperature'
  AND vehicleId = 'VIN-001'
  AND time > ago(1h)
ORDER BY time ASC

Grafana Amazon Timestream プラグインでこのクエリをパネル化し、フリート全体のヒートマップを構築できる。
リアルタイム監視はメモリストア、バッチ集計は S3 Athena から参照する 2 層クエリアーキテクチャが最適解だ。

5-6. コスト設計 — Vehicle 登録費 × Campaign データ量 × Timestream 書き込み

FleetWise の主要課金項目:

課金項目単価 (参考)最適化方針
Vehicle 登録$1.00 / 台 / 月フリート台数の計画的管理
Campaign データ収集$0.00025 / MBTRIGGER_BASED で収集量を削減
Timestream 書き込み$0.50 / 100 万レコードmemory_store 保持時間を最小化
S3 保存S3 標準料金GZIP 圧縮で 60-70% 削減

コスト試算例 (1,000 台フリート / 1 ヶ月):

Vehicle 登録: 1,000 台 × $1.00 = $1,000
TIME_BASED (30 秒間隔 / 5 信号):
  1.2 MB/台/時 × 720 時間 × 1,000 台= 864 GB → $216,000
TRIGGER_BASED (発火率 10% に絞った場合):
  864 GB × 0.10 =  86 GB →  $21,600

→ TRIGGER_BASED 移行でデータ収集コスト 90% 削減が可能

TIME_BASED の全データ収集は開発・検証フェーズのデバッグ用途に限定し、
本番フリートは TRIGGER_BASED Campaign を基本とするコスト設計を徹底する。

🔥 IoT FleetWise 本番設計 3鉄則

(1) Signal Catalog 設計を組織標準化せよ
Signal Catalog は後から変更しにくい基盤コンポーネントだ。OBD-II PID と VSS 階層名の対応表を社内標準ドキュメントで管理し、複数チームが独自定義を乱立させないよう統一ガバナンスを敷く。Signal Catalog の変更管理は semantic versioning と Vehicle Model のバージョン管理を連動させることで、既存 Campaign への影響を局所化できる。初期設計に十分な時間を投資することが長期的な運用コスト削減の鍵だ。

(2) Campaign は TRIGGER_BASED から設計せよ
TIME_BASED の全信号収集は開発・デバッグフェーズ専用と割り切る。本番フリートには TRIGGER_BASED Campaign を適用し、異常条件 (温度超過・加速度閾値・速度逸脱) をトリガーにして選択的にデータを収集する。Campaign 承認前に発火頻度シミュレーションでデータ量とコストを見積もること。フリート台数が多いほどトリガー条件の精度がコストに直結するため、condition_expression の設計に十分な検証期間を設ける。

(3) Edge Agent の接続断設計を本番前に検証せよ
トンネル・地下駐車場・山間部などの接続断シナリオを事前にシミュレーションし、persistencyPartitionMaxSize が実際の切断時間に対して十分かを検証する。再接続後のバースト送信が IoT Core のスロットリングを引き起こさないか、ロードテストで必ず確認する。バッファ上限超過時は古いデータから自動破棄されるため、保全必須データがある場合は優先度設定と保存戦略を組み合わせること。

⚠️ IoT FleetWise vs 自前車両データ収集 — 採用判断チェックリスト

以下に多く該当するほど IoT FleetWise の優位性が高い:

✅ フリート台数が 100 台超 (スケール管理コストが自前実装を上回る)
✅ OBD-II / CAN bus データが主要ソース (FleetWise のデコーダー対応範囲内)
✅ Vehicle モデルバリエーションが多い (Signal Catalog の再利用価値が高い)
✅ 接続断が頻発する運用環境 (Edge Agent のローカルバッファが不可欠)
✅ Timestream / S3 Athena での分析が必要 (マネージド連携で実装コスト削減)
✅ Campaign を動的変更したい (クラウドから OTA で収集定義を変更可能)
✅ OBD-II / CAN デコーダーを自前実装したくない (Decoder Manifest で管理)

❌ 自前収集が有利なケース:
独自プロトコル (CAN matrix 非公開) のみ利用 / 超低レイテンシ要件 / 既存テレマティクス基盤が充実 / IoT FleetWise 非対応リージョンでの運用が必須

✅ IoT FleetWise コスト最適化のポイント

Trigger-based 収集設計
異常検知系 Campaign は必ず TRIGGER_BASED を使用する。condition_expression に AND/OR の複合条件を組み合わせて発火精度を高め、誤発火によるデータ量膨張を防ぐ。post_trigger_collection_duration は最小限 (10-30 秒) に設定し、イベント前後の文脈データのみを取得する設計にする。

Signal 絞り込み戦略
Signal Catalog に全信号を定義しても、Campaign の signals_to_collect は実際に必要な信号だけに絞る。診断用途なら OBD-II 5 信号、安全監査なら速度・制動の 2 信号など、ユースケース別に Campaign を分割して最小信号セットを徹底する。不要信号を収集し続けると Timestream の書き込み回数とコストが線形に増加する。

Timestream 保持期間の最適化
memory_store_retention_period_in_hours を必要最小限 (24-48 時間) に設定し、高コストのメモリストアを削減する。Grafana リアルタイムダッシュボードはメモリストア、バッチ分析は S3 Athena から参照する 2 層クエリアーキテクチャにより、コストとパフォーマンスを両立できる。長期データは磁気ストアから定期的に S3 エクスポートして Athena 分析に切り替えると総保有コストを大幅に削減できる。

§5 で習得した FleetWise 4 本柱 (Signal Catalog / Vehicle Model / Campaign / Edge Agent) は車両データ収集の設計土台となる。
次の §6 では FleetWise を含む IoT 4 サービス横断で、現場で頻発する詰まりポイント 7 選を図解する。


§6 詰まりポイント7選 図解 (Mermaid01 判断ツリー)

IoT Vol2 の4サービス (Events/Analytics/TwinMaker/FleetWise) を本番運用する際に頻出する詰まりポイントを7パターンに体系化した。各パターンは「症状 → 原因 → 解決策」の構造で示す。まず全7パターンを一枚の判断ツリーで俯瞰する。

flowchart TD
  A[IoT Vol2 問題発生] --> B{IoT Events Detector Model?}
  B -->|Yes| C[State machine最小化+Multi-detector確認]
  B -->|No| D{IoT Analytics Pipeline?}
  D -->|Yes| E[Activity数/Lambda変換コスト確認]
  D -->|No| F{TwinMaker Scene?}
  F -->|Yes| G[3Dモデルサイズ最適化確認]
  F -->|No| H{FleetWise Campaign?}
  H -->|Yes| I[Trigger-based収集+Signal絞り込み確認]
  H -->|No| J{コスト超過?}
  J -->|Yes| K[Reserved capacity/Edge同期頻度確認]
  J -->|No| L{データ品質問題?}
  L -->|Yes| M[Pipeline欠損値/外れ値処理確認]
  L -->|No| N[Edge agent接続断バッファ動作確認]

詰まり1: Detector Model 複雑化罠 — State machine 肥大化と Multi-detector スケーリング設計

症状: Detector Model の State 数が 20 を超えたあたりから、状態遷移の可読性が急激に低下しデバッグに時間がかかる。さらに同一モデルで 1,000 台以上のデバイスを管理しようとしたとき、単一 Detector では処理が詰まり始める。

原因: Detector Model はアラーム・正常・警告など論理上は単純な状態を無計画に追加していくと State 数が線形増加する。IoT Events は 1 Detector Model インスタンスが 1 論理エンティティ (デバイス1台分) に対応するため、物理デバイス数 = Detector インスタンス数となり課金も線形増加する。

解決策: State machine を「正常 / 警告 / 異常」の 3 状態以内に収め、複雑な条件分岐は Lambda Actions でオフロードする。複数デバイスをまとめて管理したい場合は key フィールドで Multi-detector を構成し、デバイスごとに独立したインスタンスを自動生成させる。

{
  "detectorModelDefinition": {
 "states": [
{
  "stateName": "Normal",
  "onInput": {
 "transitionEvents": [
{"eventName":"toWarning","condition":"$input.sensor.temp > 70","actions":[],"nextState":"Warning"}
 ]
  }
},
{
  "stateName": "Warning",
  "onInput": {
 "transitionEvents": [
{"eventName":"toAlarm","condition":"$input.sensor.temp > 90","actions":[{"sns":{"targetArn":"arn:aws:sns:ap-northeast-1:123456789012:iot-alerts"}}],"nextState":"Alarm"},
{"eventName":"toNormal","condition":"$input.sensor.temp < 60","actions":[],"nextState":"Normal"}
 ]
  }
},
{
  "stateName": "Alarm",
  "onInput": {
 "events": [{"eventName":"SendAlert","actions":[{"lambda":{"functionArn":"arn:aws:lambda:ap-northeast-1:123456789012:function:emergency-handler"}}]}],
 "transitionEvents": [
{"eventName":"toNormal","condition":"$input.sensor.temp < 60","actions":[],"nextState":"Normal"}
 ]
  }
}
 ],
 "initialStateName": "Normal"
  },
  "key": "deviceId"
}
詰まり1 対処サマリ
State は「正常 / 警告 / 異常」の 3 状態を基本とし、複雑ロジックは Lambda にオフロードする。Multi-detector は key フィールドで有効化し、デバイス 1 台 = 1 Detector インスタンスの対応を明示的に設計する。State 数 20 超が見えた時点でアーキテクチャ見直しのトリガーとする。

詰まり2: IoT Analytics Pipeline activity 罠 — Lambda 変換コスト爆発とバッチ遅延

症状: IoT Analytics Pipeline の Lambda activity を多用したところ、メッセージ数に比例して Lambda 実行コストが急増した。また Lambda 内で外部 API を呼ぶ処理を入れたため、Pipeline のレイテンシが数秒に達し、Notebook 分析のリアルタイム性が失われた。

原因: Pipeline の Lambda activity はメッセージ 1 件ごとに Lambda を同期呼び出しする設計のため、1 日 100 万メッセージ × Lambda 実行単価が直接コストに反映される。外部 API 呼び出しを Lambda 内で行うとその応答待ちが Pipeline のスループットを制限する。

解決策: 単純なフィールド変換は Math activityAddAttributes activity で処理し、Lambda は複雑なビジネスロジックにのみ使う。バッチ的に変換が必要な場合は Dataset の SQL クエリ層で変換し、Lambda 実行回数を削減する。

resource "aws_iotanalytics_pipeline" "sensor_pipeline" {
  name = "sensor-pipeline"

  pipeline_activities {
 channel {
name= "ChannelActivity"
channel_name = aws_iotanalytics_channel.sensor.name
next= "FilterActivity"
 }
  }

  pipeline_activities {
 filter {
name= "FilterActivity"
filter = "temp > 0 AND temp < 200"
next= "MathActivity"
 }
  }

  pipeline_activities {
 math {
name= "MathActivity"
attribute = "temp_f"
math= "temp * 1.8 + 32"
next= "DatastoreActivity"
 }
  }

  pipeline_activities {
 datastore {
name  = "DatastoreActivity"
datastore_name = aws_iotanalytics_datastore.sensor.name
 }
  }
}
詰まり2 対処サマリ
Lambda activity はメッセージ数 × 実行コストが比例するため、単純変換は Math/AddAttributes/Filter activity に置き換える。複雑変換は Dataset SQL 層に移し Lambda 実行回数を最小化する。Pipeline に外部 API 呼び出しを組み込まない設計を徹底する。

詰まり3: TwinMaker Scene 最適化 — 大規模 3D モデルのブラウザパフォーマンス低下

症状: 工場全体の 3D CAD データ (GLB 形式 500MB 超) を TwinMaker Scene に取り込んだところ、Grafana TwinMaker パネルのロードに 30 秒以上かかり、ブラウザのメモリ使用量が 4GB に達してクラッシュするケースが出た。

原因: TwinMaker Scene の 3D モデルは S3 から直接ブラウザにストリームされる。巨大な GLB ファイルを 1 ファイルで管理すると初期ロード量が膨大になる。また高ポリゴンモデルをそのまま使うと GPU レンダリング負荷が高くなる。

解決策: 3D モデルを階層ごとに分割し、必要なエリアだけをロードする LOD (Level of Detail) 設計を採用する。GLB ファイルは draco 圧縮を適用し 90% 以上のサイズ削減を図る。TwinMaker の Entity/Component 階層でロード順序を制御し、初期表示には低解像度モデルを使う。

Scene 設計原則:
  GLB ファイル分割: エリア単位 (建物棟 / フロア / ライン)
  draco 圧縮: 500MB → 30-50MB 目標
  LOD 3段階:
 遠距離 (Low)- 10,000 ポリゴン以下
 中距離 (Medium) - 50,000 ポリゴン以下
 近距離 (High)  - 200,000 ポリゴン以下
  Entity 階層: Factory → Building → Floor → Machine (4 階層)
  初期ロード: Low-LOD モデルのみ
  インタラクション後: 該当 Entity のみ High-LOD へ切り替え
詰まり3 対処サマリ
GLB モデルはエリア単位に分割し draco 圧縮を適用する。Entity 階層で LOD を制御し、初期表示は Low-LOD に限定する。1 ファイル 50MB 以下を目安とし、超える場合は分割を検討する。Scene 全体ポリゴン数の目安は 5 万ポリゴン以下。

詰まり4: FleetWise Campaign コスト — 全信号収集 vs 選択的収集の判断基準

症状: FleetWise Campaign を「全 Signal 収集 / 常時アップロード」で設定したところ、車両 1 台あたりの月次データ転送コストが想定の 10 倍以上になった。クラウドへのアップロード量も膨大で Analytics の Datastore コストも跳ね上がった。

原因: 車両 CAN バスは毎秒数千シグナルを生成する。これを全量 / 常時アップロードすると 1 台あたり数 GB/日のデータ転送が発生する。FleetWise の課金モデルはクラウド転送データ量に比例するため、全量収集は設計ミスとなる。

解決策: Campaign の収集条件を conditionBasedCollectionScheme (Trigger ベース) に変更し、異常条件 (急加速 / 急減速 / 異常温度) が発生した前後数秒間のデータのみを収集する。通常時は低頻度サンプリング (1Hz) に抑える。

resource "aws_iotfleetwise_campaign" "vehicle_anomaly" {
  name= "vehicle-anomaly-campaign"
  signal_catalog_arn = aws_iotfleetwise_signal_catalog.main.arn
  target_arn= aws_iotfleetwise_fleet.main.arn

  collection_scheme {
 condition_based_collection_scheme {
condition_language_version  = 1
expression= "$variable.VehicleSpeed > 120 || $variable.BrakeForce > 80"
minimum_trigger_interval_ms = 5000
trigger_mode = "ALWAYS"
 }
  }

  signals_to_collect {
 name = "Vehicle.Speed"
 max_sample_count = 100
 minimum_sampling_interval_ms = 100
  }

  signals_to_collect {
 name = "Vehicle.BrakeForce"
 max_sample_count = 100
 minimum_sampling_interval_ms = 100
  }

  post_trigger_collection_duration = 5000
}
詰まり4 対処サマリ
Campaign は conditionBasedCollectionScheme を標準とし、異常条件発生時のみ収集する Trigger ベース設計を採用する。通常時は 1Hz 以下のサンプリングに抑える。収集シグナル数は必要最小限に絞り、不要なシグナルは Signal catalog から外す。

詰まり5: コスト最適化罠 — IoT Analytics Reserved capacity と FleetWise Edge 同期頻度

症状: IoT Analytics のコストが月に急増した。調査すると Pipeline の処理量に対して Reserved capacity を過大設定していた。一方 FleetWise の Edge agent が 1 分おきにクラウドと同期しており、通信コストが高止まりしていた。

原因: IoT Analytics の Reserved capacity はスループット保証のための購入済み処理能力で、未使用でも課金される。実際のメッセージレートより大きく設定すると無駄になる。FleetWise Edge agent のクラウド同期頻度はデフォルトで短く設定されているケースがあり、Campaign 更新が頻繁でない場合は短い同期間隔は不要なコストになる。

解決策: IoT Analytics は実際のメッセージレートを CloudWatch Metrics (IncomingMessages) で計測し、Reserved capacity を実測値 + 20% バッファで設定する。FleetWise Edge agent の同期間隔は Campaign 更新頻度に合わせ、運用フェーズでは 15 分〜1 時間に延長する。

IoT Analytics コスト最適化チェックリスト:
  1. CloudWatch: PipelineActivities/IncomingMessages を 2 週間計測
  2. ピークメッセージ/秒 x 1.2 = 適切な Reserved capacity
  3. Reserved capacity は月単位購入 → 削減は翌月から反映
  4. Pipeline activity の Lambda 呼び出し数を最小化 (詰まり2参照)

FleetWise Edge 同期コスト最適化:
  開発/テスト期: 1-5 分同期 (Campaign 検証目的)
  本番稼働期: 15-60 分同期 (Campaign 更新は事前計画)
  緊急更新が必要な場合のみ即時同期を手動トリガー
詰まり5 対処サマリ
IoT Analytics Reserved capacity は実測ベースで設定し過大購入を避ける。FleetWise Edge agent の同期間隔は本番運用フェーズでは 15〜60 分に延長してクラウド通信コストを削減する。コスト計測は月次でレビューし Reserved capacity を段階的に調整する。

詰まり6: Edge 同期 — FleetWise Edge agent 接続断時のデータバッファ動作

症状: 車両がトンネルや地下駐車場に入り LTE 接続が切れると、FleetWise のデータが欠損すると思っていた。しかし期待とは異なり、接続断中のデータが一部しか保存されていないケースが発生した。

原因: FleetWise Edge agent は接続断中のデータをローカルストレージにバッファするが、バッファサイズとデータ保持期間に上限がある。デフォルト設定では 24 時間分を保持するが、高頻度収集 Campaign が動作中の場合は 30 分程度で満杯になることがある。また Edge agent プロセスが再起動 (OTA 更新 / OS クラッシュ) した場合、メモリ内バッファは失われる。

解決策: Edge agent の永続化バッファ (Persistent queue) を有効にし、ストレージに書き込む設定にする。バッファサイズは収集データレート × 想定接続断時間で計算し、十分な容量を確保する。

{
  "staticConfig": {
 "bufferSizes": {
"dtcBufferSize": 100,
"encodedSignalBufferSize": 10000,
"rawCANFrameBufferSize": 10000
 },
 "threadIdleTimes": {
"inspectionThreadIdleTimeMs": 50,
"socketCANInterfaceThreadIdleTimeMs": 50,
"canDecoderThreadIdleTimeMs": 50
 },
 "persistencyPath": "/var/aws-iot-fleetwise",
 "persistencyUploadRetryIntervalMs": 10000
  }
}
詰まり6 対処サマリ
Edge agent の persistencyPath を永続ストレージに設定しバッファをディスクに書き込む。バッファサイズは収集レート × 最大接続断時間 × 1.5 倍で設計する。OTA 更新スケジュールは接続断が少ない時間帯 (屋外走行中) に限定し、再起動によるバッファ消失を最小化する。

詰まり7: データ品質 — IoT Analytics Pipeline 欠損値・外れ値処理パターン

症状: IoT Analytics の Dataset から取得したデータで機械学習モデルを学習させたところ、センサー故障時の null 値や 9999 (エラーコード) が混入し、モデル精度が大幅に低下した。Pipeline に入力時点でのフィルタリングが不十分だった。

原因: IoT デバイスはセンサー故障時に null-199990 などをエラーコードとして送信するが、Pipeline の Filter activity だけでは全パターンを事前定義できない。欠損値は Dataset の SQL クエリ層だけでは後処理が複雑になる。

解決策: Pipeline の Filter activity で明示的な異常値範囲を除外し、Lambda activity で統計的外れ値検出 (物理限界値チェック) を実装する。欠損値はフォワードフィル (前値補完) か、欠損フラグを付加して下流で判定させる方針を統一する。

import json

def lambda_handler(event, context):
 messages = []
 for msg in event.get("messages", []):
  payload = msg.get("payload", {})
  temp = payload.get("temp")

  # 明示的エラーコード除外
  if temp is None or temp in (-1, 9999, 0):
payload["temp"] = None
payload["temp_quality"] = "MISSING"
  # 物理限界値チェック (センサー範囲: -40 〜 150 °C)
  elif temp < -40 or temp > 150:
payload["temp"] = None
payload["temp_quality"] = "OUT_OF_RANGE"
  else:
payload["temp_quality"] = "VALID"

  msg["payload"] = payload
  messages.append(msg)

 return {"messages": messages}
詰まり7 対処サマリ
Pipeline の Filter activity でエラーコード値を事前除外し、Lambda activity で物理上ありえない範囲を除外する。欠損フラグ (temp_quality) を付加して下流の Dataset SQL で WHERE temp_quality = 'VALID' フィルタリングを実装する。欠損率モニタリングは CloudWatch カスタムメトリクスで可視化する。

§7 アンチパターン → 正解パターン変換演習 (5問)

IoT Vol2 の4サービスに関する典型的なアンチパターンを5問の演習形式で学ぶ。各問は「状況説明 → アンチパターン → 正解パターン → 解説」の構造で構成する。


Q1: Rules engine 単独 → IoT Events Detector Model (複雑状態管理 / State machine 設計)

状況: 工場の温度センサーが「正常 → 警告 → 危険」と状態遷移する。初期実装では IoT Core の Rules engine で Lambda を呼び出し、DynamoDB に状態を書き込んで状態遷移を管理していた。

アンチパターン: Lambda + DynamoDB で状態機械を自前実装

# Lambda で DynamoDB に状態を書き込み / 読み取りして状態遷移を管理
def lambda_handler(event, context):
 device_id = event["deviceId"]
 temp = event["temperature"]
 # DynamoDB から現在状態を取得
 current_state = get_state_from_dynamodb(device_id)
 # 手動で状態遷移ロジックを実装
 if current_state == "Normal" and temp > 80:
  new_state = "Warning"
  send_alert(device_id, "Warning")
 elif current_state == "Warning" and temp > 95:
  new_state = "Critical"
  trigger_emergency(device_id)
 # DynamoDB に状態を書き込み (競合状態リスクあり)
 save_state_to_dynamodb(device_id, new_state)

正解パターン: IoT Events の Detector Model で状態機械をマネージドに管理

resource "aws_iotevents_detector_model" "factory_monitor" {
  name  = "FactoryTemperatureMonitor"
  role_arn = aws_iam_role.iotevents.arn
  evaluation_method = "SERIAL"

  definition {
 initial_state_name = "Normal"

 state {
state_name = "Normal"
on_input {
  transition_events {
 event_name = "ToWarning"
 condition  = "$input.SensorInput.temperature > 80"
 next_state = "Warning"
 actions {
sns { target_arn = aws_sns_topic.alerts.arn
  payload { content_expression = "'Warning triggered'" type = "STRING" }
}
 }
  }
}
 }

 state {
state_name = "Warning"
on_input {
  transition_events {
 event_name = "ToCritical"
 condition  = "$input.SensorInput.temperature > 95"
 next_state = "Critical"
 actions {
lambda { function_arn = aws_lambda_function.emergency.arn
  payload { content_expression = "'{}'" type = "STRING" }
}
 }
  }
  transition_events {
 event_name = "ToNormal"
 condition  = "$input.SensorInput.temperature < 75"
 next_state = "Normal"
 actions {}
  }
}
 }

 state {
state_name = "Critical"
on_input {
  transition_events {
 event_name = "RecoverToNormal"
 condition  = "$input.SensorInput.temperature < 70"
 next_state = "Normal"
 actions {}
  }
}
 }
  }
  key = "deviceId"
}

解説: IoT Events の Detector Model は State machine をマネージドに管理する。DynamoDB への状態書き込み / 競合状態リスク / Lambda コールドスタートによるレイテンシを排除できる。key = "deviceId" により 10,000 台スケールでも追加インフラ不要。


Q2: 自前 ETL Lambda → IoT Analytics Pipeline (フルマネージド / コスト予測可能)

状況: IoT デバイスからのセンサーデータを S3 に保存し、Lambda でバッチ変換してから Athena で分析していた。Lambda の実行時間が長く、コスト予測が困難だった。

アンチパターン: Lambda + S3 + Athena の自前 ETL パイプライン

# アンチパターン: Rules engine → Lambda → S3 の自前 ETL
resource "aws_iot_topic_rule" "to_lambda" {
  name = "SensorToLambda"
  enabled = true
  sql  = "SELECT * FROM 'sensors/+/data'"

  lambda {
 function_arn = aws_lambda_function.etl_transformer.arn
  }
}
# Lambda で複雑な変換 + S3 書き込み → Athena クエリ
# 問題点: Lambda 実行時間が長い / コスト予測困難 / スケール時の並列度管理が複雑

正解パターン: IoT Analytics Pipeline でフルマネージド変換

resource "aws_iotanalytics_channel" "sensor" {
  name = "sensor-channel"
}

resource "aws_iotanalytics_pipeline" "sensor" {
  name = "sensor-pipeline"

  pipeline_activities {
 channel {
name= "ChannelInput"
channel_name = aws_iotanalytics_channel.sensor.name
next= "FilterBadData"
 }
  }
  pipeline_activities {
 filter {
name= "FilterBadData"
filter = "temperature > -40 AND temperature < 150"
next= "ConvertTempF"
 }
  }
  pipeline_activities {
 math {
name= "ConvertTempF"
attribute = "temperature_f"
math= "temperature * 1.8 + 32"
next= "StoreDatastore"
 }
  }
  pipeline_activities {
 datastore {
name  = "StoreDatastore"
datastore_name = aws_iotanalytics_datastore.sensor.name
 }
  }
}

resource "aws_iotanalytics_datastore" "sensor" {
  name = "sensor-datastore"
  datastore_storage {
 customer_managed_s3 {
bucket= aws_s3_bucket.analytics.bucket
key_prefix  = "iot-analytics/"
role_arn = aws_iam_role.iotanalytics.arn
 }
  }
}

解説: IoT Analytics Pipeline は自動スケールするフルマネージドサービスで、Lambda の自前管理を不要にする。Filter / Math / AddAttributes など組み込み activity で標準的な変換をカバーし、Lambda activity はカスタムロジックにのみ絞れる。コストは処理メッセージ数に比例するため予測が容易になる。


Q3: 静的 3D CAD 図 → IoT TwinMaker (デジタルツイン × リアルタイム更新 / GenAI 連携)

状況: 工場設備の監視に静的な 3D CAD 図をスライドで共有していた。設備の状態変化を確認するたびに担当者が現地確認していた。

アンチパターン: 静的 CAD ビューワーで設備状態を人手確認

アンチパターン構成:
  センサー → CloudWatch → アラーム → メール通知 → 担当者が手動で CAD 図と照合
  問題点:
 - リアルタイム性がない (アラームから確認まで数分〜数時間)
 - 設備間の関係性が可視化できない
 - 異常の根本原因特定に時間がかかる

正解パターン: IoT TwinMaker で設備状態をリアルタイム 3D 可視化

resource "aws_iottwinmaker_workspace" "factory" {
  workspace_id = "factory-digital-twin"
  role= aws_iam_role.twinmaker.arn
  s3_location  = "arn:aws:s3:::${aws_s3_bucket.twinmaker.bucket}"
}

resource "aws_iottwinmaker_entity" "production_line" {
  workspace_id = aws_iottwinmaker_workspace.factory.workspace_id
  entity_id = "production-line-01"
  entity_name  = "ProductionLine01"

  component {
 component_name = "TemperatureSensor"
 component_type_id = "com.example.TemperatureSensorComponent"
 properties = {
"temperature" = jsonencode({
  value = {
 expression = "$\{com.amazonaws.iot.timestream.query.TelemetryData.temperature}"
  }
})
 }
  }
}

解説: IoT TwinMaker は 3D モデルにリアルタイムのセンサーデータを重ねて表示できる。Grafana の TwinMaker パネルでブラウザから確認でき、設備の色変化でアラーム状態を即座に可視化する。GenAI Connector (Bedrock Claude) との統合で、異常原因を自然言語で問い合わせることも可能になる。


Q4: 全データ収集 → IoT FleetWise selective signal (コスト削減 / トリガーベース収集)

状況: 車両の全センサーシグナルを常時アップロードする Campaign を設定したところ、車両 100 台で月次の AWS コストが予算の 5 倍に達した。

アンチパターン: 全 Signal / 常時収集 Campaign

# アンチパターン: 全シグナルを常時アップロード
resource "aws_iotfleetwise_campaign" "all_signals" {
  name= "all-signals-always"
  signal_catalog_arn = aws_iotfleetwise_signal_catalog.main.arn
  target_arn= aws_iotfleetwise_fleet.main.arn

  collection_scheme {
 time_based_collection_scheme {
period_ms = 1000  # 1秒ごと全シグナル = 1台あたり数GB/日
 }
  }
  # signals_to_collect を省略 = 全シグナル収集
  # 100台 x 数GB/日 = 数TB/日のデータ転送コスト
}

正解パターン: 条件トリガーベースで必要なシグナルのみ収集

# 通常時: 診断目的の低頻度サンプリング
resource "aws_iotfleetwise_campaign" "baseline" {
  name= "vehicle-baseline"
  signal_catalog_arn = aws_iotfleetwise_signal_catalog.main.arn
  target_arn= aws_iotfleetwise_fleet.main.arn

  collection_scheme {
 time_based_collection_scheme {
period_ms = 60000  # 1分に1回のみ
 }
  }

  signals_to_collect {
 name = "Vehicle.CurrentLocation.Latitude"
 minimum_sampling_interval_ms = 60000
  }
  signals_to_collect {
 name = "Vehicle.Speed"
 minimum_sampling_interval_ms = 60000
  }
}

# 異常時: 条件トリガーで詳細収集
resource "aws_iotfleetwise_campaign" "anomaly" {
  name= "vehicle-anomaly-detail"
  signal_catalog_arn = aws_iotfleetwise_signal_catalog.main.arn
  target_arn= aws_iotfleetwise_fleet.main.arn

  collection_scheme {
 condition_based_collection_scheme {
condition_language_version  = 1
expression= "$variable.Vehicle.Speed > 130 || $variable.Vehicle.BrakeTemp > 300"
minimum_trigger_interval_ms = 10000
trigger_mode = "ALWAYS"
 }
  }

  signals_to_collect {
 name = "Vehicle.Speed"
 minimum_sampling_interval_ms = 100
  }
  signals_to_collect {
 name = "Vehicle.BrakeTemp"
 minimum_sampling_interval_ms = 100
  }
  signals_to_collect {
 name = "Vehicle.EngineRPM"
 minimum_sampling_interval_ms = 100
  }

  post_trigger_collection_duration = 10000
}

解説: 2 Campaign 構成 (通常時: 低頻度ベースライン / 異常時: 条件トリガー詳細) により、収集データ量を 95% 以上削減できる。異常条件発生から 10 秒後までのデータを保存するため、根本原因分析に必要なデータは確保できる。


Q5: オンプレ車両データ分析 → FleetWise + Analytics 連携 (マネージド / スケール)

状況: 車両から収集したデータを自社サーバーで集約し、Python スクリプトで分析していた。車両台数が 1,000 台を超えたところで自社サーバーの処理能力が限界に達した。

アンチパターン: 自社サーバー集約 + Python バッチ分析

アンチパターン構成:
  車両 → LTE → 自社サーバー (IoT Gateway) → ローカル DB → Python バッチ分析
  問題点:
 - 自社サーバーのスケールアップが必要 (コスト / 運用負荷)
 - バッチ分析のリアルタイム性がない
 - サーバー障害時にデータ欠損リスク
 - 車両台数増加で線形コスト増加

正解パターン: FleetWise + IoT Analytics のフルマネージド連携

# FleetWise から S3 経由で IoT Analytics Datastore へ連携
resource "aws_iotfleetwise_campaign" "analytics_feed" {
  name= "analytics-feed"
  signal_catalog_arn = aws_iotfleetwise_signal_catalog.main.arn
  target_arn= aws_iotfleetwise_fleet.main.arn

  collection_scheme {
 time_based_collection_scheme {
period_ms = 5000
 }
  }

  data_destination_configs {
 s3_config {
bucket_arn= aws_s3_bucket.vehicle_data.arn
data_format  = "PARQUET"
prefix = "vehicle-data/"
storage_compression_format = "GZIP"
 }
  }

  signals_to_collect {
 name = "Vehicle.Speed"
 minimum_sampling_interval_ms = 1000
  }
  signals_to_collect {
 name = "Vehicle.FuelLevel"
 minimum_sampling_interval_ms = 5000
  }
}

# S3 → IoT Analytics Channel へのルート (IoT Core Rule経由)
resource "aws_iot_topic_rule" "fleetwise_to_analytics" {
  name = "FleetwiseToAnalytics"
  enabled = true
  sql  = "SELECT * FROM 'fleetwise/+/data'"

  iot_analytics {
 channel_name = aws_iotanalytics_channel.vehicle.name
 role_arn  = aws_iam_role.iot_analytics_rule.arn
  }
}

# Analytics Dataset で集計分析
resource "aws_iotanalytics_dataset" "fleet_summary" {
  name = "fleet-daily-summary"

  content_delivery_rules {
 destination {
s3_destination_configuration {
  bucket= aws_s3_bucket.analytics_results.bucket
  key= "fleet-summary/!{iotanalytics:scheduleTime}/data.csv"
  role_arn = aws_iam_role.iotanalytics.arn
}
 }
  }

  actions {
 action_name = "SqlAction"
 query_action {
sql_query = "SELECT deviceId, AVG(speed) as avg_speed, MAX(speed) as max_speed, AVG(fuel_level) as avg_fuel FROM vehicle_datastore WHERE __dt > current_date - interval '1' day GROUP BY deviceId"
 }
  }

  triggers {
 schedule {
expression = "cron(0 1 * * ? *)"
 }
  }
}

解説: FleetWise が車両データを S3 に Parquet 形式で保存し、IoT Analytics がそのデータを取り込んで分析する。自社サーバーが不要になり、車両 10,000 台に増加しても AWS 側が自動スケールする。IoT Analytics の Notebook 機能で SageMaker との連携も容易になり、燃費予測・異常検知モデルを迅速に構築できる。


§8 まとめ + IoT二部作開始 + 49記事化告知 + 全軸クロスリンクナビ

8-1. 4本柱まとめ — IoT Events × Analytics × TwinMaker × FleetWise

本記事では AWS IoT Vol2 として、Vol1 (IoT Core / Greengrass / SiteWise / Device Defender) のデバイス接続層の上に構築される「イベント検知・分析・デジタルツイン・モビリティ」の4サービスを体系的に解説した。

IoT Events — Detector Model による複雑状態管理

IoT Events の核心は Detector Model だ。State machine を「正常 / 警告 / 異常」の3状態に収めることで可読性と保守性を担保できる。Multi-detector の key フィールドにより、10,000 台規模のデバイス群でもインフラ追加なしに独立した状態管理インスタンスを自動生成できる。Actions (SNS / Lambda / DynamoDB / Firehose) の冪等性設計は at-least-once 保証の IoT Events では必須の考慮事項だ。アンチパターンである「Lambda + DynamoDB による自前状態機械」を Detector Model に置き換えることで、競合状態リスクを排除しスケールを自動化できる。

IoT Analytics — フルマネージド分析パイプライン

IoT Analytics の Pipeline は Channel → Filter/Math/AddAttributes → Datastore の直列構成でメッセージ変換を自動化する。Lambda activity の多用はコスト爆発を招くため、標準 activity で処理できる変換は Lambda を使わないことが鉄則だ。Customer-managed S3 Datastore を選択することでデータの所有権を維持しつつ、Dataset の SQL クエリで柔軟な集計分析ができる。SageMaker Notebook との統合により、IoT データの機械学習パイプラインを短期間で構築できる。

IoT TwinMaker — 3D デジタルツインでリアルタイム可視化

IoT TwinMaker の Workspace / Entity / Component 階層はデジタルツインの設計図だ。Entity 階層 (Factory → Building → Floor → Machine) で物理空間を論理的にモデル化し、Component で各 Entity のリアルタイムデータを紐付ける。大規模 3D Scene は GLB ファイルをエリア単位に分割し draco 圧縮を適用することでブラウザのパフォーマンス問題を回避する。GenAI Connector (Bedrock Claude) との統合により、設備の異常原因を自然言語で問い合わせる次世代監視が実現できる。

IoT FleetWise — 車両データ収集を Trigger ベースで最適化

IoT FleetWise の Signal catalog は CAN/OBD-II シグナルの標準化辞書であり、Vehicle model と Campaign で車両データ収集を制御する。全シグナル / 常時収集は数TB/日のコスト爆発を招く。conditionBasedCollectionScheme で異常条件発生時のみ詳細収集し、通常時は 1Hz 以下の低頻度ベースライン収集に絞る 2-Campaign 構成が本番運用のベストプラクティスだ。Edge agent の persistencyPath を永続ストレージに設定することで、接続断中のデータバッファ消失を防ぐ。

§6+§7 の学習ポイント

詰まり7選では、Detector Model State 肥大化・Pipeline Lambda コスト爆発・TwinMaker Scene 巨大化・FleetWise 全データ収集・コスト設定ミス・Edge 接続断バッファ・データ品質欠損値の7パターンを対処法とともに整理した。演習5問では IoT Events / Analytics / TwinMaker / FleetWise の各サービスへの移行パターンを Terraform コードで実践した。

IoT Vol2 の4サービスはそれぞれ独立して使えるが、組み合わせることで真の価値を発揮する。IoT Core (Vol1) のデータを IoT Analytics で蓄積し、IoT Events で異常を検知し、IoT TwinMaker でリアルタイムに可視化し、IoT FleetWise で車両データを加える。この統合アーキテクチャが「AWS IoT 縦断設計」だ。Vol1 と Vol2 の両方を習得することで、デバイス接続から価値抽出までの全工程を自ら設計できるようになる。

IoT Vol2 本番導入チェックリスト

IoT Vol2 の4サービスを本番環境に導入する前に、以下のチェックリストで設計の抜け漏れを確認する。

カテゴリチェック項目確認ポイント
IoT EventsDetector Model State 数10 以下を推奨 / 20 超は要見直し
IoT EventsMulti-detector key 設定deviceId / vehicleId 等で分離
IoT EventsActions 冪等性DynamoDB 条件付き書き込み等で保証
IoT EventsInput ルーティングIoT Core Rules engine からの正しいルーティング確認
IoT AnalyticsLambda activity 使用箇所標準 activity で代替可能か検討
IoT AnalyticsDatastore 種別Customer-managed S3 推奨 (データ所有権)
IoT Analyticsデータ保持期間Datastore / Channel の retention policy 設定確認
IoT AnalyticsPipeline 欠損値処理Filter activity + Lambda で品質フラグ付与
IoT TwinMakerGLB ファイルサイズエリア単位分割 + draco 圧縮 (目標 50MB 以下/ファイル)
IoT TwinMakerEntity 階層深さ4 階層以内 (Factory/Building/Floor/Machine)
IoT TwinMakerGenAI Connector IAMBedrock への最小権限 IAM Role 確認
IoT TwinMakerScene LODLow/Medium/High の 3 段階 LOD 設計
IoT FleetWiseCampaign 収集方式conditionBased 推奨 / timeBased は低頻度のみ
IoT FleetWiseSignal 数Campaign 当たり必要最小限に絞る
IoT FleetWiseEdge agent persistencyPath永続ストレージ (/var/aws-iot-fleetwise) 設定確認
IoT FleetWiseバッファサイズ収集レート × 最大接続断時間 × 1.5 倍で設計
共通Terraform state 分離IoT Events / Analytics / TwinMaker / FleetWise を別 state で管理
共通IAM 最小権限サービス間の trust relationship と action 範囲を確認
共通コスト上限AWS Budgets で各サービスのコストアラーム設定

8-2. IoT 二部作開始 + Vol1↔Vol2 双方向ナビ

AWS 本番運用シリーズ 第19軸 IoT 縦深化 — IoT 二部作が始動

AWS 本番運用シリーズは「1軸 = 1テーマ複数 Vol」の縦深化構造で進化している。第19軸である IoT は Vol1 と Vol2 の二部作として設計された。

AWS IoT の5層モデル: IoT サービス群は下層から上層へ「Edge → Connect → Event → Analyze → Visualize」の5層構造で整理できる。Vol1 は Edge/Connect 層 (デバイス接続・データ収集) を、Vol2 は Event/Analyze/Visualize 層 (イベント検知・分析・デジタルツイン) を担当する。この5層モデルを理解することで、自社 IoT システムのどの層にギャップがあるかを素早く診断できる。

Vol1 (デバイス接続層) — IoT Core × Greengrass × SiteWise × Device Defender

IoT Core の MQTT ブローカー / Greengrass v2 のエッジコンピューティング / SiteWise のプロセスデータ管理 / Device Defender のデバイスセキュリティ監査という「デバイス接続・データ収集の下層」を担う。現場のセンサーを AWS に繋ぐすべての基盤技術がここにある。何万台のデバイスが接続してもスケールする MQTT ブローカー、オフライン対応のエッジランタイム、OPC-UA プロセスデータの標準化管理、デバイスセキュリティ監査まで、デバイス接続基盤のすべてが Vol1 に揃っている。

Vol2 (イベント分析層) — 本記事 — IoT Events × IoT Analytics × IoT TwinMaker × IoT FleetWise

Vol1 で収集したデータを「検知・分析・可視化・モビリティ」に活用する上層技術を担う。Detector Model による状態機械管理、Pipeline による分析基盤、デジタルツイン可視化、車両データ収集と、IoT の価値創出層がここにある。Vol1 のデータが入力で、Vol2 の分析・可視化が出力だ。両方を組み合わせることで、現場のセンサーからリアルタイム意思決定までの完全なパイプラインが完成する。

二部作の読み方: まず Vol1 でデバイス接続基盤を構築し、次に本 Vol2 でイベント検知と分析を追加する。既に IoT Core を運用中のチームは Vol2 の §2 (IoT Events) から読み始めることを推奨する。Vol1 で SiteWise を活用中であれば §4 (IoT TwinMaker) が直接つながる。車両テレマティクスに関わるチームは §5 (IoT FleetWise) から入ることも有効だ。

IoT 二部作で AWS IoT サービス群の全体像を俯瞰し、デバイス接続から分析・可視化・モビリティまでの一気通貫アーキテクチャを自らの手で設計できるエンジニアを目指してほしい。

Vol1 は以下から参照できる。


IoT Vol1 — IoT Core × Greengrass × SiteWise × Device Defender (デバイス接続層基盤)


8-3. AWS 本番運用シリーズ 49 記事化達成 + 全 20 軸全容

AWS 本番運用シリーズ 49 記事化達成 — 48 記事から 49 記事へ拡大

本 IoT Vol2 の公開により、AWS 本番運用シリーズは 49 記事に到達した。シリーズ開始から積み上げてきた各軸が、いよいよ第20軸まで埋まろうとしている。

AWS 本番運用シリーズ全 20 軸の現況は以下の通り。

| 軸 | テーマ | Vol 数 |
|—-|——–|——–|
| 第1軸 | Compute (EC2/Auto Scaling/ELB) | Vol1-2 |
| 第2軸 | Storage (S3/EBS/EFS/FSx) | Vol1-2 |
| 第3軸 | Database (RDS/Aurora/DynamoDB/ElastiCache) | Vol1-4 |
| 第4軸 | Network (VPC/Direct Connect/Transit Gateway) | Vol1-2 |
| 第5軸 | Security (IAM/WAF/Shield/KMS) | Vol1-3 |
| 第6軸 | Container (ECS/EKS/Fargate) | Vol1-3 |
| 第7軸 | Serverless (Lambda/API Gateway/EventBridge) | Vol1-2 |
| 第8軸 | DevOps CI/CD (CodePipeline/CodeBuild/CodeDeploy) | Vol1-4 |
| 第9軸 | Observability (CloudWatch/X-Ray/OpenTelemetry) | Vol1-2 |
| 第10軸 | Analytics (Glue/Athena/EMR/Redshift) | Vol1 |
| 第11軸 | AI/ML (SageMaker/Bedrock/Rekognition/Comprehend) | Vol1-3 |
| 第12軸 | Edge/CDN (CloudFront/Route53/Global Accelerator) | Vol1 |
| 第13軸 | Migration (DMS/MGN/DataSync) | Vol1 |
| 第14軸 | Hybrid (Outposts/ECS Anywhere/Hybrid管理) | Vol1 |
| 第15軸 | IAM Advanced (SCP/Permission Boundary/ABAC) | Vol1 |
| 第16軸 | Step Functions (SF Distributed Map/Express/SDK) | Vol1-3 |
| 第17軸 | DevOps Platform (CDK Pipelines/GitOps/Karpenter) | Vol1-3 |
| 第18軸 | Game/Media (AppStream/MediaConvert/MediaLive/GameLift) | Vol1 |
| 第19軸 | IoT (Core/Greengrass/SiteWise/Events/Analytics/TwinMaker/FleetWise) | Vol1-2 |
| 第20軸 | (次期公開予定) | — |

全 20 軸・49 記事を体系的に読み進めることで、AWS 本番運用のすべての主要サービス領域を網羅できる。各記事はシリーズとしての一貫性を保ちながら独立して読むことができ、担当サービス領域の深掘りにも全体俯瞰にも使える。

今後も各軸の縦深化 Vol を追加していく。次の第20軸公開も期待してほしい。

49 記事の読み方のすすめ: シリーズ全体を通読する必要はない。自分が担当するサービス領域の軸を選んで深掘りし、隣接軸 (例: IoT × Analytics、Container × DevOps) を読んでクロスサービスの連携ポイントを押さえる読み方が最も効率的だ。本シリーズの各記事は §2〜§5 の本番運用パターン解説 + §6 詰まり7選 + §7 演習5問 + §8 まとめの構成で統一されており、知りたい切り口から読み始められる。

AWS 本番運用の49記事があなたの現場設計の羅針盤となることを願っている。

シリーズ記事は定期的に最新 AWS サービス情報にアップデートされる。新しい Vol の公開通知を受け取りたい方はブックマークしておくことを推奨する。第20軸の公開時にはまた新たな縦深化が始まる。

49 記事という節目を達成できたのは、AWS 本番運用の課題に向き合い続けるエンジニアコミュニティがあってこそだ。シリーズの成長とともにあなたの設計力が高まることを願っている。


8-4. IoT 二部作マップ + 全軸接続図 (Mermaid02)

graph LR
  IOT2[IoT Vol2 第19軸縦深化] --> IOT1[IoT Vol1 IoT Core/Greengrass]
  IOT2 --> GM[Game/Media Vol1 第20軸]
  IOT2 --> DB[Database Vol1-4]
  IOT2 --> CON[Container Vol1-3]
  IOT2 --> DEV[DevOps Vol1-3]
  IOT2 --> OBS[Observability Vol1-2]
  IOT2 --> AI[AI/ML Vol1-3]
  IOT2 --> ANL[Analytics Vol1]
  IOT2 --> SRV[Serverless Vol1-2]
  IOT2 --> SEC[Security Vol1-3]
  IOT1 --> IOT2
  IOT2 --> STG[Storage Vol1-2]
  IOT2 --> SF[Step Functions Vol1-3]

IoT Vol2 は第19軸の縦深化巻として、Vol1 (デバイス接続層) と双方向に連携しながら、他の全軸とも接続している。IoT Analytics は Analytics / AI/ML / Storage と連携し、IoT TwinMaker は AI/ML (GenAI Connector) / Observability と接続する。IoT FleetWise は Container (Edge コンテナ) / Serverless (Lambda トリガー) / DevOps (OTA 配信パイプライン) と組み合わせることで本番グレードのモビリティ基盤が完成する。

全軸接続図が示す通り、IoT は孤立したサービス群ではない。他の全軸のサービスと深く連携することで、スマートファクトリー・コネクテッドカー・インフラ監視などのユースケースを実現する総合的なプラットフォームだ。IoT Vol1 と Vol2 の二部作を組み合わせることで、エッジのデバイスから AWS クラウドの AI 分析基盤までを一本の線で繋いだシステムを設計できる。本シリーズを通じて、AWS IoT の設計力を段階的に高めていってほしい。


8-5. 関連記事 ep-btn + 次のステップ

本記事で構築した IoT Vol2 の知識を活かすための関連記事を以下に示す。IoT Analytics の分析基盤をさらに深めたい方は Analytics Vol1 へ、TwinMaker GenAI Connector を活用したい方は AI/ML Vol3 へ進むことを推奨する。


IoT Vol1 — IoT Core × Greengrass × SiteWise × Device Defender


Game/Media Vol1 — AppStream 2.0 × MediaConvert × MediaLive × GameLift


Database Vol4 — Aurora DSQL × Limitless × DynamoDB Strong

IoT Vol2 で学んだ4サービス (Events/Analytics/TwinMaker/FleetWise) は、それ単体では機能しない。Vol1 で構築した IoT Core × Greengrass の接続基盤があって初めて真の価値を発揮する。

デバイス接続 (Vol1) → イベント検知 (IoT Events) → データ分析 (IoT Analytics) → デジタルツイン可視化 (IoT TwinMaker) → 車両データ収集 (IoT FleetWise) — この一連の流れが AWS IoT の「縦断アーキテクチャ」だ。本記事がその全体像を理解し、本番設計力を高める一助となれば幸いだ。

次に取り組むべきステップ

本記事を読み終えた SRE / IoT エンジニアへ、次のアクションを提案する。

  • IoT Events をまず試す: IoT Core の Rules engine で Lambda を使って状態管理しているワークロードがあれば、Detector Model への移行候補だ。既存 Lambda の状態数を棚卸しし、3 状態に整理できるか検証するところから始める。
  • IoT Analytics Pipeline を評価する: 自前 Lambda ETL のコストを CloudWatch Logs Insights で計測し、IoT Analytics の Pipeline に置き換えたときのコスト削減を試算する。Channel + Pipeline + Datastore の Terraform テンプレートは §3 のコードをそのまま流用できる。
  • TwinMaker の Grafana パネルを試す: AWS コンソールの TwinMaker で無料の Workspace を作成し、サンプル Entity を 1 件追加して Grafana パネルで表示するまでを 1 時間で体験できる。まず動くものを見てから設計を深めることを推奨する。
  • FleetWise の Signal catalog 設計を先行する: Vehicle model と Campaign は Signal catalog が先にないと設計できない。CAN/OBD-II の標準シグナル定義を調査し、自社車両に必要な Signal 一覧を事前に整理してから Terraform に進む。

AWS 本番運用シリーズは今後も各軸の縦深化 Vol を追加していく。第20軸の公開もぜひ期待してほしい。次の記事もぜひ購読してほしい。

本記事を最後まで読んでくれたエンジニアへ: IoT Vol2 で解説した技術は、現場の課題を解決するためにある。Detector Model で工場の異常を早期検知し、IoT Analytics でデータドリブンな意思決定を実現し、TwinMaker でリモート監視を高度化し、FleetWise で車両データをコスト効率よく収集する — これらはすべて実装可能だ。まず一つを選んで動かしてみてほしい。

IoT Vol1 と Vol2 の二部作を完読したエンジニアは、AWS IoT の全体設計図を頭の中に持っている。この知識を活かして、現場のデバイス接続から分析・可視化まで一気通貫のシステムを設計してほしい。


IoT Vol2 で得た知識を本番環境へ — 実装の出発点

本記事を読み終えたエンジニアへ伝えたいことがある。IoT Vol2 で解説した4サービスは、最初から全部を同時に導入する必要はない。スモールスタートで始め、価値を確認しながら段階的に拡大することを推奨する。

推奨導入順序:

① IoT Events から始める — 既存の Lambda ベース状態管理を Detector Model に移行する。State 数 3〜5 の小さなモデルで始め、動作確認してから拡張する。

② IoT Analytics を追加する — IoT Core の Rules engine から IoT Analytics Channel にルーティングするだけで分析基盤が立ち上がる。既存の Lambda ETL コストを計測し、削減効果を確認してから全量移行する。

③ IoT TwinMaker でデジタルツインを構築する — まず 1 エリア分の簡易 Entity を作成し、Grafana パネルで表示するところから始める。3D Scene は最後に追加する。

④ IoT FleetWise は Signal catalog の設計が先決 — 車両 CAN/OBD-II の標準シグナルを整理し、Vehicle model を設計してから Campaign に進む。最初は 1 車両 1 Campaign で動作確認する。

本記事が AWS IoT 本番運用の第一歩を踏み出す助けになれば幸いだ。疑問点や詰まりポイントがあれば、本シリーズの各記事の §6 詰まりポイント7選を参照してほしい。

本番化に向けた最終確認ポイント:

・ IAM Role は各サービス (IoT Events / Analytics / TwinMaker / FleetWise) ごとに最小権限で個別作成したか

・ Terraform state はサービスごとに分離し、他チームの変更で意図せず破棄されない構成になっているか

・ AWS Budgets でコストアラームを設定し、予算超過を早期検知できる体制を整えたか

・ CloudWatch ダッシュボードで IoT Events のインスタンス数、IoT Analytics のメッセージ処理量、FleetWise のデータ転送量を監視しているか

・ Edge agent の永続化バッファ設定と接続断テストを本番投入前に実施したか

これらを確認してから本番投入に進んでほしい。