マネージドサービス部 佐竹です。
AWS Transit Gateway (TGW) を利用した複数 VPC での集約設定を解説するネットワークブログの第3弾として、Interface 型 VPC Endpoint の集約を行う方法について記載します。
はじめに
まず最初に AWS Transit Gateway を利用して NAT Gateway を集約するための実装方法を以下のブログに記載しました。
本ブログにおける設計及び実装は、全 VPC がフルメッシュでお互いに疎通可能になっています。しかしそれが許容されない場合もあるでしょう。
先のブログの続きとなる第2弾では、NAT Gateway を集約した環境下で TGW の Blackhole Route による経路制御を利用し、特定の VPC だけを疎通不可にする方法について記載しました。
前提となるネットワーク設計
本ブログは第3弾であり、先の2つのブログの続編となります。このため、前提となるネットワーク設計はブログ第2弾の最後の状態となります。
構成図は上図の通りであり、ネットワーク要件は以下の通りです。
- 「VPC A」⇔「VPC B」同士の接続が可能
- 「VPC A」⇔「VPC C」同士の接続は不可能
- 「VPC B」⇔「VPC C」同士のローカル IP での接続は不可能、ただし「VPC C」から「VPC B」の NAT Gateway へは接続が可能
今回、この状況下から Interface 型 VPC Endpoint の集約を NAT Gateway と同様に「VPC B」に行います。
Interface 型の VPC Endpoint の利用料について
AWS でマルチアカウントを運用していると、第1段でご紹介した NAT Gateway 以上にコストインパクトが大きくなってしまうことがあるのが VPC Endpoint の利用料です。
上記公式ドキュメントから引用しますと「インターフェイスエンドポイントの料金」は「各 AZ の VPC エンドポイント 1 つあたりの料金 (USD/時間)」として $0.014/h が発生します*1。NAT Gateway と同様に、アベイラビリティゾーン(AZ)ごとの課金となるため、AZ 別に作成すると2倍、3倍となります。
2つの AZ で利用する場合、1つのインターフェイスエンドポイントは単純計算で年間「$0.014 * 2 AZ * 24 * 365 = $245.28」の保持費用がかかります。
注意が必要なのは、これは「1つのインターフェイスエンドポイント」の年間利用料という点です。
今現在で、187種類の VPC Endpoint が作成可能です。うち2つ(S3 と DynamoDB)は Gateway 型であり無料のため、実質185種類を作成する可能性があります。ただし利用する用途に応じて構築すればよいため、185種全てを構築する必要はありません。
以下に私の経験上、良く作成される Interface 型の VPC Endpoint を一覧にしました。
- com.amazonaws.ap-northeast-1.ec2
- com.amazonaws.ap-northeast-1.ec2messages
- com.amazonaws.ap-northeast-1.ssm
- com.amazonaws.ap-northeast-1.ssmmessages
- com.amazonaws.ap-northeast-1.logs
- com.amazonaws.ap-northeast-1.monitoring
- com.amazonaws.ap-northeast-1.events
- com.amazonaws.ap-northeast-1.kms
- com.amazonaws.ap-northeast-1.lambda
- com.amazonaws.ap-northeast-1.sqs
- com.amazonaws.ap-northeast-1.sns
仮に、これら11個のインターフェイスエンドポイントを全て作成したとします。この場合「構築して保持しているだけ」でかかる年間の費用が「$0.014 * 2 AZ * 24 * 365 * 11 Endpoint= $2,698.08」まで増えてしまいます。
そして、AWS アカウントが仮に100アカウントあり、各アカウントで11個のインターフェイスエンドポイントを作った場合この費用が100倍になってしまいます。その費用は年間「$269,808」にまで増え、現在の為替レート(150円換算)でおおよそ4,000万円を越えます。
実際に、マルチアカウントの運用をされている大規模なユーザ様でインターフェイスエンドポイントの年間利用料が数百万、数千万という実例を目にしたこともあります。「全ての AWS アカウントに VPC Endpoint を作成する」というのは、コスト最適化の観点からお勧めできない設計です。
さて、こうなってくるとインターフェイスエンドポイントなど不要なのでは?という話があるかもしれません。確かに、設計上不要であれば作成しなければいいのですが、セキュリティ等の観点から必須としているユーザ様もいらっしゃいます。
何故それでも VPC Endpoint を作成したほうが良いのか
では、何故それでも VPC Endpoint を作成したほうが良いという話が出てくるのか(コスト最適化の観点で)考えてみます。
結論から記載しますと、これは NAT Gateway と VPC Endpoint の通信料金の違いによるものです。
VPC Endpoint を作成しないということは、AWS の各サービスを利用するときに、基本的には NAT Gateway を通過してインターネットへ出てから、AWS のグローバルなエンドポイントへアクセスするという経路になります。そうなってくると気になるのは通信料で、AWS の料金ページに「処理データ料金」と記載のある費用が関係してきます。
それぞれの処理データ料金を比較してみます。
- NAT Gateway の処理データ 1 GB あたりの料金 (USD):
0.062USD
- VPC Endpoint の処理データ 1 GB あたりの料金 (USD):
0.010 USD
※最初の 1 PB
ご覧の通り「NAT Gateway > VPC Endpoint」であり、その費用の差は6.2倍です。つまりは AWS サービス間の通信では NAT Gateway ではなく VPC Endpoint を通過させることで費用が「10/62(≒84%オフ)」にできるということです。
特に CloudWatch Logs 等の一部のサービスでは、処理データ費用が嵩むことが多いため VPC Endpoint を経由させることでコストメリットが出ます。
仮に、CloudWatch Logs だけ VPC Endpoint を経由させる場合を考えてみましょう。まず VPC Endpoint の1日(24時間)の保持費用は「$0.014 * 2 AZ * 24 = $0.672」になります。これに加えて、$0.010/GB の費用が発生します。ですので「$0.672 + $0.010 * データ容量」が計算式になります。これが、NAT Gateway の「$0.062 * データ容量」よりも安くなれば元が取れる計算になります。これらの計算式が一致する値を算出すると、そのデータ容量は「0.672/0.052 = 12.9230769 GB」となるため、おおよそ1日あたり 13 GB 程度の通信量がある場合は、VPC Endpoint に集約するコストメリットが出てくるでしょう。
そういうわけで、コスト最適化の観点からみても VPC Endpoint を適切に作成する方が良い場合があります。
Interface 型 VPC Endpoint を集約し、コストを最適化する
ではここから、具体的に集約する手順をご紹介します。
再掲ですが、前提となるネットワーク構成は上図の通りです。
Interface 型 VPC Endpoint の作成
まずは集約用の VPC となっている「VPC B」において VPC Endpoint を作成する Subnet を決定します。
TGW Attachment の ENI はそれ専用の Subnet を用意すると決めたため 10.10.21.64/27
と 10.10.21.96/27
は利用ができません。よって今回は、中央にある Private Subnet 10.10.21.0/27
と 10.10.21.32/27
に VPC Endpoint の作成を行います。
マネジメントコンソール「VPC > Endpoints > Create endpoint」から作成を行っていきます。
Service は今回、例として com.amazonaws.ap-northeast-1.monitoring
を選択します*2。
VPC の設定においては「Additional settings」を開き、「Enable DNS name」のチェックを外します。これは基本的にはチェックしておいていいものなのですが、この後の Route 53 の作業でエラーになってしまうため今回は外す必要があります。
Interface 型 VPC Endpoint は ENI が作成されるため、Security Group が必須です。適切な Security Group を付与してください*3。あとは「Create endpoint」を押下し作成を完了します。
少し待つと VPC Endpoint が作成されます。
念のため詳細で、「Private DNS names enabled」が「No」となっているか確認しておきます。
また、「DNS names」は後から利用するためメモしておきます。今回は vpce-07caf4042dac42093-k4mpf7pk.monitoring.ap-northeast-1.vpce.amazonaws.com
となります。AZ 別の DNS 名もその下に2つそれぞれ出力されますがこれらは今回は不要です。
現時点での構成図は上図の通りです。
Private DNS names enabled を後から「No」に変更するには
既存の VPC Endpoint において「Yes」になっている場合は、Actions の「Modify private DNS name」を利用することで、作成後に「No」へと設定変更することも可能です。
現状の名前解決の結果を確認する
ここで試しに nslookup を行ってみます。
「VPC B」の Route 53 Resolver(Amazon Provided DNS)は 10.10.20.2
になるため、これを明示的に与えて名前解決をしてみます。
$ nslookup monitoring.ap-northeast-1.amazonaws.com 10.10.20.2 Server: 10.10.20.2 Address: 10.10.20.2#53 Non-authoritative answer: Name: monitoring.ap-northeast-1.amazonaws.com Address: 52.119.218.154
名前解決がプライベート IP ではなく、グローバル IP になっています。
これは「Private DNS names enabled」を「No」にしているためです。現状はこの状態で問題ありません。
Route 53 Private Hosted Zone の実装
続いて Route 53 Private Hosted を実装します。この設定を行うことで「VPC A」「VPC B」「VPC C」全てで VPC Endpoint を共通して名前解決が可能となります。
「Route 53 > Hosted zones > Create hosted zone」から作業を行います。
Domain name には monitoring.ap-northeast-1.amazonaws.com
を記載します。続けて Typeは「Private hosted zone」を選択します。
「VPCs to associate with the hosted zone」でこの Route 53 Private Hosted Zone を紐づける VPC を選択します。対象とする VPC は後から追加も可能ですが、ここで 「VPC A」「VPC B」「VPC C」を全て選択します。
最後に「Create hosted zone」を押下して完了します。
Private Hosted Zone の作成が完了しました。
AWS アカウントを跨ぐ場合
AWS アカウントを跨いで Private Hosted Zone を各 VPC へと関連付けるには、マネジメントコンソールでは不可能なため AWS CLI 等での作業が必要です。
詳しくは AWS 公式ドキュメントに記載がありますが、create-vpc-association-authorization と associate-vpc-with-hosted-zone を実行ください。
またこの時「Hosted zone ID」を利用しますが、これはマネジメントコンソールから確認が可能です。
レコードの追加
次に Alias レコードを1行追加します。
コンソールより「Create record」を押下して作業します。
「Alias」にチェックを入れ、「Alias to VPC endpoint」「Asia Pacific (Tokyo)」と選択した後、先ほどメモした VPC Endpoint の DNS name を選択します。その後「Create records」を押下して作業を完了します。
この設定により、本 Private Hosted Zone が関連付けられた全ての VPC で monitoring.ap-northeast-1.amazonaws.com
の名前解決先が VPC Endpoint の ENI になりました。なお、本設定の反映には数分かかるため、この後の動作確認で名前解決ができない場合少し待ってみると良いでしょう。
現時点の状態を構成図にすると上画像の通りです。
現状の名前解決の結果を確認する 2
再度ここで、「VPC C 1a Instance」内部からの名前解決を確認します。
$ nslookup monitoring.ap-northeast-1.amazonaws.com Server: 10.10.30.2 Address: 10.10.30.2#53 Non-authoritative answer: Name: monitoring.ap-northeast-1.amazonaws.com Address: 10.10.21.58 Name: monitoring.ap-northeast-1.amazonaws.com Address: 10.10.21.6
「VPC C 」の Route 53 Resolver(Amazon Provided DNS)は 10.10.30.2
です。問題なく名前解決ができており、「VPC B」に構築した Interface 型 VPC Endpoint のプライベート IP が返却されています。
Transit Gateway とルートテーブルの設定変更
これで作業は完了しているように見えるのですが、実際の通信を鑑みると VPC Endpoint の各 ENI への経路が正しくない点が2つあります。
1つは VPC Subnet のルートテーブル、もう1つは TGW のルートテーブルです。
まず「VPC A」から「VPC B」にある VPC Endpoint を参照する経路を考えてみると、「行き」の経路には問題がありません。ですが「戻り」側、つまり VPC Endpoint が作成されている Private Subnet のルートテーブルに不備があります。
また「VPC C」から「VPC B」にある VPC Endpoint を参照する経路では、そもそも「Blackhole Route」に阻まれてしまい「VPC C から出て行く」ことができません。
これらを順に修正します。
VPC Subnet のルートテーブルを修正する
Subnet のルートテーブルに経路を追加し、「VPC A」と「VPC C」共に TGW への戻りを記載します。
構成図に反映すると上図の通りです。
これで「VPC A」は VPC Endpoint と「戻り」含めて疎通が可能となりました。次は「VPC C」です。
TGW のルートテーブルを修正する
TGW のルートテーブルに経路を追加し、VPC Endpoint の存在する「VPC B」の Subnet の CIDR (10.10.21.0/27
と 10.10.21.32/27
) をそれぞれ Static で記載します*4。
再度、本設定を構成図に反映しています。
「Blackhole Route」によってドロップされる経路よりも、より詳細な(狭い)CIDR がロンゲストマッチにより優先されるためこの記載を行うことで「VPC C」から「VPC B」にある VPC Endpoint を参照することが可能になります。
これにて全作業が完了しました。次は動作確認です。
VPC Endpoint を利用できているか確認する
今回構築した monitoring.ap-northeast-1.amazonaws.com
の VPC Endpoint を正しく利用できているのかどうか、CloudTrail のログで確認してみます。
まず「VPC C 1a Instance (10.10.31.8)」に Session Manager でログインした後 describe-alarms
等のコマンドを AWS CLI で実行します。そしてその結果を CloudTrail で確認します。
JSON を確認すると「"vpcEndpointId": "vpce-07caf4042dac42093"」が表示されている通り、今回作成した VPC Endpoint を正しく経由していることがわかります。
トラブルシューティング
もし Transit Gateway の経路が不足した場合
「TGW のルートテーブルを修正する」で Static Route を追記していますが、もしこれを怠った場合どうなるでしょうか?
Systems Manager における aws ssm list-commands
は VPC Endpoint を作成していないため、正しく実行された後に権限不足のエラーが出ています。
しかし CloudWatch における aws cloudwatch describe-alarms
では結果が全く返って来ず固まってしまいました。数分待ったのですが、タイムアウトもしないようです。
Private DNS names enabled を Yes のまま Private Hosted Zone を作成した場合
VPC Endpoint 作成時に Private DNS names enabled を Yes のまま後続の処理である Route 53 Private Hosted Zone を作成しようとすると、以下のエラーが発生します。
Error occurred
Bad request.
(ConflictingDomainExists 400: The VPC vpc-0c7b663bff40b0719 in region ap-northeast-1 has already been associated with the hosted zone Z06587331KBCKO5AZNSGN with the same domain name.)
これを回避するには、予め VPC Endpoint の Private DNS names enabled を No に変更した後に Private Hosted Zone を作成してください。
まとめ
本ブログでは、AWS Transit Gateway (TGW) を利用した複数 VPC での集約設定を解説するネットワークブログの第3弾として、Interface 型 VPC Endpoint の集約を行う方法について記載しました。
ご紹介した通り、Interface 型 VPC Endpoint の集約設定には Route 53 Private Hosted Zone も合わせて設定する必要があります。
また、VPC Subnet と TGW のルートテーブルがそれぞれ正しく設定されていない場合に、作成された VPC Endpoint と疎通ができないため、その経路の修正方法についても解説しました。
ここまで3連続で投稿してきましたネットワークを題材としたブログも、一旦これで完了となります。長文のブログばかりでしたがお付き合いありがとうございました。
では、またお会いしましょう。
*1:他にも通信料が発生するのですが、今回は「保持しているだけで発生してしまう」利用料にフォーカスします。
*2:monitoring は CloudWatch の Endpoint です https://docs.aws.amazon.com/general/latest/gr/cw_region.html
*3:今回は Inbound に All traffic の 10.0.0.0/8 を許可しており、Outbound は空としています
*4:「VPC B」全体を Propagation しても良いのですが、今回は VPC Endpoint のある Subnet のみとしました
佐竹 陽一 (Yoichi Satake) エンジニアブログの記事一覧はコチラ
マネージドサービス部所属。AWS資格全冠。2010年1月からAWSを利用してきています。2021-2022 AWS Ambassadors/2023-2024 Japan AWS Top Engineers/2020-2024 All Certifications Engineers。AWSのコスト削減、最適化を得意としています。