[AWS IoT Core] ルールSQLに追加された get_registry_data() 関数を試してみました

[AWS IoT Core] ルールSQLに追加された get_registry_data() 関数を試してみました

2025.11.29

1. はじめに

製造ビジネステクノロジー部の平内(SIN)です。

2025年11月、AWS IoT Coreに新しい機能が追加されました。IoTルールSQL内で使用できるget_registry_data()関数です。この関数を使用することで、デバイスから送信されたメッセージを処理する際に、Thing registryに登録されているデバイスの属性情報やグループ情報を動的に取得できるようになりました。

本記事は、この新機能を試してみた結果や、実装時に気づいた点などについて紹介させていただきます。

2. サンプル実装の説明

検証のために、サンプルを作成してみました。

https://github.com/furuya02/iot-get-registry-data-sample

(1) サンプルの構成

サンプルでは、以下のリソースをAWS CDKで構築しています。

002

  • IoT Thing: test-device-001(デバイスの属性としてdeviceTypelocationfirmwareVersionを設定)
    003

  • IoT Thing Group: production-devices(グループの属性としてenvironmentpriorityを設定)

004

  • IAM Role: GetRegistryDataRole(DescribeThing/ListThingGroupsForThing API用の権限を持つ統合ロール)
  • IoT Rule 1: DescribeThingRule(DescribeThing APIでThing情報を取得)
  • IoT Rule 2: ListThingGroupsForThingRule(ListThingGroupsForThing APIでThingグループ一覧を取得)
  • Lambda関数: GetRegistryDataFunction(両方のルールから呼び出される統合関数)

(2) デプロイ手順

サンプルのデプロイ手順です。

# 依存関係のインストール
cd cdk
pnpm install

# デプロイ
cdk deploy

デプロイ後、Thingtest-device-001をThingグループproduction-devicesに追加します。

aws iot add-thing-to-thing-group \
  --thing-name test-device-001 \
  --thing-group-name production-devices

次に、デバイスの証明書を作成し、Thingにアタッチします。

# 証明書の作成
aws iot create-keys-and-certificate \
  --set-as-active \
  --certificate-pem-outfile client/certs/device.cert.pem \
  --private-key-outfile client/certs/device.private.key \
  --output json > certificate-output.json

# 証明書ARNを取得
CERT_ARN=$(cat certificate-output.json | jq -r '.certificateArn')

# ルートCA証明書のダウンロード
curl -o client/certs/AmazonRootCA1.pem \
  https://www.amazontrust.com/repository/AmazonRootCA1.pem

# 証明書をThingとポリシーにアタッチ
aws iot attach-thing-principal \
  --thing-name test-device-001 \
  --principal $CERT_ARN

aws iot attach-policy \
  --policy-name test-device-001-policy \
  --target $CERT_ARN

準備はここまでです。以下のコマンドで、Pythonクライアントからメッセージを送信できます。

cd client
pip install -r requirements.txt

python publish_message.py \
  --endpoint <IoT_ENDPOINT> \
  --thing-name test-device-001 \
  --count 5 \
  --interval 2

009

3. 取得できるデータ

get_registry_data()関数では、2つのAPIに相当する情報を取得できます。

(1) DescribeThing

Thing情報を取得するには、以下のようにIoT Ruleを定義します。

SELECT
  *,
  clientId,
  timestamp,
  'DESCRIBE_THING' as rule_type,
  get_registry_data("DescribeThing", 'test-device-001', 'arn:aws:iam::xxx:role/GetRegistryDataRole') as deviceInfo
FROM
  'device/+/telemetry'

このルールで取得できる情報は以下の通りです。

005

Thing名、ARN、属性、バージョンなどの情報が取得できます。デバイスの属性情報をルール内で利用することで、属性に基づいたメッセージのルーティングやフィルタリングが可能になります。

(2) ListThingGroupsForThing

Thingが所属するグループ一覧を取得するには、以下のようにIoT Ruleを定義します。

SELECT
  *,
  clientId,
  timestamp,
  'LIST_THING_GROUPS' as rule_type,
  get_registry_data("ListThingGroupsForThing", 'test-device-001', 'arn:aws:iam::xxx:role/GetRegistryDataRole') as deviceGroups
FROM
  'device/+/telemetry'

このルールで取得できる情報は以下の通りです。

006

デバイスが所属するグループ名の配列が取得できます。グループ情報を使用することで、"production"グループと"test"グループでメッセージの送信先を変えるといった処理が可能になります。

4. 実装例

実際のサンプル実装から、一部を紹介させてください。

(1) CDKスタック定義

iot-registry-data-sample-stack.ts:73-90

// get_registry_data用の統合IAMロール
const registryDataRole = new iam.Role(this, 'RegistryDataRole', {
  roleName: 'GetRegistryDataRole',
  assumedBy: new iam.ServicePrincipal('iot.amazonaws.com'),
  description: 'Unified role for get_registry_data() function to access Thing registry',
});

// get_registry_data()で必要な権限を付与
registryDataRole.addToPolicy(
  new iam.PolicyStatement({
    effect: iam.Effect.ALLOW,
    actions: [
      'iot:DescribeThing',
      'iot:ListThingGroupsForThing',
    ],
    resources: ['*'],
  })
);

IAMロールには、iot:DescribeThingiot:ListThingGroupsForThingの権限が必要です。

(2) IoT Rule定義

iot-registry-data-sample-stack.ts:115-140

// IoT Rule 1: DescribeThing API用
const describeThingRule = new iot.CfnTopicRule(this, 'DescribeThingRule', {
  ruleName: 'DescribeThingRule',
  topicRulePayload: {
    sql: `
      SELECT
        *,
        clientId,
        timestamp,
        'DESCRIBE_THING' as rule_type,
        get_registry_data("DescribeThing", '${thingName}', '${registryDataRole.roleArn}') as deviceInfo
      FROM
        'device/+/telemetry'
    `,
    description: 'Test get_registry_data("DescribeThing") API',
    actions: [
      {
        lambda: {
          functionArn: getRegistryDataFunction.functionArn,
        },
      },
    ],
    ruleDisabled: false,
    awsIotSqlVersion: '2016-03-23',
  },
});

ルールSQLの中でget_registry_data()関数を呼び出し、結果をdeviceInfoという名前でLambda関数に渡しています。

(3) Lambda関数

log-event.py:8-18

def handler(event: dict, context: dict) -> dict:
    """
    IoT Ruleから送信されたイベントをCloudWatch Logsに出力するLambda関数

    get_registry_data()で取得したデバイス情報を含むイベント全体をログに記録します。
    IoT RuleのSQL内のrule_typeフィールドでどちらのルールから呼び出されたか識別します。
    """
    # IoT RuleのSQLで設定されたrule_typeを取得(環境変数は使用しない)
    rule_type = event.get("rule_type", "UNKNOWN")
    logger.info(f"========== {rule_type} ==========")
    logger.info(json.dumps(event, indent=2, ensure_ascii=False))

Lambda関数では、IoT Ruleから渡されたイベント(deviceInfodeviceGroupsを含む)を受け取り、CloudWatch Logsに出力しています。

5. 実装上の注意

実装してみて、注意が必要だ感じた事項です。

(1) Thing名の指定方法

get_registry_data()の第2パラメータには、実際のThing名を指定する必要があります。

-- ❌ clientIdはMQTT接続のクライアントIDであり、Thing名とは限らない
get_registry_data("DescribeThing", clientId, roleArn)

-- ✅ Thing名を明示的に指定するか、トピックから抽出
get_registry_data("DescribeThing", 'test-device-001', roleArn)
-- または
get_registry_data("DescribeThing", topic(2), roleArn)  -- device/THING_NAME/telemetry の場合

MQTTのclientIdは任意の文字列を指定できるため、Thing名と一致するとは限りません。Thing名を取得したい場合は、トピック名から抽出するか、明示的に指定する必要があります。

(2) 第3パラメータ(roleArn)

AWSドキュメントではget_registry_data(apiName, thingName[, roleArn])のように角括弧で記載されていますが、実際にはroleArnは必須パラメータのようでした。

-- ❌ エラー: "Get registry data requires its last parameter to be roleArn"
get_registry_data("DescribeThing", thingName)

-- ✅ 正常動作
get_registry_data("DescribeThing", thingName, 'arn:aws:iam::xxx:role/RoleName')

第3パラメータがないと、以下のようなエラーで、ルールが保存できませんでした。

007

(3) IAMロールの必要権限

指定するIAMロールには、以下のような権限が必要です。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": [
        "iot:DescribeThing",
        "iot:ListThingGroupsForThing"
      ],
      "Resource": "*",
      "Effect": "Allow"
    }
  ]
}

権限が付与されていない場合、IoT Ruleの実行時にエラーが発生し、Lambda関数などの後続アクションが実行されません。

001

[logLevel]: ERROR
[eventType]: RuleExecution
[reason]: ExternFunctionException
[ruleName]: DescribeThingRule
[details]: Function 'GetRegistryData' failed to execute for rule 'DescribeThingRule'. Could not retrieve registry data. Received error message User: arn:aws:sts::xxxxxxxxxxxx:assumed-role/GetRegistryDataRole/jxDJ4011 is not authorized to perform: iot:DescribeThing on resource: arn:aws:iot:ap-northeast-1:xxxxxxxxxxxx:thing/test-device-001 because no identity-based policy allows the iot:DescribeThing action (Service: Iot; Status Code: 403; Error Code: AccessDeniedException; Request ID: d2e5bfaf-425d-4f3c-a2e1-864b0ded73e0)

(4) 1ルールで1回の呼び出しの制限

1つのIoT Ruleでget_registry_data()1回のみ呼び出し可能です。

-- ❌ エラー: "Rule cannot contain more than 1 get_registry_data function calls"
SELECT
  get_registry_data("DescribeThing", thingName, roleArn) as deviceInfo,
  get_registry_data("ListThingGroupsForThing", thingName, roleArn) as deviceGroups
FROM 'device/+/telemetry'

008

6. 活用アイデア

get_registry_data()関数を活用することで、色々高度なIoTシステムを構築できそうです。

(1) デバイス管理・制御

デバイスタイプ別のルーティング

デバイスのdeviceType属性(センサー/アクチュエーター/ゲートウェイ等)を取得し、タイプごとに異なる処理パイプラインに振り分けることで、例えば、センサーデータは分析用、アクチュエーターは制御用などとして、効率的なシステム構築が可能になりそうです。

ファームウェアバージョン管理

デバイスのfirmwareVersion属性をチェックし、古いバージョンのデバイスを検出して自動的にOTAアップデート指示を送信できます。セキュリティパッチ未適用のデバイスを特定し、迅速な対応が可能になります。

(2) マルチテナント・組織管理

所有者情報による自動振り分け

デバイスのownerIddepartmentId属性を取得し、メッセージに組織情報を付与することで、部門ごとのダッシュボードに自動的に振り分けることができます。マルチテナント環境では、各テナントのデータを自動的に分離できます。

SLA別の優先度制御

デバイスが属するThingグループからsla属性(premium/standard)を取得し、プレミアムデバイスは即時処理、標準デバイスはバッチ処理といった、サービスレベルに応じたQoS制御が可能になります。

(3) 運用最適化

動的閾値によるアラート

デバイスのalertThreshold属性を取得し、デバイスごとに異なる閾値でアラート判定を行うことができます。デバイスの設置環境に応じた柔軟な閾値管理が実現します。

メンテナンスモードのフィルタリング

デバイスのmaintenanceMode属性を確認し、メンテナンス中のデバイスからのアラートを抑制することで、計画的メンテナンス中の誤アラートを防止できます。

(4) コンプライアンス・セキュリティ

地域別データ保存先の振り分け

デバイスのregion属性を取得し、地域ごとに適切なリージョンのDynamoDBテーブルやS3バケットに保存することで、データ主権要件に対応できます。

セキュリティレベル別の処理

デバイスのsecurityLevel属性(high/medium/low)を取得し、高セキュリティデバイスのデータのみ追加暗号化して保存するなど、機密性に応じた処理が可能になります。

7. まとめ

今回は、AWS IoT Coreの新機能get_registry_data()関数を試してみました。
デバイスのレジストリを動的に利用可能になったことで、かなり柔軟なシステム設計が可能になったのではないでしょうか。

サンプルコードはGitHubで公開しました。
https://github.com/furuya02/iot-get-registry-data-sample

この記事をシェアする

FacebookHatena blogX

関連記事