AWSアカウントを跨いでSQSのメッセージを送信するパターン集

大栗です。

多数のシステムを運用するときは、システムに応じてAWSアカウントやVPCを分けて配置することを検討します。システム間で疎結合にメッセージを交換するためにSQSを多用しますが、AWS構成は色々と考えられます。パターンによってメリット・デメリットがあるのでまとめてみました。

参考:AWSアカウントとVPC、分ける? 分けない?: 分割パターンのメリット・デメリット

AWSアカウントを跨ぐSQS使用で検討すべきこと

AWSアカウントを跨いでSQSでメッセージを送信する場合には、以下の様なことを検討する必要があります

  • アクセス権限は?(送信元アカウントと送信先アカウントの権限)
  • SNSを使う?使わない?
  • どっちのアカウントに配置する?(送信元アカウントと送信先アカウント)

アクセス権限

AssumeRoleによる異なるアカウントの権限の取得

アカウントを超えて一般的なAWSリソースにアクセスする場合には、AssumeRole1を使用することが多いです。

AssumeRoleを使用するには、以下の手順が必要になります。
基本的にこの手順をアクセスする都度2実行する必要があります。

  1. AssumeRoleを実行する。
  2. STSが一時的なアカウントBのアクセス情報を発行する。
  3. アカウントBとしてSQSへアクセスする。

IAMの権限の設定を行うことで、AssumeRoleで発行した一時的なアクセス情報でSQS以外のリソースへもアクセスできます。そのため別のアカウントに対して様々なリソースへアクセスする場合にはAssumeRoleを使用する事を推奨します。ただし、アクセスする毎に一時的なアクセス情報を発行するとパフォーマンスに影響が出るため、アクセス情報をキャッシュしてAssumeRoleの回数を減らすべきです。

AssumeRole

SQS Policyによる異なるアカウントからのアクセス許可

SQSやS3、SNSなどにはIAMとは異なるアクセスポリシーが設定できます。

SQSのアクセスポリシーで設定する場合は、以下の手順が必要となります。
SQS Policyは事前設定なので、同じアカウントのSQSと同じように異なるアカウントのSQSへアクセスできます。

  1. 事前にSQS PolicyでアカウントAのアクセスを許可する
  2. アカウントAとしてSQSへアクセスする

アクセス元のプログラムではアカウントが異なることを意識する事無くメッセージを送信できるので、別のアカウントに対してSQSのみアクセスする場合は手間がかからないアクセスポリシーの設定を推奨します。ただし、アクセス元の管理者では権限を外す事ができない(IAMユーザやIAM Roleの削除は可能)ので注意が必要です。

SQS_Policy_2

SQS Policyの記述方法は、以下の内容を参考にして下さい。

SNSの使用可否

【AWS】SQSキューの前には難しいこと考えずにSNSトピックを挟むと良いよ、という話というエントリがあるのですが、SQSの前にSNSを挟むという考え方もあります。エントリ内でも言及がありますが、YAGNI(You ain't gonna need it)に反する部分があるため必ずしもSNSを挟む必要はありません。

最近SQSにFIFOキューが追加されましたが、FIFOキューの場合は現時点でSNSからメッセージを転送できないので注意しましょう。

Q: Amazon SQS FIFO キューは、Amazon Simple Notification Service (SNS) と互換性がありますか?

Amazon SNS は現在 FIFO キューへのメッセージ転送をサポートしていません。SNS を使用して標準キューにメッセージを転送することはできます。

SNSを使用する

SNSを挟むべき代表的なユースケースとしてFanoutパターンがあります。一つ目イベントに対して並行して処理を行う場合には、SNSをメッセージのハブの様に使用してPub/Subモデルのアーキテクチャを採用してPublisherで複数メッセージを送信せずにSNSに任せましょう。

SNSを使用しない

SNSを挟むべきでないユースケースとしてQueuing Chainパターンがあります。ジョブやキューを直列に複数つなげる場合には、SNSを挟まずに連携するコンポーネントを減らしてシンプルなアーキテクチャにすることをお勧めします。

SQSを配置するアカウント

SQSを送信元アカウントか送信先アカウントのどちらに配置するかも検討材料となります。キューに入ったメッセージについて運用の管理をどのアカウントで行うのか?という問を念頭に置いて考えます。

SQSのみ配置する場合

SQSのみ配置する場合には、以下の2パターンが考えられます。

  1. 送信先アカウントに配置
  2. 送信元アカウントに配置

SQSでは一旦メッセージを投入すると、送信先でリトライ処理を行ったり、可視性タイムアウトを送信先の処理時間に応じて変更する必要があります。メッセージに対する操作やキュー自体に対する操作は送信先で実施することが多くなるので『送信先アカウントに配置』することを基本としましょう。

クロスアカウント配置_SQS_2

SQSとSNSを連携する場合

SQSとSNSを連携する場合には、以下の3パターンが考えられます。

  1. 送信先アカウントに両方配置
  2. 送信先を送信元に分ける
  3. 送信元アカウントに両方配置

前項の『SQSのみ配置する場合』で述べている通り、SQSは送信先に配置するほうが良いので1.と2.を検討します。つまりSNSを配置するアカウントはどちらかと言うことです。
SNSを使用する場合は、基本的にPub/Subモデルを適用する事になります。Pub/Subモデルの利点の一つとしてPublisherとSubscriberを疎結合にして役割や責任を分離できることがあります。送信元にPublisherであるSNSを、送信先にSubscriberであるSQSを配置すると役割や責任を明確に分離できます。そのため『送信先を送信元に分ける』事を推奨します。

クロスアカウント配置_SQS_SNS_2

まとめ

大規模なシステムでは権限分離のためにサブシステム単位でにアカウントを分離する場合があります。アカウントを超えてメッセージをやり取りする場合は様々な検討課題があります。本エントリではアクセス権限、他サービス(SNS)連携、配置アカウントの3点を取り上げて構成を検討しました。ユースケースによっては他にも検討すべき課題があるかもしれませんが、まとめた内容が参考になれば幸いです。


  1. AssumeRoleの詳細はIAMロール徹底理解 〜 AssumeRoleの正体を参照下さい。 
  2. 一時的なアクセス情報は一定の有効期間があるため、必ずしも毎回である必要はありません。