こんにちは!MSPセクションの飛田です。

企業のAWS環境が成長するにつれて、複数のAWSアカウントを利用するケースが増えています。

アカウント間でセキュアに通信を行いたい、特にインターネットを経由せずにプライベートなネットワークで通信したいというニーズは非常に高まっています。

この記事では、AWS PrivateLinkを活用して、異なるAWSアカウント間(アカウントAとアカウントB)のプライベートサブネットに存在するEC2インスタンス間での通信をセキュアに実現する手順を詳細に解説します。

前提条件

この記事の手順を実施する前に、以下の前提条件が満たされていることを確認してください。

  • AWSアカウント: AWSアカウントAとAWSアカウントBがそれぞれ存在していること。
  • VPCとサブネット: 各アカウント内にVPCが作成済みであり、プライベートサブネットが構成されていること。
  • EC2インスタンス: 各アカウントのプライベートサブネット内にEC2インスタンスが起動済みであること。
    • 動作確認用にあらかじめ、アカウントBのEC2にapacheをインストールし、curlコマンドなどでAWS acount Bと表示されるように設定しています。

構成図

今回の設定の構成図は以下のようになります。

設定手順

それでは、具体的な設定手順をステップごとに見ていきましょう。

ステップ1: アカウントB (サービスプロバイダー側) での作業

まず、サービスを提供する側、つまりアカウントBでの設定を行います。

ステップ1-1: Network Load Balancer (NLB) の作成

アカウントBで、EC2インスタンスをターゲットとするNetwork Load Balancer (NLB) を作成します。

  1. EC2コンソールを開き、左側のメニューから [ロードバランサー] を選択します。
  2. [ロードバランサーの作成] をクリックします。
  3. [Network Load Balancer] を選択し、[ロードバランサーの作成] をクリックします。
  4. [ステップ 1: ロードバランサー設定の定義] 画面で、以下の項目を設定します。
  • ロードバランサー名: 任意のロードバランサー名を入力します (例: nlb-for-privatelink)。
  • スキーム: [internal] を選択します (重要: プライベートリンク用なのでinternalにします)。
  • ネットワークマッピング
    • アカウントBのEC2インスタンスが属するVPCを選択します。
    • 可用性を考慮して、ap-northeast-1aとap-northeast-1cのプライベートサブネットを選択します。
  • セキュリティーグループ
    • NLB用に新たに作成します。
    • タイプ: [HTTP]ポート: [80]、を選択しソースはアカウントAのVPCのCIDR範囲を指定します。

  • リスナー:
    • ロードバランサープロトコル: [TCP] を選択します。
    • ロードバランサーポート: [80] を入力します。
    • デフォルトアクション: [ターゲットグループに転送] を選択し、[新しいターゲットグループ] をクリックします。
  • ターゲットグループ:
    • ターゲットタイプ: [インスタンス] を選択します。
    • ターゲットグループ名: 任意のターゲットグループ名を入力します (例: tg-ec2-account-b)。
    • プロトコル: [TCP] を選択します。
    • ポート: [80] を入力します。
    • VPC: アカウントBのEC2インスタンスが属するVPCを選択します。
    • ヘルスチェック: TCPを選択します。
    • [次へ]を選択します。
    • 使用可能なインスタンスでアカウントBのEC2インスタンスを選択し、[保留中として以下を含める] をクリックします。
    • [ターゲットグループを作成]を選択します。
  • デフォルトアクション:転送先に、作成したターゲットグループを追加します。
  • [ロードバランサーの作成] をクリックします。

ステップ1-2: VPC Endpoint Service の作成

次に、作成したNLBを紐付けるVPC Endpoint Serviceを作成します。

  1. VPCコンソールを開き、左側のメニューから [Endpoint Service] を選択します。
  2. [Endpoint Service を作成] をクリックします。
  3. [ステップ 1: Endpoint Service 設定の定義] 画面で、以下の項目を設定します。
    • 名前: 任意のエンドポイントサービス名を入力します(例: account-b-endpoint-service)。
    • ロードバランサータイプ: [ネットワーク] を選択します。
    • 使用可能なロードバランサー: 先ほど作成したNLBを選択します (例: nlb-for-privatelink)。
    • リクエスト要件: 必要に応じて設定します。
      • [エンドポイントの承諾が必要] にチェックを入れると、アカウントAからの接続リクエストを手動で承認する必要があります。セキュリティを高くしたい場合はチェックを入れることを推奨します。
      • チェックを外すと、自動的に接続が確立されます。
  4. [Endpoint Service を作成] をクリックします。
  5. 作成されたら[プリンシパルを許可]タブから[プリンシパルを許可]を選択します。
  6. 追加するプリンシパルに[arn:aws:iam::アカウントAのアカウントID:root]の形式でARNを入力します。
    (重要:この手順は忘れがちなので必ず実施するようにしましょう)
  7. 作成されたEndpoint Serviceの詳細画面を開き、[サービス名] をメモしておきます。このサービス名は、アカウントAからVPC Endpointを作成する際に必要になります。

ステップ2: アカウントA (サービスコンシューマー側) での作業

次に、サービスを利用する側、つまりアカウントAでの設定を行います。

ステップ2-1: VPC Endpoint (Interface Endpoint) の作成

アカウントAで、アカウントBのVPC Endpoint Serviceに接続するためのVPC Endpoint (Interface Endpoint) を作成します。

  1. VPCコンソールを開き、左側のメニューから [エンドポイント] を選択します。
  2. [エンドポイントを作成] をクリックします。
  3. [ステップ 1: エンドポイント設定の定義] 画面で、以下の項目を設定します。
    • 名前タグ – オプション: 任意の名前を入力します(例: account-a-vpce)。
    • タイプ: [NLBとGWLBを使用するエンドポイントサービス] を選択します。
    • サービス名: ステップ1-2でメモしたアカウントBのVPC Endpoint Serviceの**[サービス名]** を入力します。
      サービスの検証が成功すると、サービス名が検証されました。と表示されます。
    • VPC: アカウントAのEC2インスタンスが属するVPCを選択します。
    • サブネット: VPC Endpointを作成するサブネットを選択します。プライベートサブネットを選択してください。複数のアベイラビリティーゾーンのサブネットを選択することを推奨します。
    • セキュリティグループ: VPC Endpointに適用するセキュリティグループを選択します。新しいセキュリティグループを作成し、インバウンドルールポート80アカウントAのプライベートサブネットからのトラフィック(CIDR)を許可するように設定します。
  4. [エンドポイントを作成] をクリックします。
    ステータスが保留中であることを確認します。
ステップ2-2: エンドポイントの承諾

各アカウントでエンドポイントの承諾と確認を行います。

  • アカウントB (エンドポイントサービス):
    • エンドポイントサービスのエンドポイント接続タブのアクションからエンドポイント接続リクエストの承諾を選択します。
    • 状態がpendingであることを確認します。
  • アカウントA (エンドポイント):
    • ステータスが利用可能になったことを確認します
  • アカウントB (エンドポイントサービス):
    • 再度アカウントBに戻り、状態がAvailableになったことを確認します。
ステップ2-3: セキュリティグループの調整

最後に、各セキュリティグループの設定を調整します。

  • アカウントB (EC2インスタンスのセキュリティグループ):
    • インバウンドルール: ポート80 を許可するルールを追加します。ソースは、作成したNLBのセキュリティーグループを指定します。
      (重要:この手順を忘れるとターゲットグループのヘルスチェックが通らないので注意しましょう。)
  • アカウントA (VPC Endpointのセキュリティグループ):
    • インバウンドルール: ポート80 を許可するルールが、VPC Endpoint作成時に設定されていることを確認します (アカウントAのプライベートサブネットからのトラフィックを許可)。
    • アウトバウンドルール: 通常はデフォルトで全て許可されていますが、必要に応じて確認してください。
  • アカウントA (EC2インスタンスのセキュリティグループ):
    • アウトバウンドルール: ポート80 を許可するルールを追加します。送信先は、アカウントBのプライベートサブネット、またはVPC EndpointのENIのIPアドレス宛のトラフィックを許可するように設定します (最初は広めに設定し、後から絞り込むことを推奨します)。

通信確認

設定が完了したら、アカウントAのEC2インスタンスからアカウントBのEC2インスタンスへ80番ポートで通信できることを確認します。

  1. アカウントAのEC2インスタンスにSSH接続します。
  2. curl コマンドなどを使用して、VPC EndpointのDNS名宛にポート80でアクセスします。VPC EndpointのDNS名は、アカウントAのVPCコンソールで、作成したVPC Endpointの詳細画面から確認できます。

curl {VPC EndpointのDNS名}:80

下記のようにアカウントBのEC2インスタンスでHTTPサービスが正常に動作していれば、レスポンスが返ってくるはずです。

まとめ

AWS PrivateLinkを使用することで、異なるAWSアカウント間でもインターネットを経由せずにセキュアなプライベート通信を実現できます。今回の例では80番ポートでの通信を設定しましたが、他のポートやプロトコルでも同様の手順で設定可能です。

PrivateLinkを活用することで、セキュリティを向上させながら、柔軟なAWS環境を構築することができます。ぜひ、今回の記事を参考に、PrivateLinkの利用を検討してみてください。