EC2 からのプライベート RDS:同じ VPC、peering、それとも別の方法?
セキュリティグループより先に経路を選びます。同じ VPC、peering、共有 VPC、プライベート相互接続のいずれかです。
開発者のノート PC は社員 VPN 経由でプライベート RDS インスタンスに到達しますが、EC2 上のアプリケーションはまったく接続できません。これは壊れたデプロイではありません。ノート PC には EC2 インスタンスが決して継承しないトンネルがあり、RDS における「プライベート」とはデータベースにパブリックエンドポイントがないという意味であり、人間の VPN 利用者だけが許可された呼び出し元という意味ではありません。アプリケーションには独自の承認された経路、独自のセキュリティグループとの関係、独自のデータベース ID が必要であり、この三つを選ぶ順序がデバッグの大半を節約します。まず経路を決め、次に権限を決め、最後に自分の机ではなくデプロイ済み環境から検証してください。
ノート PC の VPN はアプリケーションの経路ではない
社員 VPN が人間に対して何をするにしても、インスタンスが同じネットワーク経路の一部であると明示されていない限り、インスタンスには何も行いません。プライベートサブネット内の EC2 インスタンスは、VPC ルーティング、セキュリティグループ、ネットワーク ACL を通じて RDS に到達します。人間のトンネル、人間のセッション、人間の認証情報を継承することはなく、継承すべきでもありません。無人で動作するアプリケーション接続と社員のリモートアクセスは、独立して運用できる必要があります。
この独立性は利点です。VPN が停止してもアプリケーションは動き続けます。アプリケーションに問題が起きても、誰もリモートアクセスを失いません。両者を一つの経路に統合する設計は、たいていインシデントの最中、最悪のタイミングで発見されます。
判断 1:同じ VPC、直接経路
アプリケーションとデータベースが同じ VPC にあり、直接ルーティングで間に検査用ミドルボックスがない場合、経路は単純で、セキュリティグループ参照が利用できる最も強力な手段です。アプリケーションに専用のグループを与え、アドレス範囲ではなくそのグループからデータベースのポートを許可します。
aws ec2 authorize-security-group-ingress --group-id sg-0db123 --protocol tcp --port 5432 --source-group sg-0app456
aws rds describe-db-instances --db-instance-identifier prod-db --query 'DBInstances[0].{Endpoint:Endpoint.Address,Port:Endpoint.Port,Public:PubliclyAccessible,Groups:VpcSecurityGroups}'
ポートは例であり、エンジンに合わせる必要があります。グループ参照はアプリケーションのインスタンスからのトラフィックを許可しますが、そのルールをコピーするわけでも、データベースのログインを作成するわけでもありません。二つの別問題には 二つの別の修正があります。
次に、追加したルールで止まらず経路の残りを確認します。アプリケーションの送信ポリシー、データベースに付与されたグループの完全な集合、サブネットのルートテーブル、ネットワーク ACL のすべてが一致している必要があります。セキュリティグループのルールはステートフルですが、カスタムネットワーク ACL は要求と戻りトラフィックを別々のルールで許可する必要があり、一時ポートも含みます。狭い新しいデータベースルールは、すでに付与されていた古い広い許可を打ち消すものでもありません。
判断 2:別の VPC または別のアカウント
アプリケーションが別の VPC にある場合、ネットワーク所有者はサポートされたプライベート相互接続を選びます。peering、トランジット設計、共有 VPC の取り決めです。その場合、両方向のルーティングが存在する必要があり、名前解決が RDS エンドポイントで機能する必要があり、データベースポリシーが評価する送信元が実際に到着するものと一致する必要があります。アカウント名の一致や共有の請求関係は、そのどれも提供しません。
セキュリティグループ参照は変化する部分です。いくつかのプライベート相互接続設計では機能しますが、ミドルボックスが送信元を書き換えたり接続を終端したりした瞬間に機能しなくなります。データベースはアプリケーションのグループではなくミドルボックスを見るからです。RDS VPC のシナリオは、同じ VPC 内のアクセスと他の構成を区別しており、ルールのスタイルがそのまま通用すると仮定する前に、固有のトポロジーをこれらと照合する価値があります。
不足している経路を、データベースをパブリックに公開して解決しないでください。それは別の所有者による別の公開判断であり、通常は結果から最も遠い人が提案します。
判断 3:データベースが受け入れる ID
ネットワークアクセスとデータベース認証は別の層であり、混同すると最も誤解を招くエラーが生まれます。インスタンスロールは AWS API を呼び出すための AWS ID であり、データベースユーザーではありません。IAM データベース認証はエンジンと設定が許す場合にサポートされる機能であり、データベースユーザーへのマッピングであって、その代替ではありません。
アプリケーションの設定では、一度の検索で得たアドレスではなく RDS エンドポイント名を使ってください。Multi-AZ のフェイルオーバーはその名前の背後のアドレスを変えるため、IP に固定されたアプリケーションは必要なまさにその瞬間に失敗します。エラーを消すためにエンジンの TLS 検証を無効にするのではなく有効のままにしてください。検証の失敗は到達したエンドポイントについて何かを伝えています。
次に、アプリケーションが必要とする最小限の権限を、実際に使うスキーマでデータベースアカウントに付与します。この作業は地味で、監査可能で、インシデントレビューが必ず尋ねる部分です。
デプロイ済み環境から検証する
インスタンスから、または同じグループ、サブネット、ロールで動くタスクからテストします。四つの失敗はノート PC からは同じに見えますが、そこからは簡単に区別できます。解決しない名前、タイムアウトする接続、TLS 検証の失敗、拒否されたデータベースログインです。それぞれが異なる境界を指しており、どれなのかを知る前にデータベースの公開範囲を変えるのは当て推量です。
psql "host=prod-db.abc123.eu-west-1.rds.amazonaws.com port=5432 dbname=app sslmode=verify-full" -c 'select 1'
インスタンスからは成功し自分の机から失敗するなら、アプリケーションの経路は問題なく、直すべきは自分のアクセスです。両方から失敗するなら、認証情報ではなく上記のグループと経路の確認から始めてください。この一つの比較が、こうしたチケットが生む混乱の大半を防ぎます。