0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【AWS IoT Core】MQTTでメッセージをS3に送ってみる (CloudFormation)

Last updated at Posted at 2025-05-27

はじめに

業務の方でAWS IoT Coreを触ることになりそうなので、キャッチアップとして入門レベルの実装をしてみたいと思います。

今回は、下記のような構成を作ります。AWSリソースは、CloudFormationで作成します。

  1. MQTTX(ツール)からAWS IoT CoreにMQTTでメッセージを送信
  2. 受信したメッセージをAmazon S3に保存

概要

AWSにおけるIoTサービス達

AWSでは、下記のIoTサービスが提供されており、今回はそのうちの「AWS IoT Core」に入門してみます。

デバイスソフトウェア

サービス名 概要
FreeRTOS 小型マイクロコントローラー向けのリアルタイムOS
AWS IoT Greengrass エッジデバイス上でのローカル処理と機械学習実行
AWS Kinesis Video Streams ビデオストリームの収集・処理・保存・分析
AWS IoT ExpressLink 組み込み向け接続モジュールとソフトウェア

接続

サービス名 概要
AWS IoT Core IoTデバイスをクラウドに接続するマネージドサービス

コントロール

サービス名 概要
AWS IoT Device Defender IoTデバイスのセキュリティ監視・監査
AWS IoT Device Management 大規模IoTデバイスの一括管理
AWS IoT FleetWise 車両データ収集・変換・転送

分析サービス

サービス名 概要
AWS IoT SiteWise 産業機器データの収集・整理・分析
AWS IoT TwinMaker デジタルツイン作成サービス
AWS IoT Events
(2025年12月15日終了予定)
イベント検出とアクション実行
AWS IoT Analytics
(2025年12月15日終了予定)
IoTデータの高度な分析

サービス終了のお知らせ
下記、AWS IoT Events と AWS IoT Analyticsについて、サービス終了のお知らせがAWSから出ているので注意が必要です。

  • AWS IoT Eventsは、2026年5月20日に終了
  • AWS IoT Analyticsは、2025年12月15日に終了

https://aws.amazon.com/about-aws/whats-new/2025/05/aws-service-changes/

AWS IoT Coreとは

AWS IoT Coreは、IoTデバイスをAWSクラウドに安全に接続&通信するためのフルマネージドサービスです。IoTデバイスから送信されたデータは、AWS IoT Coreを通って、他のAWSサービスへ転送したり、処理したりすることができます。

構成要素

IoT Core 構成.png

構成要素 説明
DveiceGateway デバイスからメッセージを受け取るゲートウェイ
下記の通信プロトコルに対応
• HTTPS
• MQTT
• MQTT over WebSocket
Topic メッセージの宛先を示す階層構造の文字列
デバイスからはTopicを宛先としてメッセージを送ることが出来る
RuleEngine 受信したメッセージを処理するためのSQLベースのルール
フィルタリング、日時を付与するなどメッセージを加工できる
Action ルールに基づいて実行される
他のAWSサービスなどにメッセージを送ることが出来る
Policy デバイスがアクセスできるリソースとアクションを定義できる
Certificate デバイス認証のためのX.509証明書の発行・管理ができる
IoT Shadow デバイスの仮想的な状態をAWS上で管理できる

MQTTとは
MQTTは、「Message Queuing Telemetry Transport」の略称で、IoTの接続に使用される通信プロトコルです。下記のようにPub/Sub形式で通信が可能です。

参考:https://dev.classmethod.jp/articles/mqtt_illustrations/

やってみる

今回は、下記を構築し、S3にメッセージが保存されることを確認してみます。
IoT Core 構成 やってみる.png

準備:MQTTクライアントツール(MQTTX)をインストールする

下記のサイトを参考にMQTTXというツールをインストールします。

image.png

詳細はこちら

MQTTXの公式サイトを開いて、「ダウンロード」ボタンを押します
https://mqttx.app/ja
image.png

自身の環境にあったものをダウンロードします。(筆者はWindows版をダウンロードしました)
image.png

インストーラーを起動して、「次へ」ボタンを押します
image.png

インストールフォルダを指定して、「インストール」ボタンを押します
image.png

「完了」ボタンを押して準備完了です
image.png

Step1. AWS IoT X.509証明書を発行する

証明書の発行自体は、CloudFormationで書けないようなので、手動で発行を行います。

image.png

AWSマネージドコンソールからAWS IoT Coreの画面を開きます
左メニューから管理 > セキュリティ > 証明書を開き、「証明書を作成」ボタンを押します
image.png

証明書のステータスを「アクティブ」に変えて、「作成」ボタンを押します
image.png

ダイアログが表示されるので、下記の4点セットをダウンロードしておきます

  • デバイス証明書
  • パブリックキーファイル
  • プライバシーキーファイル
  • Amazon 信頼サービスエンドポイント(RSAの方)
    image.png

できました。
image.png

Step2. ClouFormationテンプレートを作成する

次に必要なAWSサービスをデプロイするためのCloudFormationを作成していきます。

image.png

完成版はこちら
templete.yaml
AWSTemplateFormatVersion: "2010-09-09"

Parameters:
  NamePrefix:
    Type: String
    Default: "dev"
    
  CertificateId:
    Type: String

Resources:
  # ------------------------------------------------------------
  # Amazon S3 リソース
  # ------------------------------------------------------------
  # S3バケット
  S3Bucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: !Sub "${NamePrefix}-iot-message-bucket"

  # ------------------------------------------------------------
  # AWS IoT Core リソース
  # ------------------------------------------------------------
  # IoTポリシー
  IoTPolicy:
    Type: AWS::IoT::Policy
    Properties:
      PolicyName: !Sub "${NamePrefix}_iot_policy"
      PolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Action:
              - iot:Connect
              - iot:Publish
              - iot:Subscribe
              - iot:Receive
            Resource: "*"
  
  # ポリシーに証明書を設定
  PolicyAttachment:
    Type: AWS::IoT::PolicyPrincipalAttachment
    Properties:
      PolicyName: !Ref IoTPolicy
      Principal: !Sub "arn:aws:iot:${AWS::Region}:${AWS::AccountId}:cert/${CertificateId}"

  # モノを作成
  IoTThing:
    Type: AWS::IoT::Thing
    Properties:
      ThingName: !Sub "${NamePrefix}_iot_thing"

  # モノに証明書を設定
  CertificateAttachment:
    Type: AWS::IoT::ThingPrincipalAttachment
    Properties:
      ThingName: !Ref IoTThing
      Principal: !Sub "arn:aws:iot:${AWS::Region}:${AWS::AccountId}:cert/${CertificateId}"

  # TopicRule用のIAMロール
  TopicRuleRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Action: sts:AssumeRole
            Principal:
              Service: iot.amazonaws.com
      Policies:
        - PolicyName: TopicRulePolicy
          PolicyDocument:
            Version: 2012-10-17
            Statement:
            - Effect: Allow
              Action: 
                - s3:PutObject
              Resource: !Sub "${S3Bucket.Arn}/*"

  # IoT TopicRule
  IoTTopicRule:
    Type: AWS::IoT::TopicRule
    Properties:
      RuleName: !Sub ${NamePrefix}_iot_topic_rule
      TopicRulePayload:
        Actions:
          - S3:
              BucketName: !Ref S3Bucket
              Key: "iot-data/${topic()}/${timestamp()}"
              RoleArn: !GetAtt TopicRuleRole.Arn
        AwsIotSqlVersion: "2016-03-23"
        RuleDisabled: false
        Sql: !Sub "SELECT * FROM 'iot/topic/sensor'"

  # ログ保存用のIAMロール
  IoTLoggingRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: iot-logging-role
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              Service: iot.amazonaws.com
            Action: sts:AssumeRole
      Policies:
        - PolicyName: IoTLoggingPolicy
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Effect: Allow
                Action:
                  - logs:CreateLogGroup
                  - logs:CreateLogStream
                  - logs:PutLogEvents
                Resource: "*"
  # ログ設定
  IoTLogging:
    Type: AWS::IoT::Logging
    Properties:
      AccountId: !Ref AWS::AccountId
      DefaultLogLevel: ERROR
      RoleArn: !GetAtt IoTLoggingRole.Arn

S3バケットを作成

AWS IoT Coreから送られたメッセージを貯めるためのバケットを作成します。

  S3Bucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: !Sub "${NamePrefix}-iot-message-bucket"

認証・認可の設定

証明書を使用して、IoT Coreの機能にアクセスできるようIoTポリシーを設定します。

  # IoTポリシー
  IoTPolicy:
    Type: AWS::IoT::Policy
    Properties:
      PolicyName: !Sub "${NamePrefix}_iot_policy"
      PolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Action:
              - iot:Connect
              - iot:Publish
              - iot:Subscribe
              - iot:Receive
            Resource: "*"
  
  # ポリシーに証明書を設定
  PolicyAttachment:
    Type: AWS::IoT::PolicyPrincipalAttachment
    Properties:
      PolicyName: !Ref IoTPolicy
      Principal: !Sub "arn:aws:iot:${AWS::Region}:${AWS::AccountId}:cert/${CertificateId}"

モノ(クライアント)を作成

AWS IoT Coreでは、IoTデバイスを「モノ」という単位で管理することが出来ます。
今回は、MQTTXツールを「モノ」として作成します。

  # モノを作成
  IoTThing:
    Type: AWS::IoT::Thing
    Properties:
      ThingName: !Sub "${NamePrefix}_iot_thing"

  # モノに証明書を設定
  CertificateAttachment:
    Type: AWS::IoT::ThingPrincipalAttachment
    Properties:
      ThingName: !Ref IoTThing
      Principal: !Sub "arn:aws:iot:${AWS::Region}:${AWS::AccountId}:cert/${CertificateId}"

RuleEngineとActionを設定する

RuleEngineとAictionでは、全スルーでそのままS3へメッセージを配信する設定にします。
IoT CoreからS3へアクセスが必要なので、IAMポリシーも設定しています。

  # TopicRule用のIAMロール
  TopicRuleRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Action: sts:AssumeRole
            Principal:
              Service: iot.amazonaws.com
      Policies:
        - PolicyName: TopicRulePolicy
          PolicyDocument:
            Version: 2012-10-17
            Statement:
            - Effect: Allow
              Action: 
                - s3:PutObject
              Resource: !Sub "${S3Bucket.Arn}/*"

  # IoT TopicRule
  IoTTopicRule:
    Type: AWS::IoT::TopicRule
    Properties:
      RuleName: !Sub ${NamePrefix}_iot_topic_rule
      TopicRulePayload:
        Actions:
          - S3:
              BucketName: !Ref S3Bucket
              Key: "iot-data/${topic()}/${timestamp()}"
              RoleArn: !GetAtt TopicRuleRole.Arn
        AwsIotSqlVersion: "2016-03-23"
        RuleDisabled: false
        Sql: !Sub "SELECT * FROM 'iot/topic/sensor'"

(デバッグ用) IoT Core全体のログ設定

疎通した際にエラーが起きてもいいようにCloudWatchへログを出力する設定をしておきます。
注意点としては、特定のTopicなどのログではなくIoT Core全体のログ設定となります。

  # ログ保存用のIAMロール
  IoTLoggingRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: iot-logging-role
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              Service: iot.amazonaws.com
            Action: sts:AssumeRole
      Policies:
        - PolicyName: IoTLoggingPolicy
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Effect: Allow
                Action:
                  - logs:CreateLogGroup
                  - logs:CreateLogStream
                  - logs:PutLogEvents
                Resource: "*"
  # ログ設定
  IoTLogging:
    Type: AWS::IoT::Logging
    Properties:
      AccountId: !Ref AWS::AccountId
      DefaultLogLevel: ERROR
      RoleArn: !GetAtt IoTLoggingRole.Arn

CloudFormationをデプロイする

詳細はこちら

AWSマネージドコンソールからCloudFormationの画面を開き、スタックの作成 > 新しいリソースを使用を選択します。

image.png

テンプレートの指定で「テンプレートファイルのアップロード」のラジオボタンを選択します。

image.png

その下の「ファイルの選択」から先ほど作成したテンプレートファイルを指定して、「次へ」ボタンを押します。
image.png

任意のスタック名を入力して、「次へ」ボタンを押します。
image.png

一番最後のチェックボックスにチェックを入れ、「次へ」ボタンを押します。
image.png

最後に「送信」ボタンを押して完了です。(ステータスがCREATE_COMPLETEになることを確認して下さい)
image.png

Step3. MQTTXの設定を行う

ドメインを確認する

IoT Coreのドメインを確認します。MQTTXから接続する際に使います。
image.png

MQTTXを設定する

下記の手順を参考にMQTTXの設定を行います。
https://dev.classmethod.jp/articles/mqtt-client-mqttx/#mqttx%25E5%2581%25B4%25E3%2581%25AE%25E8%25A8%25AD%25E5%25AE%259A

Step4. 疎通してみる

MQTTXからIoT Coreまで届いているか確認する

AWS IoT Core側でテスト > MQTTテストクライアント を開いて、「サブスクライブ」ボタンを押します
image.png

MQTTXにて、送信先のTopicを設定し、画面右下の送信ボタンを押します
image.png

AWS IoT Core側に届きました!
image.png

IoT CoreからS3まで届いているか確認する

AWSマネージドコンソールからS3バケットを確認すると、IoT CoreからS3までも問題なく届いていました!
image.png

届かない場合はCloudWatchのログを確認しよう
先ほどのCloudFormationでAWS IoT Coreのログを有効化しています。
なので疎通で行き詰ったら、CloudWatchのログを見ると解決できるかもしれません。

まとめ

今回は、AWS IoT Coreに入門してみましたが、機能が多いですね...(奥が深い...)

あとIoT Coreから多数のAWSサービスへメッセージを送ることができるのですが、アーキテクチャを考えたときに、SNSを挟むべきか?SQSに積んでから処理するか?それとも直接S3に突っ込むか?など、実際に使うとなると悩みそうだなというのも感じました。(知識ないだけですが...)

今度は、Shadow機能など使えていない機能がまだまだあるので、時間があるときに試したいなーと思っています。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?