マルチリージョンアクセスポイントを利用して、インターネットへの接続経由がない閉鎖的 VPC 環境からのクロスリージョン S3 アクセスをやってみた

マルチリージョンアクセスポイントを利用して、インターネットへの接続経由がない閉鎖的 VPC 環境からのクロスリージョン S3 アクセスをやってみた

Clock Icon2025.04.07

はじめに

テクニカルサポートの 片方 です。
東京リージョンの閉鎖的な VPC 環境(インターネット接続なし)に配置された EC2 インスタンスから、異なるリージョンの S3 バケットへ、AWS 内部ネットワークのみを使用してセキュアにアクセスしたいという場合があります。
以前であれば、別リージョンの VPC、VPC ピアリング又は Transit Gateway、別リージョンの S3 インターフェース VPC エンドポイントが必要であり大変でした。

今回ご紹介するマルチリージョンアクセスポイントを使用する方法であれば、"マルチリージョンアクセスポイント" と "S3 インターフェース VPC エンドポイント(com.amazonaws.s3-global.accesspoint)" のみで簡単に実現可能なのでやってみました。

https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/MultiRegionAccessPoints.html

やってみた

対象 S3 バケットへ AWS CLI コマンドでアクセス可能な状態にすることをゴールとします。
なお既に、閉鎖的な VPC 環境(インターネット接続なし)に配置された EC2 インスタンス (Amazon Linux 2023) が起動中であり、起動中 EC2 インスタンスと異なるリージョンに S3 バケットが存在する前提で進めさせていただきます。

以下が実装の流れです。

  1. マルチリージョンアクセスポイントの作成
  2. S3 インターフェース VPC エンドポイント(com.amazonaws.s3-global.accesspoint) の作成
  3. EC2 インスタンスに関連付けたロールにポリシーを作成~追加

マルチリージョンアクセスポイントの作成

https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/multi-region-access-point-create-examples.html

AWS Management Console にサインインし、Amazon S3 コンソール (https://console.aws.amazon.com/s3/) を開きます。
ナビゲーションペインで、[Multi-Region Access Points] (マルチリージョンアクセスポイント) を選択します。
[マルチリージョンアクセスポイントの作成] を選択して、マルチリージョンアクセスポイントの作成を開始します。
[マルチリージョンアクセスポイント] ページの [マルチリージョンアクセスポイント名] フィールドに、マルチリージョンアクセスポイントの名前を入力します。
このマルチリージョンアクセスポイントに関連付けるバケットを選択します。今回は バージニア北部にある S3 バケットを対象としました。

s3-mraps

その他の設定は行わず、[マルチリージョンアクセスポイントの作成] を選択します。
作成完了まで、暫く待ちます。
作成が完了したら、ARN を控えておきます。こちらを使用してアクセスを行うためです。

s3-mraps-arn

S3 インターフェース VPC エンドポイント(com.amazonaws.s3-global.accesspoint) の作成

AWS PrivateLink で使用するマルチリージョンアクセスポイントの設定 - Amazon Simple Storage Service
https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/MultiRegionAccessPointsPrivateLink.html

必ず com.amazonaws.s3-global.accesspoint エンドポイントを作成してください。他のエンドポイントタイプでは、マルチリージョンアクセスポイントにアクセスできません。

ナビゲーションペインで、[エンドポイント] を選択します。
[エンドポイントを作成] を選択して作成を開始します。

01

中部へスクロールし、サービスのセクションで検索窓に S3 と記載。表示された複数の S3 に関するエンドポイントの中より、com.amazonaws.s3-global.acesspoint を選択します。

02

エンドポイントを作成する VPC を選択し、DNS 名を有効化のチェックボックスにチェックを入れます。
その後、サブネットセクションでは接続元 EC2 インスタンスが存在するサブネットを選択します。
今回は、デフォルトのセキュリティグループで、ポリシーもそのままにして作成します。

03

EC2 インスタンスに関連付けたロールにポリシーを作成~追加

ご自身の環境に合わせて適宜修正のうえ以下のポリシーを作成してください。
作製したポリシーを、EC2 インスタンスに関連付けたロールにアタッチします。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:GetObject",
                "s3:PutObject",
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws:s3::${ACCOUNT_ID}:accesspoint/${MRAP_NAME}",
                "arn:aws:s3::${ACCOUNT_ID}:accesspoint/${MRAP_NAME}/object/*",
                "arn:aws:s3:::${BUCKET_NAME}/*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws:s3:::${BUCKET_NAME}"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:GetMultiRegionAccessPoint",
                "s3:GetMultiRegionAccessPointPolicy",
                "s3:GetMultiRegionAccessPointRoutes",
                "s3:ListMultiRegionAccessPoints"
            ],
            "Resource": "*"
        }
    ]
}

対象 S3 バケットが AWS Key Management Service (KMS) で暗号化されている場合、以下のポリシーを追加してください。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "kms:Decrypt"
            ],
            "Resource": [
                "arn:aws:kms:<リージョン>:<アカウントID>:key/<KMSキーID>"
            ]
        }
    ]
}

これで、実装は終了です。お疲れさまでした!

検証してみた

エンドポイント経由でマネージドノードとして登録している EC2 インスタンス (Amazon Linux 2023) にセッションマネージャーを利用して接続します。
06

07

なお、アクセスするバージニア北部リージョンの S3 バケットには適当なオブジェクト (ファイル) をアップロード済みです。
05

04

バケットの一覧を表示

※ コマンド例

$ aws s3 ls s3://arn:aws:s3::<アカウントID>:accesspoint/<MRAPの名前>/

実行例 ※一部マスクします

$ aws s3 ls s3://arn:aws:s3::xxxxxxxxxxxx:accesspoint/mgayc5xy8tcqm.mrap/
2025-04-06 02:18:25          5 text1.txt
2025-04-06 02:18:25          6 text10.txt
2025-04-06 02:18:25          5 text2.txt
2025-04-06 02:18:25          5 text3.txt
2025-04-06 02:18:25          5 text4.txt
2025-04-06 02:18:27          5 text5.txt
2025-04-06 02:18:27          5 text6.txt
2025-04-06 02:18:27          5 text7.txt
2025-04-06 02:18:27          5 text8.txt
2025-04-06 02:18:27          5 text9.txt

08

S3 オブジェクトをダウンロード

※ コマンド例

$ aws s3 cp s3://arn:aws:s3::<アカウントID>:accesspoint/<MRAPの名前>/<オブジェクトキー> <ローカルファイルパス>

実行例 ※一部マスクします

$ sudo aws s3 cp s3://arn:aws:s3::xxxxxxxxxxxx:accesspoint/mgayc5xy8tcqm.mrap/text7.txt ./s3_downloaded_text7.txt
download: s3://arn:aws:s3::xxxxxxxxxxxx:accesspoint/mgayc5xy8tcqm.mrap/text7.txt to ./s3_downloaded_text7.txt

09

S3 へアップロード

※ コマンド例

$ aws s3 cp <ローカルファイルパス> s3://arn:aws:s3::<アカウントID>:accesspoint/<MRAP名>/<アップロード先パス>

実行例 ※一部マスクします

$ sudo aws s3 cp ./s3_downloaded_text7.txt s3://arn:aws:s3::xxxxxxxxxxxx:accesspoint/mgayc5xy8tcqm.mrap/uploaded_text7.txt
upload: ./s3_downloaded_text7.txt to s3://arn:aws:s3::xxxxxxxxxxxx:accesspoint/mgayc5xy8tcqm.mrap/uploaded_text7.txt
sh-5.2$ aws s3 ls s3://arn:aws:s3::xxxxxxxxxxxx:accesspoint/mgayc5xy8tcqm.mrap/
2025-04-06 02:18:25          5 text1.txt
2025-04-06 02:18:25          6 text10.txt
2025-04-06 02:18:25          5 text2.txt
2025-04-06 02:18:25          5 text3.txt
2025-04-06 02:18:25          5 text4.txt
2025-04-06 02:18:27          5 text5.txt
2025-04-06 02:18:27          5 text6.txt
2025-04-06 02:18:27          5 text7.txt
2025-04-06 02:18:27          5 text8.txt
2025-04-06 02:18:27          5 text9.txt
2025-04-06 04:53:40          5 uploaded_text7.txt

検証では sudo を使用してますが、無くても可能です。

10

11

AWS CLI コマンドの実行に成功しました!

補足

s3api コマンドでも操作可能です。

実行例 ※一部マスクします
 aws s3api list-objects-v2 --bucket arn:aws:s3::xxxxxxxxxxxx:accesspoint/mgayc5xy8tcqm.mrap
{
    "Contents": [
        {
            "Key": "text1.txt",
            "LastModified": "2025-04-06T02:18:25+00:00",
            "ETag": "\"cef7ccd89dacf1ced6f5ec91d759953f\"",
            "ChecksumAlgorithm": [
                "CRC64NVME"
            ],
            "ChecksumType": "FULL_OBJECT",
            "Size": 5,
            "StorageClass": "STANDARD"
        },
        {
            "Key": "text10.txt",
            "LastModified": "2025-04-06T02:18:25+00:00",
            "ETag": "\"64aa080c987473907ed1f2b0f31a954f\"",
            "ChecksumAlgorithm": [
                "CRC64NVME"
            ],
            "ChecksumType": "FULL_OBJECT",
            "Size": 6,
            "StorageClass": "STANDARD"
        },
        {
            "Key": "text2.txt",
            "LastModified": "2025-04-06T02:18:25+00:00",
            "ETag": "\"fe6123a759017e4a2af4a2d19961ed71\"",
            "ChecksumAlgorithm": [
                "CRC64NVME"
            ],
            "ChecksumType": "FULL_OBJECT",
            "Size": 5,
            "StorageClass": "STANDARD"
        },
        {
            "Key": "text3.txt",
            "LastModified": "2025-04-06T02:18:25+00:00",
            "ETag": "\"265246eadd25390e2406a0d9bd22242b\"",
            "ChecksumAlgorithm": [
                "CRC64NVME"
            ],
            "ChecksumType": "FULL_OBJECT",
            "Size": 5,
            "StorageClass": "STANDARD"
        },
        {
            "Key": "text4.txt",
            "LastModified": "2025-04-06T02:18:25+00:00",
            "ETag": "\"2a3def1740220a8312f1d046093437b9\"",
            "ChecksumAlgorithm": [
                "CRC64NVME"
            ],
            "ChecksumType": "FULL_OBJECT",
            "Size": 5,
            "StorageClass": "STANDARD"
        },
        {
            "Key": "text5.txt",
            "LastModified": "2025-04-06T02:18:27+00:00",
            "ETag": "\"48fa2467e5e644c8a594757d255db7eb\"",
            "ChecksumAlgorithm": [
                "CRC64NVME"
            ],
            "ChecksumType": "FULL_OBJECT",
            "Size": 5,
            "StorageClass": "STANDARD"
        },
        {
            "Key": "text6.txt",
            "LastModified": "2025-04-06T02:18:27+00:00",
            "ETag": "\"c39223eba07c4b56829a5f3e1002b240\"",
            "ChecksumAlgorithm": [
                "CRC64NVME"
            ],
            "ChecksumType": "FULL_OBJECT",
            "Size": 5,
            "StorageClass": "STANDARD"
        },
        {
            "Key": "text7.txt",
            "LastModified": "2025-04-06T02:18:27+00:00",
            "ETag": "\"994a8fc3f93e1f30d6b8da85b1a727dd\"",
            "ChecksumAlgorithm": [
                "CRC64NVME"
            ],
            "ChecksumType": "FULL_OBJECT",
            "Size": 5,
            "StorageClass": "STANDARD"
        },
        {
            "Key": "text8.txt",
            "LastModified": "2025-04-06T02:18:27+00:00",
            "ETag": "\"3460f771bb99815edf441d105788831b\"",
            "ChecksumAlgorithm": [
                "CRC64NVME"
            ],
            "ChecksumType": "FULL_OBJECT",
            "Size": 5,
            "StorageClass": "STANDARD"
        },
        {
            "Key": "text9.txt",
            "LastModified": "2025-04-06T02:18:27+00:00",
            "ETag": "\"3effc6913c18e67cdf6392b41c0e5b5c\"",
            "ChecksumAlgorithm": [
                "CRC64NVME"
            ],
            "ChecksumType": "FULL_OBJECT",
            "Size": 5,
            "StorageClass": "STANDARD"
        },
        {
            "Key": "uploaded_text7.txt",
            "LastModified": "2025-04-06T04:53:40+00:00",
            "ETag": "\"994a8fc3f93e1f30d6b8da85b1a727dd\"",
            "ChecksumAlgorithm": [
                "CRC64NVME"
            ],
            "ChecksumType": "FULL_OBJECT",
            "Size": 5,
            "StorageClass": "STANDARD"
        },
        {
            "Key": "uploaded_text8.txt",
            "LastModified": "2025-04-06T04:58:12+00:00",
            "ETag": "\"994a8fc3f93e1f30d6b8da85b1a727dd\"",
            "ChecksumAlgorithm": [
                "CRC64NVME"
            ],
            "ChecksumType": "FULL_OBJECT",
            "Size": 5,
            "StorageClass": "STANDARD"
        }
    ],
    "RequestCharged": null,
    "Prefix": ""
}
(END)

まとめ

ゲートウェイ型のエンドポイントでは、それを作成したリージョンでのみ使用可能であり、S3 バケットと同じリージョンにゲートウェイエンドポイントを作成する必要があり、その対策として冒頭でお伝えした S3 インターフェース VPC エンドポイント + α の構成で実現する必要がありました。
本ブログではこちらに比べても非常に簡単に実現することが可能ですね。本ブログが誰かのご参考になれば幸いです。

https://docs.aws.amazon.com/ja_jp/vpc/latest/privatelink/vpc-endpoints-s3.html

ゲートウェイエンドポイントは、それを作成したリージョンでのみ使用できます。必ず S3 バケットと同じリージョンにゲートウェイエンドポイントを作成してください。

参考資料

アノテーション株式会社について

アノテーション株式会社は、クラスメソッド社のグループ企業として「オペレーション・エクセレンス」を担える企業を目指してチャレンジを続けています。「らしく働く、らしく生きる」のスローガンを掲げ、様々な背景をもつ多様なメンバーが自由度の高い働き方を通してお客様へサービスを提供し続けてきました。現在当社では一緒に会社を盛り上げていただけるメンバーを募集中です。少しでもご興味あれば、アノテーション株式会社WEBサイトをご覧ください。

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.