AWS PrivateLink が Amazon S3 に対応!何が嬉しいのか


はじめに

2021/2/2 のアップデートで AWS PrivateLink 経由で Amazon S3 にアクセスできるようになりました。

AWS PrivateLink for Amazon S3 is Now Generally Available
https://aws.amazon.com/jp/blogs/aws/aws-privatelink-for-amazon-s3-now-available/

これまでの Gateway 型 VPC エンドポイントと比較して何が嬉しく、どのような点に注意すべきか記載します。

嬉しい点

オンプレミスからのアクセス

なんと言ってもこの点が待望だったかと思います。
Gateway 型の場合、S3 のエンドポイントはグローバル IP アドレスのままです。
VPC 内の S3 に対する通信を、ルートテーブルの設定で VPC エンドポイントに向けることにより
AWS NW の外 (インターネット) には出ない形で通信を行います。

この仕様上、AWS Direct Connect や VPN を使用して接続されたオンプレミス環境から
直接 S3 と通信することはできませんでした。
ではこれまでどうしていたかというと、EC2 にプロキシサーバーたてて対応することがありました。
当然のことながら、このプロキシサーバーの稼働コスト、メンテナンスコストが発生します。

AWS PrivateLink による Interface 型の エンドポイントは VPC に エンドポイント用の ENI が作成されます。
ENI に割り当てられた プライベートIP を使用して、オンプレミス環境から S3 へ
直接プライベート接続することができます!

他 VPC や別のリージョンからのアクセス

考え方としてはオンプレミスと同じです。
エンドポイントに払い出された VPC のプライベート IP を介してアクセスするため
例えば VPC Peering で接続された他リージョンの VPC からもアクセスすることができます。

1つのエンドポイントで、任意のリージョンの S3 バケットにアクセスできるわけはありません。
Gateway 型の VPC エンドポイントと同様、アクセスする S3 バケットは
同じリージョンに存在する必要があります。東京リージョンの VPC および VPC エンドポイントからは
東京リージョンに存在する S3 バケットにのみアクセスできます。

Gateway 型 と Interface 型エンドポイントの併用

S3 の Gateway 型エンドポイントと Interface 型エンドポイントは併用が可能です。
VPC 上のアプリケーションは これまで通り Gateway 型エンドポイントを使用し、
オンプレミスアプリケーションは Interface 型エンドポイントを使用するといった構成が可能です。

後述のとおり、Interface 型エンドポイントはデータ転送料金やエンドポイント URL の変更などを
考慮しなければならないため、この構成にはメリットがあります。

考慮すべき点

利用料金

Gateway 型の VPC エンドポイントは無料で利用することができましたが、
Interface 型の VPC エンドポイントは エンドポイント 1 つあたりの料金 (USD/時間) および
処理データ 1 GB あたりの料金 (USD) が発生します。

2021/2/3 時点で、東京リージョンの場合は以下のコストが発生します。

VPC エンドポイント 1 つあたりの料金 (USD/時間) 処理データ 1 GB あたりの料金 (USD)
0.014 USD 0.01 USD

3 AZ で冗長構成をとる場合、エンドポイントの時間料金が3つ分発生します。
1 GBあたりのデータ転送料金もそれほど高額ではありませんが、大量のデータをやり取りする場合は
料金について予め考慮が必要でしょう。

エンドポイントの指定

S3 の Interface 型エンドポイントはプライベート DNS 機能をサポートしていません。
エンドポイント作成画面でもチェックボックスがグレーアウトされています。

プライベート DNS 機能とはサービスのデフォルト DNS 名 (ex. ec2.ap-northeast-1.amazonaws.com) を
VPC のエンドポイントに割り当てられたプライベート IP アドレスに解決してくれる機能です。
これにより Route 53 Resolver (以前の Amazon Provided DNS) を使用している VPC や
Route 53 Resolver for Hybrid Clouds を使用しているオンプレミス環境ではアプリケーション側の
変更を必要とせず、デフォルトの DNS ホスト名を使用して VPC エンドポイントに対して
リクエストを送信することができます。

この機能を使用することができないため、PrivateLink を使用して S3 にアクセスするには
以下のように VPC エンドポイントに払い出された固有の DNS 名を使用する必要があります。

例えば AWS CLI の場合は以下のようになります。

$ aws s3 ls s3://my-bucket/ --endpoint-url https://bucket.vpce-1a2b3c4d-5e6f.s3.ap-northeast-1.vpce.amazonaws.com

AWS SDK (boto3) を使用したアプリケーションの場合。

import boto3

s3_client = boto3.client(
    's3',
    endpoint_url = 'https://bucket.vpce-1a2b3c4d-5e6f.s3.ap-northeast-1.vpce.amazonaws.com'
)

サブドメインに bucket を指定するのは、S3 バケットに関連する API 操作を行う場合です。
(指定するのはバケット名ではないことに注意してください。)
操作対象の API によってサブドメインを変える必要があります。

API操作 エンドポイント例
バケット bucket.vpce-1a2b3c4d-5e6f.s3.ap-northeast-1.vpce.amazonaws.com
アクセスポイント accesspoint.vpce-1a2b3c4d-5e6f.s3.ap-northeast-1.vpce.amazonaws.com
S3 Control control.vpce-1a2b3c4d-5e6f.s3.ap-northeast-1.vpce.amazonaws.com

例えばエンドポイントのプライベート IP などを直に指定すると、SSL validation failed が発生します。

$ aws s3 ls --endpoint-url https://xxx.xxx.xxx.xxx
SSL validation failed for https://xxx.xxx.xxx.xxx/ ("hostname 'xxx.xxx.xxx.xxx' doesn't match either of 's3.ap-northeast-1.amazonaws.com', 
'*.accesspoint.vpce-1a2b3c4d-5e6f-ap-northeast-1d.s3.ap-northeast-1.vpce.amazonaws.com', 
'*.control.vpce-1a2b3c4d-5e6f-ap-northeast-1a.s3.ap-northeast-1.vpce.amazonaws.com', 
'*.accesspoint.vpce-1a2b3c4d-5e6f.s3.ap-northeast-1.vpce.amazonaws.com', 'bucket.vpce-1a2b3c4d-5e6f-ap-northeast-1a.s3.ap-northeast-1.vpce.amazonaws.com', 
'*.s3-control.ap-northeast-1.amazonaws.com', '*.control.vpce-1a2b3c4d-5e6f-ap-northeast-1d.s3.ap-northeast-1.vpce.amazonaws.com', 
'*.s3.ap-northeast-1.amazonaws.com', '*.s3-accesspoint.ap-northeast-1.amazonaws.com', '*.control.vpce-1a2b3c4d-5e6f.s3.ap-northeast-1.vpce.amazonaws.com', '*.bucket.vpce-1a2b3c4d-5e6f-ap-northeast-1d.s3.ap-northeast-1.vpce.amazonaws.com', 
'bucket.vpce-1a2b3c4d-5e6f-ap-northeast-1c.s3.ap-northeast-1.vpce.amazonaws.com', 'bucket.vpce-1a2b3c4d-5e6f.s3.ap-northeast-1.vpce.amazonaws.com',
'*.control.vpce-1a2b3c4d-5e6f-ap-northeast-1c.s3.ap-northeast-1.vpce.amazonaws.com', '*.bucket.vpce-1a2b3c4d-5e6f.s3.ap-northeast-1.vpce.amazonaws.com', '*.accesspoint.vpce-1a2b3c4d-5e6f-ap-northeast-1c.s3.ap-northeast-1.vpce.amazonaws.com', 
'*.bucket.vpce-1a2b3c4d-5e6f-ap-northeast-1c.s3.ap-northeast-1.vpce.amazonaws.com', 
'bucket.vpce-1a2b3c4d-5e6f-ap-northeast-1d.s3.ap-northeast-1.vpce.amazonaws.com', 
'*.accesspoint.vpce-1a2b3c4d-5e6f-ap-northeast-1a.s3.ap-northeast-1.vpce.amazonaws.com', 
'*.bucket.vpce-1a2b3c4d-5e6f-ap-northeast-1a.s3.ap-northeast-1.vpce.amazonaws.com'",)

実験: アプリケーションが エンドポイント URL の変更に対応していなかったら?

VPC エンドポイントに払い出されたプライベート IP アドレスを hosts に設定し、ローカルで
デフォルトの DNS 名を強制的に上書きしたところ、バケットレベルの操作は行うことができました。

xxx.xxx.xxx.xxx s3.ap-northeast-1.amazonaws.com
xxx.xxx.xxx.xxx <bucket-name>.s3.ap-northeast-1.amazonaws.com
$ aws s3 ls
$ aws s3 ls s3://my-bucket/

ただこのような使い方はドキュメントには記載がなく、AWS 的にサポートされるかは不明です。
そもそも hosts を使用する場合は、

  • VPC エンドポイントの冗長構成がとれない
  • バケット毎に DNS 名を追加する必要がある

などデメリットが多いですので、参考程度にお願いします。

ドキュメント

Amazon S3 and interface VPC endpoints (AWS PrivateLink)
https://docs.aws.amazon.com/AmazonS3/latest/userguide/privatelink-interface-endpoints.html

以上です。
参考になれば幸いです。
Happy storing!