こんにちは、VPoTの岩本 (iwamot) です。
事情によりパブリックアクセスを有効化していたAmazon RDSのDBインスタンスがあったのですが、パブリックアクセス不要となったため、プライベートサブネットに移行しました。
その際、Egress-Onlyインターネットゲートウェイ (以下、Egress-Only IGW) を活用することで、有料のNATゲートウェイやVPCエンドポイントを追加することなく、移行を完了できました。
本記事では、移行の背景や、実際の移行手順をご紹介します。
移行の背景
まず、移行の背景についてです。
今回、DBをプライベートサブネットに移行しようと思ったのは、パブリックアクセスが不要となったためでした。
パブリックアクセスを有効化していたのは、複数のAWSアカウントにあるLambda関数からアクセスする要件があったからです。VPCピアリングなどで対応する手もありますが、IAM認証のみ許可すれば大丈夫と考え、シンプルなパブリックアクセスを選んだ形です。
その後、要件が変わり、DBと同じアカウントにあるLambda関数からのみアクセスできればOKとなりました。プライベートサブネットに移行できるチャンスが来たわけです。
サービスエンドポイントへの接続をどうするか
ただ、DBをプライベートサブネットに移行するには、越えなければならないハードルがひとつありました。「Lambda関数からAWSサービスエンドポイントへの接続をどうするか」です。
対象のLambda関数は、DBだけでなく、AWSサービスエンドポイントにもアクセスする必要があります。具体的にはAthena、STS、CloudWatchです。
Lambda関数にVPCをアタッチすれば、プライベートサブネットのDBにアクセス可能にはなります。が、一方で、サービスエンドポイントへの経路が断たれてしまいます。
このとき、ぼくの頭にまず浮かんだのは、有料のNATゲートウェイやVPCエンドポイントを使う方法でした。しかし、できればコストを追加せずに移行したいところです。
Egress-Only IGWならコスト増なく対応できる
しばらく考えて思いついたのが、今回の主役、Egress-Only IGWでした。Egress-Only IGWには、以下の特徴があります。
- IPv6トラフィックでのみ使用される
- VPCからインターネットへの送信が可能(インターネットからは通信を開始できない)
- 課金されない
つまり、アクセス先のAWSサービスエンドポイントがIPv6に対応していれば、VPCをアタッチしたLambda関数から無料で接続できるということです。
サービスエンドポイントのIPv6対応状況は、こちらのドキュメントで公開されています。
AthenaもSTSもCloudWatchもIPv6をサポートしているので*1、以下の構成に移行可能なはずです。
| 項目 | 移行前 | 移行後 |
|---|---|---|
| DBインスタンス | パブリックサブネット | プライベートサブネット |
| Lambda → DB | インターネット | VPC内 |
| Lambda → AWSサービス | IPv4 | IPv6 (Egress-Only IGW経由) |
実際の移行手順
ゴールが決まったので、以下の手順で移行を進めました。
- VPCにIPv6サポートを追加
- Lambda関数の設定を変更
- DBをプライベートサブネットに移行
- 不要になったリソースを削除
1. VPCにIPv6サポートを追加
まず、VPCにIPv6サポートを追加しました。CIDRブロックの関連付けや、ルートテーブルの更新などです。詳しくはドキュメントをご参照ください。
2. Lambda関数の設定を変更
次に、Lambda関数の設定を変更しました。要点は以下のとおりです。
- セキュリティグループでIPv6 egressを許可
- 環境変数で
AWS_USE_DUALSTACK_ENDPOINT=trueを指定(参考) - VPCをアタッチ。「デュアルスタックのサブネットの IPv6 トラフィックを許可」を有効化(参考)
環境変数については、Lambda関数で利用しているboto3に対し、IPv4・IPv6デュアルスタックなサービスエンドポイントへのリクエストを送信させる意図です。
3. DBをプライベートサブネットに移行
続いて、DBをプライベートサブネットに移行しました。ここが本丸です。
簡単に移行できるものと思っていたのですが、パブリックサブネットにあるDBをプライベートサブネットに直接移行することはできず、少し手間がかかりました。
具体的には「マルチAZを無効化 → サブネットグループを編集 → マルチAZを有効化 → ...」といった手順を踏む必要があります。詳しくはこちらの記事をご参照ください。
移行後、DBのセキュリティグループを編集しました。
- 移行前:
0.0.0.0/0からのアクセスを許可 - 移行後:Lambda関数のセキュリティグループからのアクセスを許可
4. 不要になったリソースを削除
最後に、不要となったパブリックサブネットや、通常のインターネットゲートウェイを削除しました。これで作業完了です。
まとめ
以上、Egress-Only IGWを活用することで、コスト増なしにRDSをプライベート化した事例をご紹介しました。実務で初めて扱えたので、よい機会となりました。
今回はLambdaでしたが、ECSなど別のサービスでも応用できそうな印象です。もちろん、アクセス先がIPv6に対応している前提とはなります。
コストとセキュリティを天秤にかけてパブリックサブネットを選んでいる場面では、Egress-Only IGWが救世主となるかもしれません。検討してみてはいかがでしょうか。
*1:STSのグローバルサービスエンドポイントはIPv6には対応していません。リージョナルエンドポイントの利用が前提です。