Amazon MQ RabbitMQブローカーにおけるクラスターデプロイメントモードについて

このブログシリーズ 「クラウドセキュリティ 実践集」 では、一般的なセキュリティ課題を取り上げ、「なぜ危険なのか?」 というリスクの解説から、「どうやって直すのか?」 という具体的な修復手順(コンソール、AWS CLI、Terraformなど)まで、分かりやすく解説します。

この記事では、Amazon MQのRabbitMQブローカーのアクティブ/スタンバイデプロイメントモードについて解説します。

ポリシーの説明

Amazon MQ の Security Hub コントロール – AWS Security Hub

[MQ.6] RabbitMQ ブローカーはクラスターデプロイメントモードを使用する必要があります。

このコントロールは、Amazon MQ RabbitMQ ブローカーのデプロイモードがクラスターデプロイに設定されているかどうかを確認します。単一インスタンスブローカー (デフォルトで有効) がデプロイモードに設定されている場合、コントロールは失敗します。

リスク

Amazon MQは、クラウドでメッセージブローカーを簡単にセットアップおよび運用できるマネージドメッセージブローカーサービスです。特にRabbitMQは、多くの分散アプリケーションで利用されています。しかし、Amazon MQ RabbitMQブローカーがクラスターデプロイメントモードを使用していない場合、以下のような重大な可用性およびデータ保護上のリスクが発生します。

  • 単一障害点 (SPOF) の発生: シングルインスタンスのRabbitMQブローカーは、単一のアベイラビリティーゾーン (AZ) 内の1つのサーバー上で動作します。もしこのサーバーに障害が発生したり、基盤となるAZに問題が発生したりすると、ブローカー全体が利用不能になり、メッセージの送受信が停止し、アプリケーションの機能が中断されます。
  • データ損失のリスク: シングルインスタンスモードでは、メッセージデータは基本的にその単一のノードにのみ保存されます。もしノードが回復不能な障害に見舞われた場合、キューに格納されていた未処理のメッセージや、永続化されたメッセージデータが失われる可能性があります。これは、金融取引、注文処理、重要な通知システムなど、データ損失が許容されないアプリケーションにとって壊滅的な影響を与えます。
  • ダウンタイムの増加: 計画的なメンテナンス(AWSによるパッチ適用など)や予期せぬ障害が発生した場合、シングルインスタンスブローカーは再起動や復旧に時間がかかります。この間、アプリケーションはメッセージング機能を利用できず、ダウンタイムが長くなり、サービスの可用性が低下します。
  • スループットとパフォーマンスの制約: クラスターデプロイメントは、複数のノード間で負荷を分散できるため、単一ノードよりも高いスループットとより良いパフォーマンスを提供できます。シングルインスタンスモードでは、このスケーラビリティの恩恵を受けられません。
  • 高可用性および災害復旧戦略の欠如: シングルインスタンスブローカーは、高可用性や災害復旧の要件を満たすことができません。ビジネス継続性計画において、メッセージングシステムの信頼性は極めて重要であり、クラスター化はこれらの要件を満たすための基本的な手段です。

対策

Amazon MQ RabbitMQブローカーをクラスターデプロイメントモードで設定することは、メッセージングシステムの高可用性、耐久性、およびデータ整合性を確保するための重要なベストプラクティスです。

  • クラスターデプロイメントの選択: Amazon MQ RabbitMQブローカーを作成または移行する際に、必ずクラスターデプロイメントモードを選択します。これにより、3つのRabbitMQブローカーノードが論理的にグループ化され、それぞれが異なるアベイラビリティーゾーンに配置されます。
  • データ複製と同期: クラスターデプロイメントでは、RabbitMQのミラーキュー機能などを活用し、メッセージデータがクラスター内の全ノードに複製されます。これにより、ノード障害が発生した場合でも、他のノードがメッセージ処理を引き継ぎ、ダウンタイムとデータ損失を最小限に抑えます
  • 自動フェイルオーバー: Amazon MQは、クラスター内のノードに障害が発生した場合、自動的にトラフィックを健全なノードにルーティングします。これにより、アプリケーションはブローカーの障害から透過的に回復でき、手動での介入なしにサービスを継続できます。
  • 専用のEBSボリューム: 各RabbitMQブローカーノードには専用のAmazon Elastic Block Store (Amazon EBS) ボリュームが割り当てられます。これにより、メッセージの永続化と耐久性が確保されます。
  • 共有状態の保持: クラスターは単一の共有状態を保持するため、異なるノードに接続しているクライアントも一貫したメッセージングエクスペリエンスを得られます。

修復方法

AWSコンソールでの修復手順

Amazon MQ RabbitMQブローカーをシングルインスタンスからクラスターデプロイメントに直接変更することはできません。このため、修復は既存のシングルインスタンスブローカーからの移行または新規作成という形になります。

AWSコンソールでの修復手順(新規作成の場合)

新しいAmazon MQ RabbitMQブローカーをクラスターデプロイメントモードで作成する手順です。

  1. Amazon MQサービスへ移動: AWSコンソールにログインし、Amazon MQ サービスを開きます。
  2. ブローカーの作成:ブローカーを作成」をクリックします。
  3. ブローカーの詳細設定:
    • ブローカータイプを選択: 「RabbitMQ」を選択します。
    • デプロイモードを選択: 「クラスタデプロイ」を選択します。これが最も重要な設定です。
    • ブローカーエンジンバージョン: 適切なバージョンを選択します。
    • ブローカー名: 任意の名前を付けます。
    • ブローカーインスタンスタイプ: アプリケーションの要件に合ったインスタンスタイプを選択します。
    • ブートユーザー名とパスワード: RabbitMQ管理コンソールおよびアプリケーション接続用のユーザー認証情報を設定します。
    • ネットワーク設定:
      • VPC: ブローカーをデプロイするVPCを選択します。
      • サブネット: 少なくとも3つの異なるアベイラビリティーゾーンにまたがるサブネットを選択します。クラスターデプロイは複数のAZにノードを分散します。
      • セキュリティグループ: アプリケーションや管理ツールからRabbitMQポート(デフォルト: 5671 for AMQP/TLS, 15671 for management over HTTPS)へのアクセスを許可するセキュリティグループを設定します。
    • その他の設定: 必要に応じて、ストレージタイプ(General Purpose SSD (gp3) を推奨)、バックアップ設定、メンテナンスウィンドウ、タグなどを設定します。
  1. ブローカーの作成: 設定を確認し、「ブローカーを作成」をクリックします。 ブローカーの作成には時間がかかります。作成後、アプリケーションを新しいクラスターブローカーに接続するように設定を更新します。

Terraformでの修復手順

TerraformでAmazon MQ RabbitMQブローカーをクラスターデプロイメントモードで作成する例です。既存のシングルインスタンスから移行する場合は、現在のブローカーをTerraformで管理し、その設定を更新するか、新しいクラスターブローカーをTerraformで作成し、移行後に古いブローカーを削除します。

# (例) VPC、サブネット、セキュリティグループ
resource "aws_vpc" "main" {
  cidr_block = "10.0.0.0/16"
  tags = {
    Name = "mq-vpc"
  }
}

resource "aws_subnet" "private_subnet_a" {
  vpc_id            = aws_vpc.main.id
  cidr_block        = "10.0.1.0/24"
  availability_zone = "${data.aws_region.current.name}a"
  tags = {
    Name = "mq-private-subnet-a"
  }
}

resource "aws_subnet" "private_subnet_b" {
  vpc_id            = aws_vpc.main.id
  cidr_block        = "10.0.2.0/24"
  availability_zone = "${data.aws_region.current.name}b"
  tags = {
    Name = "mq-private-subnet-b"
  }
}

resource "aws_subnet" "private_subnet_c" {
  vpc_id            = aws_vpc.main.id
  cidr_block        = "10.0.3.0/24"
  availability_zone = "${data.aws_region.current.name}c"
  tags = {
    Name = "mq-private-subnet-c"
  }
}

resource "aws_security_group" "rabbitmq_sg" {
  name        = "rabbitmq-access-sg"
  description = "Allow access to RabbitMQ broker"
  vpc_id      = aws_vpc.main.id

  # AMQP/TLSポート (5671)
  ingress {
    from_port   = 5671
    to_port     = 5671
    protocol    = "tcp"
    cidr_blocks = ["10.0.0.0/16"] # VPC内部からのアクセスを許可。必要に応じて限定
    description = "Allow AMQP/TLS from VPC"
  }

  # RabbitMQ管理コンソール (15671) - 通常は限定されたIPからのみ許可
  ingress {
    from_port   = 15671
    to_port     = 15671
    protocol    = "tcp"
    cidr_blocks = ["YOUR_TRUSTED_IP_CIDR/32"] # 管理用IPアドレスに置き換え
    description = "Allow RabbitMQ Management from trusted IPs"
  }

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }

  tags = {
    Name = "rabbitmq-sg"
  }
}

# Amazon MQ RabbitMQ クラスターブローカー
resource "aws_mq_broker" "rabbitmq_cluster_broker" {
  broker_name        = "my-rabbitmq-cluster-broker"
  engine_type        = "RabbitMQ"
  engine_version     = "3.12.10" # 最新のサポートバージョンを確認
  host_instance_type = "mq.m5.large" # 適切なインスタンスタイプを選択

  # クラスターデプロイメントモードを有効化
  deployment_mode    = "CLUSTER_MULTI_AZ"

  # 3つの異なるAZにまたがるサブネットを指定
  subnet_ids         = [
    aws_subnet.private_subnet_a.id,
    aws_subnet.private_subnet_b.id,
    aws_subnet.private_subnet_c.id,
  ]
  security_groups    = [aws_security_group.rabbitmq_sg.id]

  # ブートユーザーの定義
  user {
    username = "mqadmin"
    password = "YourStrongPasswordHere123!" # 強力なパスワードに置き換え
  }

  # 必要に応じて追加設定
  apply_immediately      = true
  auto_minor_version_upgrade = true
  public_and_private_addresses = false # プライベートアドレスのみを推奨
  storage_type           = "EBS"
  storage_type_config {
    storage_type = "EBS"
    # EBS設定 (gp3を推奨)
    volume_type = "gp3"
    throughput  = 125 # MB/s
    iops        = 3000
  }

  # CloudWatch Logs へのロギング設定 (推奨)
  logs {
    audit   = true # 監査ログを有効化
    general = true # 一般ログを有効化
  }

  tags = {
    Environment = "Production"
  }
}

# 現在のAWSリージョンを取得
data "aws_region" "current" {}

上記のTerraformコードでは、aws_mq_broker リソースの deployment_mode"CLUSTER_MULTI_AZ" に設定することで、RabbitMQブローカーをクラスターデプロイメントモードで作成しています。

  • subnet_ids: クラスターデプロイの場合、少なくとも3つの異なるアベイラビリティーゾーンにまたがるサブネットを指定する必要があります。
  • engine_typeengine_version: RabbitMQのエンジンタイプとバージョンを指定します。
  • host_instance_type: ブローカーインスタンスのタイプを指定します。
  • user: RabbitMQ管理コンソールおよびアプリケーション接続用のユーザー認証情報を設定します。
  • public_and_private_addresses: セキュリティのため、falseに設定し、プライベートアドレスのみを公開することを推奨します。

YOUR_TRUSTED_IP_CIDR/32YourStrongPasswordHere123! などのプレースホルダーは、実際の環境に合わせて修正してください。

最後に

この記事では、Amazon MQ RabbitMQブローカーをクラスターデプロイメントモードで運用することの重要性について解説しました。クラスターデプロイは、メッセージングシステムの可用性、耐久性、およびデータ損失耐性を大幅に向上させ、単一障害点のリスクを軽減します。

貴社のAmazon MQ RabbitMQブローカーは、高可用性を考慮したクラスターデプロイメントモードで稼働していますか?この機会にぜひ設定を確認し、必要であれば新しいクラスターブローカーへの移行を検討してください。

こちらの内容の検出は弊社が提供するSecurifyのCSPM機能で簡単に検出及び管理する事が可能です。運用が非常にラクに出来る製品になっていますのでぜひ興味がある方はお問い合わせお待ちしております。

最後までお読みいただきありがとうございました。この記事が皆さんの役に立てば幸いです。

この記事をシェアする

クラウドセキュリティ対策実践集一覧へ戻る

貴社の利用状況に合わせた見積もりを作成します。

料金プランを詳しく見る