TerraformでAWS SQSとSNSのファンアウトを実装する

AWS
Nishipy
公式チュートリアルをもとに、SQSとSNSを連携してみます

予備知識

まずは、SQSとSNSについて軽くまとめます。

SQS

Amazon SQS(サーバーレスアプリのためのメッセージキューサービス)| AWS
Amazon SQS の完全マネージド型のメッセージキューは、マイクロサービス、分散システム、およびサーバーレスアプリケーションの切り離しとスケーリングを容易にします。

SQSは、Amazon Simple Queue Serviceの略で、完全マネージド型のメッセージキューイングサービスです。疎結合なアーキテクチャを実現します。

Amazon Simple Queue Service (SQS) は、完全マネージド型のメッセージキューイングサービスで、マイクロサービス、分散システム、およびサーバーレスアプリケーションの切り離しとスケーリングが可能です。SQS では、メッセージ指向ミドルウェアの管理や運用に関連する複雑さやオーバーヘッドを排除できるため、開発者が差別化作業に集中することができます。SQS を使用すると、あらゆる量のソフトウェアコンポーネント間でメッセージを送信、保存、受信できます。メッセージが失われることはなく、他のサービスを利用可能にしておく必要もありません。

もっと細かい説明やFAQは、ここに書いてあります。

よくある質問 - Amazon SQS | AWS
FIFO キュー、メッセージ識別子、ロングおよびショートポーリング、セキュリティなどについては、Amazon SQS のよくある質問への回答をご覧ください。

まずキューの種類としては、以下の2つがあります。メッセージサイズは、最大256KB。

  • スタンダード: 通常はこちら。パフォーマンスは高いが、順序保証なし
  • FIFO: 順序保証あり。東京リージョンでも利用可能

SQSのキューからメッセージを取得する際はポーリングを行います。ポーリングには、以下の2種類があります。ほとんどの場合、パフォーマンス面とコスト面で、ロングポーリングの利用が推奨されているようです。

  • ショートポーリング: 通常かこちら。ポーリングされたメッセージキューが空であっても直ちに応答を返す
  • ロングポーリング: ロングポーリングではメッセージがメッセージキューに達するか、ロングポーリングがタイムアウトになるまで応答を返さない

さらに、処理に失敗したメッセージを分離して扱うために、デッドレターキューを用意しておくのがよいみたいです。

Amazon SQSデッドレターキュー - Amazon Simple Queue Service
正常に処理できないメッセージを他のキューがターゲットにすることができる、 Amazon SQSデッドレターキューへのメッセージの送信について説明します。

SNS

Amazon SNS(サーバーレスアプリのための pub/sub メッセージングサービス)| AWS
Amazon SNSは柔軟なフルマネージド型の pub/sub メッセージング/モバイル通知サービスです。SNS を使用すると、分散システムやサービス、モバイルデバイスなど、多数の受信者にメッセージを送信することができます。

SNSは、Amazon Simple Notification Serviceの略で、完全マネージド型 pub/sub メッセージングサービスです。疎結合なアーキテクチャを実現します。

Amazon Simple Notification Service (SNS) は、マイクロサービス、分散型システム、およびサーバーレスアプリケーションの分離を可能にする、高可用性で、耐久性に優れたセキュアな完全マネージド型 pub/sub メッセージングサービスです。Amazon SNS は、高スループット、プッシュベース、多対多のメッセージングのためのトピックを提供します。Amazon SNS トピックを使用すると、パブリッシャーシステムが、Amazon SQS キュー、AWS Lambda 関数、および HTTP/S ウェブフックを含む並列処理のために、メッセージを多数のサブスクライバーエンドポイントにファンアウトすることができるようになります。また、SNS はモバイルプッシュ、SMS、E メールを使用するエンドユーザーに対し、通知をファンアウト (一括送信) するのに使用できます。

もっと細かい説明やFAQは、ここに書いてあります。

よくある質問 - Amazon SNS | AWS
セキュリティ、信頼性、コンプライアンス、SMS、Voip iOS 通知と MAC OS 通知などについては、Amazon SNS のよくある質問への回答をご覧ください。

SNSはpub/sub メッセージングサービスであり、登場する用語は以下の通りです。SNSのメッセージは、SQSのようにポーリングされず、即座にサブスクライバーに配信されます。メッセージサイズは、最大256KB。

  • パブリッシャー(pub): メッセージをパブリッシュ(公開)するやつ
  • サブスクライバー(sub): メッセージをサブスクライブ(購読)するやつ
  • トピック: パブリッシャーがメッセージを公開するところ。トピックに公開されたメッセージは、そのトピックに紐づいたサブスクライバーに配信される

ファンアウト

SNSでは1つのトピックに対して、複数のサブスクライバーが設定できます。そのため、SNSトピックを起点として、様々な非同期処理を並行して実行できます。扇状に広がっていくため、ファンアウト(Fan-out)らしい?

「ファンアウト」シナリオでは、Amazon SNS メッセージがトピックに送信され、その後レプリケートされて、複数の Amazon SQS キュー、HTTP エンドポイント、E メールアドレスにプッシュされます。これで並列非同期処理が可能になります。

一般的な Amazon SNS シナリオ - Amazon Simple Notification Service
ファンアウト シナリオは、SNS トピックに発行されたメッセージがレプリケートされ、Firehose 配信ストリーム、Amazon SQS キュー、HTTP(S) エンドポイント、Lambda 関数などの複数のエンドポイントにプッシュされる場合です。これで並列非同期処理が可能になります。 本番稼働用データをテスト環境に...(続く)



公式チュートリアル

「ファンアウトイベント通知を送信する」というチュートリアルが公式で用意されています。このチュートリアルでは、Amazon Simple Notification Service (SNS) と Amazon Simple Queue Service (SQS) を使って、ファンアウトを実装しています。

Send Fanout Event Notifications with Amazon SQS and Amazon SNS
Tutorial: Send Fanout Event Notifications with Amazon Simple Queue Service (SQS) and Amazon Simple Notification Service (SNS)

操作は全てGUIベースで行われます。これだけやっても面白くないので、今回はTerraformでコード化してみました。

SNSとSQSの準備

terraform.tfvars

まずは、クレデンシャルを変数として設定します。自分のアクセスキーIDとシークレットアクセスキーを入れてください。

main.tf

メインの処理は、このファイルにまとめています。おおまかには以下のような処理を行っています。

  • SNSトピック作成
  • SQSキュー作成(2つ)
    • キューのポリシー設定
    • SNSのサブスクリプション設定

サブスクライバー側のSQSにポリシーを設定するのを忘れていて、後から追記しました。

あとは以下のコマンドを実行するだけで、今回のチュートリアルに必要な環境は整います。



SNSトピックにメッセージを発行

SNSトピックにメッセージをパブリッシュします。内容は、チュートリアルにあわせて、"1 x Widget @ $29.99 USD, 2 x Widget Cables @ $4.99"とします。

SQSで確認

サブスクライバーとして設定したSQSのキューを確認します。無事配信されています。

クリーンアップ

作ったSNSとSQSの環境は、忘れず消しておきましょう。

さいごに

疎結合なアーキテクチャを実現するSNSとSQSを使いました。AWSフルマネージドのサービスなので、すぐに始められていいですね。マネージドコンソールが若干使いにくかったりしましたが、とても楽に操作できました。また、このブログでTerraformを使ったのも初めてなので、今後機会を増やしていきたいと思います。

TerraformとAnsibleの違いを調べてみた
NishipyTerraformというOSSを最近知りました。Ansibleとの違いがわからず調査したのですが、英語の記事しか見つからず、地味に苦労したのでまとめます。1. Terraformとは?Terraf...(続く)

以上.

コメント