AWS SQL Server 構築チュートリアル応用:RDS Proxy
RDS for SQL Server の基本構築に続き、最後の一歩として RDS Proxy を整理します。Secrets Manager、IAM ロール、Proxy 作成、SQL Server パスワード認証、IAM 認証、Terraform 例まで扱います。
前回までの 2 つの記事では、RDS for SQL Server の基本構築 と 監査設定およびパスワードローテーション を扱いました。ここまでで、データベースへ接続でき、バックアップでき、監査でき、パスワードも Secrets Manager で管理できる状態になっています。
ただし、まだ 1 つ残っている問題があります。アプリケーションとデータベースの間にある「接続」そのものです。
よくある状況は次のようなものです。
- アプリケーションを再デプロイしたり水平スケールしたりすると、一瞬で大量の新規接続が作られ、データベースの接続数を使い切ってしまう。
- Lambda やコンテナのようなライフサイクルの短いコンピューティングリソースでは、実行ごとに新しい接続を作成し、データベース側のリソースの多くが接続の確立と解放に使われてしまう。
- マイクロサービス化後、各サービスが水平スケールする。各アプリケーションに Connection Pool があっても、サービス間で接続プールは共有されないため、結果的にデータベースが圧迫される。
これらに共通しているのは、データベース接続を「アプリケーション側でうまく処理すべきもの」として扱っている点です。RDS Proxy は、この部分を AWS のマネージドレイヤーへ移すためのサービスです。
RDS Proxy とは
RDS Proxy は AWS が提供するフルマネージドなデータベース接続プロキシです。アプリケーションは RDS endpoint に直接接続するのではなく、Proxy endpoint に接続します。Proxy はデータベースへの接続プールを維持し、複数のアプリケーション接続の間でデータベース接続を共有します。これを multiplexing と呼びます。
主に次の問題を解決します。
| 機能 | 説明 |
|---|---|
| 接続プール化 | Proxy がデータベースとの長時間接続を維持するため、アプリケーション側の大量の短時間接続がデータベースへ直接影響しにくくなる |
| failover 中断の短縮 | failover 時に Proxy がアプリケーション側の接続を保持し、新しい primary へ自動的に接続するため、DNS TTL を待つ必要がない |
| 認証情報の集中管理 | Proxy は Secrets Manager の secret を使ってデータベースへ接続するため、パスワードローテーション時にアプリケーションを変更しなくてよい |
| 認証の強化 | アプリケーションに IAM 認証で Proxy へ接続させることができ、アプリケーション側でデータベースパスワードを保持しなくてよい。SQL Server の場合、Proxy からデータベースへは引き続き Secrets Manager の認証情報を使う |
RDS Proxy は RDS for SQL Server をサポートしています。そのため、このシリーズでも最後の一歩として扱えます。ただし注意点として、Proxy は vCPU 時間単位で課金されるサービスであり、無料機能ではありません。導入前にコストに見合うかを評価してください。
すべての場面で RDS Proxy が必要なわけではありません。アプリケーション数が少なく、接続が安定しており、すでに適切な connection pool 管理ができている場合は、RDS へ直接接続するだけで十分なこともあります。RDS Proxy が特に有効なのは、serverless、大量の短時間接続、頻繁なスケール、failover 中断時間を短くしたいシステムです。
構築前に確認すること
| 項目 | 事前に確認する内容 |
|---|---|
| VPC と Subnet | Proxy は RDS と同じ VPC に置く必要がある。少なくとも 2 つの AZ にまたがる Private Subnet を推奨 |
| Security Group | アプリケーションから Proxy、Proxy から RDS の 2 区間で 1433 を許可する |
| Secrets Manager | DB 認証情報を保存した secret があるか、形式に username と password が含まれているか |
| IAM Role | Proxy が secret を読み取るための IAM Role が必要 |
| 認証方式 | アプリケーションが SQL Server パスワード認証で Proxy へ接続するのか、IAM 認証を使うのか |
| TLS | アプリケーション側で TLS 接続を有効化できるか。IAM 認証では TLS が必須 |
| エンジン制限 | SQL Server workload が MARS、temporary table、prepared statements など pinning を起こしやすい機能を使っているか |
ここで 1 つ訂正です。 前回の記事では SQL Server 2022 を作成しました。 ただし、SQL Server 2022 は現時点では RDS Proxy の対応リストに入っていません。 そのため、ここでは SQL Server 2019 のインスタンスを作り直しています。
ネットワーク構成は次の 2 区間になります。
1
アプリケーション --( 1433 )--> RDS Proxy --( 1433 )--> RDS for SQL Server
そのため、Security Group も 2 つの区間に分けて考えます。
- Proxy の Security Group:inbound でアプリケーションの Security Group から
1433を許可する。 - RDS の Security Group:inbound で Proxy の Security Group から
1433を許可する。
Proxy を作成した後もアプリケーションが RDS へ直接接続できる状態だと、接続の統制としては不十分です。RDS の inbound は Proxy の Security Group だけに絞ることをおすすめします。
方法 1:AWS Console GUI で作成する
Secrets Manager Secret を準備する
RDS Proxy がデータベースへ接続するとき、アプリケーションから渡されたパスワードを使うわけではありません。Secrets Manager に保存された secret を使います。そのため、最初に secret が存在することを確認します。
前回の記事で master user password を RDS 管理にしている場合、Secrets Manager には RDS が作成した secret があります。それをそのまま使えます。アプリケーションに master 以外のデータベースアカウントを使わせたい場合は、先に SQL Server 側で login と user を作成し、それに対応する secret を手動で作成します。
1
2
3
4
{
"username": "app_user",
"password": "<high-strength-password>"
}
1 つの Proxy には複数の secret を紐づけられます。各 secret は、Proxy 経由で接続できる 1 つのデータベースアカウントに対応します。アプリケーションが Proxy に接続するときに指定する username は、そのうちのどれか 1 つの secret と一致している必要があります。
Secret には少なくとも
usernameとpasswordの 2 つの key が必要です。手動で secret を作成する場合は、「Credentials for Amazon RDS database」タイプを選ぶと、形式を間違えにくくなります。
IAM Policy と IAM Role を作成する
Proxy には secret を読み取るための IAM Role が必要です。手順は前回までの記事で扱った IAM Role と同じです。先に policy を作成し、次に rds.amazonaws.com が assume できる role を作成します。
Policy には少なくとも secretsmanager:GetSecretValue が必要です。secret がカスタマー管理 KMS key で暗号化されている場合は、kms:Decrypt も必要です。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "secretsmanager:GetSecretValue",
"Resource": [
"arn:aws:secretsmanager:<region>:<account-id>:secret:<secret-name>-*"
]
},
{
"Effect": "Allow",
"Action": "kms:Decrypt",
"Resource": "arn:aws:kms:<region>:<account-id>:key/<key-id>",
"Condition": {
"StringEquals": {
"kms:ViaService": "secretsmanager.<region>.amazonaws.com"
}
}
}
]
}
Trust policy では、rds.amazonaws.com がこの role を assume できるようにします。
1
2
3
4
5
6
7
8
9
10
11
12
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "rds.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
前回までと同じく、本番環境では aws:SourceAccount と aws:SourceArn を追加して、信頼範囲を絞ることをおすすめします。
Console で Proxy を作成するとき、ウィザードに IAM Role を自動作成させることもできます。デモ環境では便利ですが、本番環境では role と policy を自分で管理したほうが、権限境界が明確になり、IaC にも載せやすくなります。
Proxy を作成する
RDS Console に入り、左側メニューから Proxies ページを開きます。
作成ボタンを押した後、主な設定は次のとおりです。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
Proxy configuration
> Engine family
>> Microsoft SQL Server
> Proxy identifier
>> sqlserver-demo-proxy
> Idle client connection timeout
>> 30 minutes (デフォルトは 30 分。アプリケーションの挙動に合わせて調整)
Target group configuration
> Database
>> sqlserver-express-demo (前回の記事で作成した DB instance)
> Connection pool maximum connections
>> 100 (Proxy が使用できる database max connections の割合)
Authentication
> Secrets Manager secrets
>> 先ほど準備した secret を選択 (複数選択可)
> IAM role
>> 作成した IAM Role を選択
> Client authentication type
>> SQL Server authentication
> IAM authentication
>> Disabled (後で IAM 認証の例として Required に変更)
Connectivity
> Subnets
>> 少なくとも 2 つの AZ にまたがる Private Subnet を選択
> VPC security groups
>> Proxy 専用の Security Group
いくつかの設定は少し補足しておきます。
- Connection pool maximum connections (
MaxConnectionsPercent):Proxy が使用できるデータベース最大接続数の割合です。同じデータベースに Proxy を通らない接続元がある場合は、100 にしないほうが安全です。 - Idle client connection timeout (
IdleClientTimeout):アプリケーション側の接続がどれくらい idle になったら Proxy が切断するかです。アプリケーション側の connection pool idle 設定と合わせておくと、すでに切断された接続を再利用する問題を避けやすくなります。 - Connection borrow timeout (
ConnectionBorrowTimeout):データベース接続がすべて使用中のとき、アプリケーション側のリクエストが最大でどれくらい待つかです。
作成後、Proxy の状態が Available になるまで待ちます。詳細ページで Proxy endpoint を確認できます。
作成後は、まず Proxy 詳細ページの Targets セクションで target の状態が
AVAILABLEになっているか確認します。unavailableのままの場合、よくある原因は secret の認証情報が実際のデータベース認証情報と一致していない、IAM Role が secret を読めない、または Proxy から RDS への Security Group が開いていないことです。
クライアント認証方式
RDS Proxy は「アプリケーションから Proxy へ接続する区間」に対して 2 種類の認証方式を提供します。重要なのは、どちらを選んでも「Proxy からデータベースへ接続する区間」は Secrets Manager の secret を使う点です。
| 認証方式 | 説明 | 向いている場面 |
|---|---|---|
| SQL Server パスワード認証 | アプリケーションがデータベース認証情報で Proxy に接続し、Proxy が secret の内容と照合する | 既存アプリケーションをほぼそのまま移行したい場合。connection string の host を変えるだけで済みやすい |
| IAM 認証 | アプリケーションが IAM 身分で短時間有効な token を生成し、driver が対応する access token 属性で Proxy に接続する。データベースパスワードを知る必要がない | ECS、EKS、Lambda、EC2 など、すでに IAM Role を持つコンピューティングリソース |
この設定は Proxy の次の 2 つの項目に対応します。
- Client authentication type (
ClientPasswordAuthType):SQL Server ではSQL_SERVER_AUTHENTICATIONを選びます。 - IAM authentication (
IAMAuth):Disabledはパスワード認証のみ、Requiredはすべての接続に IAM token を必須にする設定です。
方法 1:SQL Server パスワード認証
これはデフォルトで、最も簡単な方式です。手順は次のとおりです。
まず、Proxy の IAM authentication が無効 (Disabled) になっていることを確認します。
次に、アプリケーションが使用するアカウントに対応する secret が Proxy に紐づいていることを確認します。アプリケーションが接続時に使う username と password は、いずれかの secret の内容と一致している必要があります。Proxy は接続を受け取ると、この認証情報を secret と照合し、認証に成功してからデータベース接続をプールから借り出します。
最後に、アプリケーションの connection string の host を RDS endpoint から Proxy endpoint に変更します。
1
2
3
4
Server / Host: <proxy-endpoint>
Port: 1433
User: app_user
Password: secret と同じパスワード
sqlcmd でテストします。
1
sqlcmd -S "<proxy-endpoint>,1433" -U app_user -P '<password>' -Q "SELECT @@SERVERNAME;"
正しく接続できれば、Proxy の Monitoring にメトリクスが表示され始めます。
この方式の利点は、アプリケーションをほとんど変更しなくてよいことです。host を変えるだけで済みます。ただし、パスワードはまだアプリケーション設定に残ります。つまり、認証情報のガバナンスは半分だけ解決された状態です。Proxy からデータベースへの区間は Secrets Manager のローテーションに追従しますが、アプリケーションから Proxy への区間では、アプリケーション側のパスワード同期が必要です。
secret の自動ローテーションを有効にしている場合、ローテーション後はアプリケーション側のパスワードも更新する必要があります。そうしないと接続失敗が発生します。この同期問題を完全になくしたい場合は、IAM 認証へ切り替えます。
方法 2:IAM 認証
IAM 認証を使うと、アプリケーションはデータベースパスワードを知る必要がありません。アプリケーションは EC2 instance profile、ECS task role、Lambda execution role など自分の IAM 身分を使って、15 分間有効な token を生成します。そのうえで、データベース driver が対応する access token 属性を使って Proxy に接続します。
注意点として、RDS for SQL Server 自体は端到端の IAM データベース認証をサポートしていません。ここでの IAM 認証は「アプリケーションから Proxy」までの区間だけです。Proxy から SQL Server へは、引き続き Secrets Manager に保存された認証情報で接続します。
設定手順は次のとおりです。
ステップ 1:Proxy の IAM authentication 設定を変更する
Proxy 詳細ページで Modify を押し、IAM authentication を Required に変更します。
Required に変更すると、すべての接続で IAM token が必須になります。元のパスワード認証は使えなくなります。段階的に切り替えたい場合は、まずテスト環境で一通りの流れを検証してください。
ステップ 2:アプリケーションの IAM 身分に rds-db:connect 権限を付与する
アプリケーションが使用する IAM Role に、この Proxy への接続を許可する policy を追加します。
1
2
3
4
5
6
7
8
9
10
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "rds-db:connect",
"Resource": "arn:aws:rds-db:<region>:<account-id>:dbuser:<proxy-resource-id>/app_user"
}
]
}
ARN 形式では次の点に注意します。
- service は
rdsではなくrds-dbです。 <proxy-resource-id>は Proxy の resource ID です。形式はprx-0123456789abcdef0のようになります。Proxy 詳細ページ、または CLI で確認できます。ARN のdb-proxy:より後ろの値を使います。
1
2
3
aws rds describe-db-proxies \
--db-proxy-name sqlserver-demo-proxy \
--query "DBProxies[0].DBProxyArn"
- 最後の
app_userはデータベースアカウント名です。複数のアカウントを許可する場合は、resource を複数列挙できます。デモ環境では一時的に*を使うこともできますが、本番環境では明示的に指定することをおすすめします。
ステップ 3:IAM token を生成して接続する
アプリケーションまたはテスト用マシンで、AWS CLI を使って token を生成します。hostname には RDS endpoint ではなく Proxy endpoint を指定してください。
1
2
3
4
5
aws rds generate-db-auth-token \
--hostname <proxy-endpoint> \
--port 1433 \
--username app_user \
--region <region>
出力は長い token になります。SQL Server の場合、この token を通常の password 欄に入れてはいけません。driver が提供する token/access token 属性を使います。username は引き続き app_user です。たとえば JDBC は accessToken、ODBC は sql_copt_ss_access_token、.NET SqlClient は AccessToken を使います。
IAM 認証では TLS が必須です。そのため、connection string では暗号化を有効にする必要があります。たとえば .NET の SqlConnection では、connection string に username と暗号化設定を残し、token は別途 AccessToken に渡します。
1
2
3
4
5
6
var token = "<generate-db-auth-token の出力、または SDK で生成した token>";
using var connection = new SqlConnection(
"Server=<proxy-endpoint>,1433;User ID=app_user;Encrypt=True;Database=my_app;");
connection.AccessToken = token;
await connection.OpenAsync();
つまり、client tool や driver が SQL Server の access token 属性をサポートしていない場合、この IAM 認証方式のテストには使えません。token を -P の password として渡す一般的なやり方では、login failed になることがよくあります。
言語によって token の生成方法は異なりますが、重要な点は同じです。hostname は Proxy endpoint、port は SQL Server の
1433、username は Proxy secret 内のデータベースアカウントと一致させます。
ステップ 4:token の期限切れに対応する
token の有効期間は 15 分です。ただし、これは「接続を確立するとき」の認証期限を意味します。すでに確立された接続は、token が期限切れになったからといって切断されません。アプリケーション側では次のことを行います。
- 新しい接続を作成する前に毎回新しい token を生成する。token を静的なパスワードのように長時間キャッシュしない。
- connection pool を使う場合、pool が新しい接続を作るタイミングで新しい token を取得できることを確認する。多くの AWS SDK や wrapper library には対応する実装パターンがあります。
IAM 認証のエラーは、多くの場合 login failed としか表示されません。token 期限切れ、
rds-db:connect権限不足、TLS 未有効化のどれなのかは直接分からないことがあります。調査時は、TLS が有効か、token が 15 分以内に生成されたものか、IAM policy の resource ARN が正しいか、特に proxy resource id と username が一致しているかを順番に確認します。
Proxy に接続できないときの確認順序
Proxy への接続に失敗する場合は、次の順番で確認すると切り分けやすくなります。
- Proxy の状態が Available か、target の状態が
AVAILABLEか。 - アプリケーションから Proxy への Security Group が
1433を許可しているか。 - Proxy から RDS への Security Group が
1433を許可しているか。 - Secret の認証情報が実際のデータベース認証情報と一致しているか。RDS 管理の secret を手動コピーした場合、ローテーションには自動追従しない点に注意する。
- Proxy の IAM Role が secret と KMS key を読み取れるか。
- IAM 認証モードでは、TLS、token の有効期限、
rds-db:connect権限が正しいか。 - VPC 外から接続していないか。Proxy endpoint は VPC 内でのみ名前解決および接続でき、publicly accessible には対応していない。
方法 2:Terraform で作成する
前回の記事の Terraform 例に、RDS Proxy 関連リソースを追加します。この例には secret、IAM role、proxy、target group 設定、target 登録が含まれます。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
variable "db_app_username" {
type = string
default = "app_user"
}
variable "db_app_password" {
type = string
sensitive = true
}
resource "aws_secretsmanager_secret" "sqlserver_app_user" {
name = "rds/sqlserver-express-demo/app-user"
}
resource "aws_secretsmanager_secret_version" "sqlserver_app_user" {
secret_id = aws_secretsmanager_secret.sqlserver_app_user.id
secret_string = jsonencode({
username = var.db_app_username
password = var.db_app_password
})
}
resource "aws_security_group" "sqlserver_proxy" {
name = "sqlserver-proxy"
description = "Allow application access to RDS Proxy"
vpc_id = var.vpc_id
ingress {
description = "SQL Server from application"
from_port = 1433
to_port = 1433
protocol = "tcp"
security_groups = [var.app_security_group_id]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
# RDS の Security Group に Proxy からの inbound を許可する
resource "aws_security_group_rule" "sqlserver_from_proxy" {
type = "ingress"
from_port = 1433
to_port = 1433
protocol = "tcp"
security_group_id = aws_security_group.sqlserver.id
source_security_group_id = aws_security_group.sqlserver_proxy.id
description = "SQL Server from RDS Proxy"
}
resource "aws_iam_role" "sqlserver_proxy" {
name = "rds-proxy-sqlserver-demo"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Principal = {
Service = "rds.amazonaws.com"
}
Action = "sts:AssumeRole"
Condition = {
StringEquals = {
"aws:SourceAccount" = data.aws_caller_identity.current.account_id
}
}
}
]
})
}
resource "aws_iam_policy" "sqlserver_proxy_secrets" {
name = "rds-proxy-sqlserver-demo-secrets"
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Action = "secretsmanager:GetSecretValue"
Resource = aws_secretsmanager_secret.sqlserver_app_user.arn
}
]
})
}
resource "aws_iam_role_policy_attachment" "sqlserver_proxy_secrets" {
role = aws_iam_role.sqlserver_proxy.name
policy_arn = aws_iam_policy.sqlserver_proxy_secrets.arn
}
resource "aws_db_proxy" "sqlserver" {
name = "sqlserver-demo-proxy"
engine_family = "SQLSERVER"
role_arn = aws_iam_role.sqlserver_proxy.arn
vpc_subnet_ids = var.private_subnet_ids
vpc_security_group_ids = [aws_security_group.sqlserver_proxy.id]
idle_client_timeout = 1800
require_tls = true
auth {
auth_scheme = "SECRETS"
client_password_auth_type = "SQL_SERVER_AUTHENTICATION"
iam_auth = "DISABLED" # IAM 認証を強制する場合は REQUIRED に変更
secret_arn = aws_secretsmanager_secret.sqlserver_app_user.arn
}
tags = {
Name = "sqlserver-demo-proxy"
}
}
resource "aws_db_proxy_default_target_group" "sqlserver" {
db_proxy_name = aws_db_proxy.sqlserver.name
connection_pool_config {
max_connections_percent = 100
max_idle_connections_percent = 50
connection_borrow_timeout = 120
}
}
resource "aws_db_proxy_target" "sqlserver" {
db_proxy_name = aws_db_proxy.sqlserver.name
target_group_name = aws_db_proxy_default_target_group.sqlserver.name
db_instance_identifier = aws_db_instance.sqlserver.identifier
}
output "proxy_endpoint" {
value = aws_db_proxy.sqlserver.endpoint
}
本番環境で使う場合は、少なくとも次を調整してください。
- パスワードを変数として平文で渡さない。Secrets Manager に生成させるか、ローテーション機構を使う。
- IAM 認証へ切り替える場合は、
iam_authをREQUIREDにし、アプリケーションの IAM Role にrds-db:connectを付与する。 max_connections_percentは、Proxy を通らない接続元が他にあるかを考慮して決める。require_tls = trueは維持することをおすすめします。IAM 認証では TLS が必須であり、パスワード認証でも暗号化通信を使うべきです。
Pinning:接続プール化は万能ではない
RDS Proxy の主な効果は multiplexing にあります。複数のアプリケーション接続が、より少ないデータベース接続を共有できます。ただし、一部の操作は接続の session 状態を変更します。その場合、同じデータベース接続を他の session と安全に共有できなくなります。このとき Proxy は、アプリケーション接続を特定のデータベース接続に固定します。接続が終了するまでこの状態が続き、この動作を pinning と呼びます。
pinning された接続も通常どおり利用できますが、接続共有の効果は失われます。大半の接続が pinning される場合、Proxy は単なる転送レイヤーに近くなり、課金は発生するのに効果は大きく下がります。
SQL Server で pinning を起こしやすい操作には、MARS、DTC、temporary table、transactions、cursors、prepared statements、一部の SET statements などがあります。CloudWatch の DatabaseConnectionsCurrentlySessionPinned メトリクスで pinning の割合を確認できます。
Proxy 導入後は、pinning メトリクスを一定期間観察することをおすすめします。pinning の割合が高い場合は、まずアプリケーションが pinning を起こす構文を多用していないか確認し、調整できるかを評価してから、Proxy を使い続ける価値があるか判断します。
RDS Proxy for SQL Server の制限
導入前に知っておくべき制限です。
- Proxy は RDS と同じ VPC に置く必要があり、public access はサポートされません。アプリケーションは VPC 内、または VPN、Peering、Transit Gateway 経由で接続する必要があります。
- Windows Authentication はサポートされません。クライアント認証は SQL Server 認証と IAM 認証のみです。
- MARS (Multiple Active Result Sets) を使用すると session pinning が発生し、Proxy は initialization queries を実行しません。connection string で
MultipleActiveResultSets=Trueを有効にしているアプリケーションでは、pinning によって Proxy の効果が相殺されないかを先に評価してください。 - 1 つの Proxy は 1 つの target database、つまり instance または cluster にのみ関連付けられます。
- Proxy は課金対象サービスです。target database の vCPU 数に基づいて課金され、最低課金 vCPU 数があります。
作成後のチェックリスト
- Proxy と target の状態が Available /
AVAILABLEである。 - アプリケーションが Proxy endpoint へ接続するよう変更され、正常にクエリできる。
- RDS の Security Group が Proxy からの接続だけを許可する形に絞られている。
- 選択した認証方式を実測している。パスワード認証では secret 同期方針、IAM 認証では token 更新機構を確認する。
require_tlsが有効で、アプリケーションの connection string でも暗号化が有効になっている。- CloudWatch で
DatabaseConnections、ClientConnections、DatabaseConnectionsCurrentlySessionPinnedなどのメトリクスを確認している。 - failover 演習を行い、failover 中のアプリケーション挙動が期待どおりか確認している。
- Secrets ローテーション後、Proxy とアプリケーションの接続挙動を検証している。
まとめ
ここまでで、このシリーズでは RDS for SQL Server を「作れる」状態から「運用できる」状態へ近づけてきました。
- 1 本目の記事では、ネットワーク、バージョン、ストレージ、バックアップ、復元といったプラットフォームを扱いました。
- 2 本目の記事では、監査レコードとパスワードローテーションというガバナンスを扱いました。
- 今回の記事では、接続プール化、failover 中断時間、アプリケーションが IAM 身分で Proxy 経由のデータベース接続を行う方法を扱いました。
RDS Proxy は必須ではありません。接続ガバナンスを得るためにコストを払う選択肢です。接続挙動が単純で安定している従来型のシステムでは、必要ないかもしれません。一方で、serverless、頻繁なスケール、failover 中断に敏感なシステムでは、比較的少ない変更で安定性を大きく改善できる可能性があります。
導入後は、必ずメトリクスを確認してください。特に pinning の割合は重要です。Proxy の価値は「入れたから有効」と考えるのではなく、データで検証する必要があります。




