「Basic Ingest」をうまく使ってAWS IoT Coreのコストを削減しよう

コスト削減のために、隙あらば使っていきたい
2021.07.18

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

概要

本エントリーでは、「AWS IoT」のコスト削減に寄与してくれるであろう「Basic Ingest」についてまとめます。
シンプルで導入しやすい機能なので、コスト削減を検討したい方は是非ご検討いただきたい機能です。

Reducing messaging costs with basic ingest

目次

1.Basic Ingestについて

AWSIoTを利用するにあたって、デバイスからAWSに送信したメッセージに基づいてなんらかのアクション(ex. lambda関数を実行)を実行したいケースは多いと思います。
そのためには、実行したい「ルールアクション」とそのトリガーとなる「ルール」を 「ルールエンジン」に設定する必要があります。
 「ルールエンジン」は 「メッセージブローカー」 を介して「デバイスゲートウェイ(デバイス)」からのメッセージを受け取ることで、「ルールアクション」を実行することができます。

「Basic Ingest」機能を利用すると、「メッセージブローカー」を介さず直接「ルールエンジン」にメッセージを送信できるため、メッセージングコストが削減できます。
(ルールエンジンやアクションのコストは変わらず発生する点に注意してください)

参照: AWS IoT Core 料金

注意点として、メッセージが「メッセージブローカーをバイパスする」ため「他のデバイスが対象のトピックをサブスクライブして、なんらかの処理を実行する」といったケースでは「Basic Ingest」は採用できません。
「Basic Ingest」は「デバイスからAWSにメッセージを送信してルールアクションを実行したいだけ」のような場合に採用しましょう。

また、そもそもメッセージングコストが小さいなら、無理して「Basic Ingest」を導入するメリットは小さいです。
例えば、以下は東京リージョン(2021年7月18日時点)での料金ですが、「毎月100万件のメッセージングしかしていない」場合はそもそもメッセージングコストに1.2USDしかかかっていないので、このコストを削減するために「Basic Ingest」を導入するメリットは小さいです。

条件 コスト
メッセージ 10 億件まで 1.20USD (メッセージ 100 万件あたり)
次のメッセージ 40 億件 0.96USD (メッセージ 100 万件あたり)
メッセージ 50 億件超 0.84USD (メッセージ 100 万件あたり)

参照: AWS IoT Core 料金

「Basic Ingest」は「メッセージブローカーをバイパス」しているため、あくまでも「選択肢を減らしている」点には注意してください。

2.やり方

「Basic Ingest」は以下の規則でトピックにメッセージをパブリッシュすれば実行できます。

$aws/rules/<実行したいIoTルール名>/<IoTルールのFROMで指定したトピック>

例えば、hoge/fooトピックを対象として「myrule」というルールを作成した場合は、以下のトピックにメッセージをパブリッシュすることで、「Basic Ingest」機能を利用することができます。

$aws/rules/myrule/hoge/foo

3.やってみた

まずは「Basic Ingest無し」でルールアクションを起動してみます。
その後に「Basic Ingest」機能を利用してアクションを実行してみます。

下準備内容を知りたい方はこちらをクリック!!
  • ルールとアクション

「test/topic」トピックにきたメッセージをそのままS3に保存するアクションを設定しました。
ルール名は「test_basic_ingest」です。

格納先のS3パスは以下のようにまだ空っぽです。

  • IoTポリシー

test/topicトピックにメッセージをパブリッシュするために必要な権限を付与します。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "iot:Publish"
      ],
      "Resource": [
        "arn:aws:iot:<region>:<awsAccountId>:topic/test/topic"
      ]
    },
    {
      "Effect": "Allow",
      "Action": [
        "iot:Connect"
      ],
      "Resource": [
        "arn:aws:iot:<region>:<awsAccountId>:client/test-*"
      ]
    }
  ]
}

Basic Ingest無し

test/topicトピックにメッセージをパブリッシュしてみます。
これだと、「Basic Ingest」無しで、普通にメッセージブローカーを介してルールエンジンにメッセージを送信している状態です。
ちゃんとS3にオブジェクトが格納できることが確認できました。

Basic Ingest有り

続いて、「Basic Ingest」で同様のアクションを実行できるかを確認します。

「Basic Ingest」で同様のアクションを実行するための下準備はこちら!
  • IoTポリシーを修正

「Basic Ingest」を利用するためにメッセージを送信するべきトピックを変更する必要があるので、IoTポリシーを変更します。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "iot:Publish"
      ],
      "Resource": [
        "arn:aws:iot:<region>:<awsAccountId>:topic/$aws/rules/test_basic_ingest/test/topic"
      ]
    },
    {
      "Effect": "Allow",
      "Action": [
        "iot:Connect"
      ],
      "Resource": [
        "arn:aws:iot:<region>:<awsAccountId>:client/test-*"
      ]
    }
  ]
}

あとはデバイス側のスクリプトでパブリッシュ先のトピックを変更します。

topic="$aws/rules/test_basic_ingest/test/topic"

下準備を施した後にメッセージをパブリッシュしてみると、ちゃんとアクションが実行できてS3にオブジェクトが格納できていることが確認できましたo(・∇・o)

4.まとめ

開発初期はまだ将来的にどうなるか分からないのでとりあえず選択肢の多い「メッセージブローカー」にPublishしていたものの、ある程度開発が落ち着いたら「これ、メッセージブローカーを介する必要なくない...?」となることもあるかもしれません。
もしメッセージングコストが高くつきそうな方は、「Basic Ingest」について頭の片隅に入れておくと、少しハッピーになれるかもしれません。

おまけ

topic()関数は使えるのだろうか、と気になったのですがちゃんと使えました。

基本的な取り込みが使用されている場合、トピック ($aws/rules/rule-name) の最初のプレフィックスは topic() 関数では使用できません。たとえば、次のトピックがあるとします。
$aws/rules/BuildingManager/Buildings/Building5/Floor2/Room201/Lights
topic() = "Buildings/Building5/Floor2/Room201/Lights"
topic(3) = "Floor2"

参照: topic(10 進数)

参照