Amazon Web Services ブログ

AWS IoT Core と Amazon SQS を使用してメッセージを複数のアカウントにルーティングする

はじめに

このブログでは、1つ以上の取り込み用アカウントの AWS IoT Core メッセージをデータ用アカウントの Amazon Simple Queue Service (Amazon SQS) にルーティングする方法について説明します。IoT テレメトリをあるアカウントに取り込み、それを別のアカウントに送信してさらに処理する必要があるというのは一般的なパターンです。例えば、ある組織が複数のアカウントでデバイスをホストしていて、取り込まれるデータが機密データおよび運用データとして分類されている場合です。機密データは元の取り込み用アカウントに保管する必要がありますが、運用データは運用チームが監視する別のアカウントに中継する必要があります。
この記事では、クロスアカウントアクセス用の AWS IoT ルールを設定して MQTT トピックデータセットを Amazon SQS にルーティングする方法を学びます。AWS IoT のルールにより、デバイスが AWS サービスとやり取りできるようになります。ルールを使用して、デバイスからのデータの拡張やフィルタリング、データベースへのデータの書き込み、Amazon SQS へのメッセージの送信などのタスクをサポートできます。実行できるタスクの全リストについては、AWS IoT Core デベロッパーガイドAWS IoT のルールセクションを参照してください。

ソリューション概要

このソリューションでは、まずデータ用アカウントに Amazon SQS キューを作成し、取り込み用アカウントにデータ送信を許可するアクセス権限を付与します。次に、AWS IoT ルールを作成し、そのルールにメッセージを送信してテストします。

  1. データ用アカウントに iot-data という名前の Amazon SQS キューを作成し、取り込み用アカウントからこのキューにパブリッシュできるようにします。
  2. 取り込み用アカウントでは:
    a. データ用アカウントで Amazon SQS へのデータ送信を許可するポリシーをもつ、AWS Identity and Access Management (IAM) ロールを作成します。
    b. SQS キューへのデータ送信時に発生したエラーの再送信を許可するポリシーをもつ IAM ロールを作成します。
  3. 取り込み用アカウントに IoT ルールを作成して、data/private というトピックからのメッセージを評価し、データ用アカウントの SQS キューに送信します。ルールには、トラブルシューティングのためにメッセージを error/rules トピックに再送信するエラー処理があります。
  4. メッセージを MQTT トピック data/private に送信し、メッセージがデータ用アカウントの SQS キューに表示されていることを確認します。

ソリューション図

Solution architecture diagram

ソリューション構築手順

前提条件

  1. 2つの AWS アカウントがあること
  2. 両方のアカウントの管理者権限があること
  3. AWS コマンドラインインターフェイス (AWS CLI)が使えること

データ用アカウントに SQS キューを作成する

  1. 次の内容を含む queue_attributes.json という名前のファイルを作成します。
    { "MessageRetentionPeriod": "259200" }
  2. AWS CLI の設定をデータ用アカウントに設定し、create-queue.json ファイルを使用して、iot-data という名前の SQS キューを作成します。
    aws sqs create-queue \
         --queue-name iot-data \   
         --attributes file://queue_attributes.json
  3. 次のセクションで必要になるので、出力の QueueURL を記録します。
  4. 取り込み用アカウントが Amazon SQS キューリソースにアクセスできるようにアクセス権限を付与するには、add-permission コマンドを実行します。AWS アカウント ID は適宜変更してください。
    aws sqs add-permission \
         --queue-url https://sqs.<データ用アカウントのリージョン>.amazonaws.com/<データ用アカウントID>/iot-data \
         --label IoTSendMessage \
         --aws-account-ids <取り込み用アカウントID> \
         --actions SendMessage

SQS へのクロスアカウント送信用の AWS Identity and Access Management (IAM) ロールとポリシーを作成する

取り込み用アカウントから SQS キューへ送信するには、まずそのアクションを許可する必要があります。

  1. 次の内容を含む iot_policy.json という名前のファイルを作成します。
    {
        "Version": "2012-10-17",
        "Statement": [
            {
    			"Effect": "Allow",
    			"Principal": {
    				"Service": "iot.amazonaws.com"
    			},
    			"Action": "sts:AssumeRole"
    		}
    	]
    }
  2. AWS CLI の設定を取り込み用アカウントに設定した状態で、次のコマンドを実行して iot-cross-sqs-allow というロールを作成し、信頼ポリシーをアタッチして IoT とのやり取りを許可します。
    aws iam create-role \ 
         --role-name iot-cross-sqs-allow \ 
         --assume-role-policy-document file://iot_policy.json
  3. 出力を確認し、正しいことを確認します。
    {
        "Role": {
            "Path": "/",
            "RoleName": "iot-cross-sqs-allow",
            "RoleId": "XXXXXXXXXXXXXXXXXXXXX",
            "Arn": "arn:aws:iam::XXXXXXXXXXXX:role/iot-cross-sqs-allow",
            "CreateDate": "2022-09-07T05:05:58+00:00",
            "AssumeRolePolicyDocument": {
                "Version": "2012-10-17",
                "Statement": [
    				{
    					"Effect": "Allow",
    					"Principal": {
    						"Service": "iot.amazonaws.com"
    					},
    					"Action": "sts:AssumeRole"
    				}
    			]
    		}
        }
    }
  4. 次の内容を含む allow_send_cross_sqs.json という名前のファイルを作成します。リソース ARN については、データ用アカウントのリージョンとアカウント ID を変更してください。
    {
        "Version": "2012-10-17",
        "Statement": [
    		{
    			"Effect": "Allow",
    			"Action": "sqs:SendMessage",
    			"Resource": "arn:aws:sqs:<データ用アカウントのリージョン>:<データ用アカウントID>:iot-data"
    		}
    	]
    }
  5. 次のコマンドを使用して、このカスタムインラインポリシーを前のステップで作成したロールに追加します。
    aws iam put-role-policy \
         --role-name iot-cross-sqs-allow \
         --policy-name new-iot-cross-sqs-policy \
         --policy-document file://allow_send_cross_sqs.json

エラーの再送信を許可する AWS IAM ロールとポリシーを作成する

AWS IoT ルールを使用してメッセージを再送信する場合、このアクションを許可する権限を適切に設定する必要があります。

  1. AWS CLI の設定を取り込み用アカウント用に設定し、以前に作成した同じファイルを使用して、iot-republish という新しいロールを作成します。
    aws iam create-role \
         --role-name iot-republish \
         --assume-role-policy-document file://iot_policy.json
    
  2. 出力を確認し、正しいことを確認します。
    {
        "Role": {
            "Path": "/",
            "RoleName": "iot-republish",
            "RoleId": "XXXXXXXXXXXXXXXXXXXXX",
            "Arn": "arn:aws:iam::XXXXXXXXXXXX:role/iot-republish",
            "CreateDate": "2022-09-07T05:24:36+00:00",
            "AssumeRolePolicyDocument": {
                "Version": "2012-10-17",
                "Statement": [
    				{
    					"Effect": "Allow",
    					"Principal": {
    						"Service": "iot.amazonaws.com"
    					},
    					"Action": "sts:AssumeRole"
    				}
    			]
    		}
        }
    }
  3. 次に、以下の内容を含む allow_republish.json という名前のファイルを作成します。このポリシーでは、errors で始まるトピック名に送信を制限していることに注意してください。必ず取り込み用アカウントのリージョンとアカウント ID を変更して下さい。
    {
        "Version": "2012-10-17",
        "Statement": {
            "Effect": "Allow",
            "Action": "iot:Publish",
            "Resource": "arn:aws:iot:<取り込み用アカウントのリージョン>:<取り込み用アカウントID>:errors/*"
        }
    }
    
  4. インラインポリシーとして前の手順で作成したポリシーを iot-republish ロールに追加します。
    aws iam put-role-policy \
         --role-name iot-republish \
         --policy-name iot-republish \
         --policy-document file://allow_republish.json
    

取り込み用アカウントでメッセージを評価し、エラーを再送信するIoT ルールを作成する

次に、メッセージを SQS キューにルーティングし、エラーが発生したメッセージを error/rules という名前のトピックに再送信する IoT ルールを作成します。

  1. 以下の内容を含む ingestion_rule.json という名前のファイルを作成します。queueURLroleArn の値は、必ず前のステップで受け取った値に更新してください。
    {
    "sql": "SELECT * FROM 'data/private'" ,
    "description": "Cross-account publishing of messages to SQS.",
    "ruleDisabled": false,
    "awsIotSqlVersion": "2016-03-23",
    "actions": [{
    	"sqs": {
    		"roleArn": "<iot-cross-sqs-allow ロールのARN>",
    		"queueUrl": "https://sqs.<データ用アカウントのリージョン>.amazonaws.com/<データ用アカウントID>/iot-data",
    		"useBase64": true
    	}
    }], 
    "errorAction": {
        "republish": {
          "roleArn": "<iot-republish ロールのARN>",
          "topic": "error/rules",
          "qos": 0
        }
      }
    }
  2. AWS CLI の設定を取り込み用アカウントに設定したら、データ用アカウントの SQS にメッセージを送信するための IoT ルールを作成します。
    aws iot create-topic-rule \
         --rule-name "cross_account_sqs_publish" \
         --topic-rule-payload file://ingestion_rule.json

メッセージを送信し、データ用アカウントの SQS キューに表示されていることを確認します。

このソリューションをテストするために、メッセージを AWS IoT Core に送信し、データ用アカウントの SQS キューに正常に届くかどうかを確認します。

  1. 取り込み用アカウントから、AWS IoT MQTT クライアントを使用して、data/private および error/rules をサブスクライブします。
  2. 引き続き AWS MQTT IoT クライアントで、次のサンプルペイロードを含むメッセージを data/private トピックに送信します。
    {
        "message": "Hello, world",
        "clientType": "MQTT client"
    }
    
  3. AWS CLI の設定をデータ用アカウントに設定し、次のコマンドを実行して、SQS キューからメッセージを取得し、確認します。
    aws sqs receive-message \
        --queue-url https://sqs.<データ用アカウントのリージョン>.amazonaws.com/<データ用アカウントID>/iot-data
    

    出力の Body パラメータは Base64 でエンコードされている場合があります。その場合は、送信されたメッセージの内容を確認するには、デコードする必要があります。

  4. SQS キューにメッセージが届かない場合は、error/rules トピックのサブスクリプションで、取り込み用アカウントの AWS MQTT IoT クライアントから配信されたエラーメッセージを確認してください。

クリーンアップ

使用しなくなったリソースはクリーンアップすることをお勧めします。AWS リソースをクリーンアップすることで、アカウントに追加料金が発生するのを防ぐことができます。

  1. SQS キューを削除します。
    aws sqs delete queue \
       --queue-url https://sqs.<データ用アカウントのリージョン>.amazonaws.com/<データ用アカウントID>/iot-data
  2. iot-cross-sqs-all の IAM ロールを削除します。
    aws iam delete-role-policy \
         --role-name iot-cross-sqs-all \
         --policy-name iot-cross-sqs-all
    
    aws iam delete-role --role-name iot-cross-sqs-all
    
  3. iot-republish の IAM ロールを削除します。
    aws iam delete-role-policy \
         --role-name iot-republish \
         --policy-name iot-republish
    
    aws iam delete-role --role-name iot-republish
    
  4. cross_account_sqs_publish のトピックルールを削除します。
    aws iot delete-topic-rule \
         --rule-name cross_account_sqs_publish

まとめ

このブログでは、AWS IoT メッセージを取り込み用アカウントからデータ用アカウントの Amazon SQS にルーティングする方法について説明しました。機密データと運用データを別々のアカウントで分離できる1つのパターンを示しました。他の AWS サービスとのクロスアカウントメッセージルーティングの実行方法に関するその他の例については、AWS デベロッパーガイドの関連ドキュメントをご覧ください。

著者

Steve Krems は、アマゾンウェブサービス (AWS) の IoT 担当スペシャリストソリューションアーキテクトです。Steveは、この役職に就く前に半導体業界で18年間、クラウドへの移行とモダナイゼーションを中心としたIT管理業務に就いていました。
Kai-Matthias Dickmanは、アマゾンウェブサービス (AWS) の IoT 担当スペシャリストソリューションアーキテクトです。大企業の開発者や意思決定者と協力して AWS IoT サービスの運用を促進することを楽しんでいます。Kai は IoT とクラウドに関する深い知識を持っており、スタートアップ企業から大企業に至るまで、世界中のお客様が AWS エコシステムで IoT ソリューションを構築できるように支援しています。

この記事は Route messages across multiple accounts with AWS IoT Core and Amazon SQS の日本語訳です。IoT Consultant の正村 雄介が翻訳しました。