【AWS】RDS ProxyをCloudFormationで構築する
RDS Proxyが2020/6/30にGAされましたね。
最近RDS Proxyに触れる機会があり、サクッと消せるようにCloudFormation(以下CFnと略)を使って構築しました。その時書いたCFnテンプレートを一例としてご紹介します。
RDS Proxyの詳細や運用の勘所については説明しませんので、公式ドキュメントなどを参照してください。
要件
- プロキシ先はAurora
- ユーザとパスワードの一般的な認証
- Secrets Managerを利用
- TLSは必須ではない
CFnテンプレート
- Secrets Managerを利用
テンプレートが100行超えたのでGitHub Gistにアップロードしました。
テンプレートの全容を見たい方はhomoluctus/rds_proxy.ymlを参照してください。
解説
Parameters
Parameters:
# DB Proxy
ProxyName:
Type: String
ProxyEngineFamily:
Type: String
AllowedValues:
- MYSQL
- POSTGRESQL
ProxyIdleClientTimeout:
Type: Number
ProxyRequireTLS:
Type: String
AllowedValues:
- true
- false
Default: false
ProxyVpcSecurityGroupIds:
Type: List<AWS::EC2::SecurityGroup::Id>
ProxyVpcSubnetIds:
Type: List<AWS::EC2::Subnet::Id>
# DB Proxy Target Group
ProxyTargetConnectionBorrowTimeout:
Type: Number
ProxyTargetMaxConnectionsPercent:
Type: Number
ProxyTargetMaxIdleConnectionsPercent:
Type: Number
ProxyTargetDBClusterIdentifiers:
Type: CommaDelimitedList
# Secrets Manager
SecretsManagerRoleName:
Type: String
SecretsManagerName:
Type: String
SecretsManagerKMSKeyId:
Type: String
SecretsManagerManagedPolicyName:
Type: String
Resources
DB Proxy
RDSProxy:
Type: "AWS::RDS::DBProxy"
Properties:
Auth:
# Secrets Managerを利用してユーザ名とパスワードで認証
# 予めSecretsは作成しておく必要があり
- AuthScheme: SECRETS
IAMAuth: DISABLED
SecretArn: !Sub "arn:aws:secretsmanager:${AWS::Region}:${AWS::AccountId}:secret:${SecretsManagerName}"
# 作成するRDS Proxyの名前
DBProxyName: !Ref ProxyName
# 2020/08/17時点でMySQLとPostgreSQLがサポートされている
EngineFamily: !Ref ProxyEngineFamily
# Proxyとクライアント間の接続がアイドル状態の時に接続切断するまでの秒数
IdleClientTimeout: !Ref ProxyIdleClientTimeout
# TLSが必須かどうか
RequireTLS: !Ref ProxyRequireTLS
# RDS Proxyに設定するIAM Role
# 今回はSecrets Managerから値を取得して復号可能なRoleをアタッチ
RoleArn: !GetAtt SecretsManagerRole.Arn
# RDS Proxyにアタッチするセキュリティグループ
VpcSecurityGroupIds: !Ref ProxyVpcSecurityGroupIds
# RDS Proxyを構築するVPC Subnet
VpcSubnetIds: !Ref ProxyVpcSubnetIds
DB Proxy Target Group
Parameters:
# DB Proxy
ProxyName:
Type: String
ProxyEngineFamily:
Type: String
AllowedValues:
- MYSQL
- POSTGRESQL
ProxyIdleClientTimeout:
Type: Number
ProxyRequireTLS:
Type: String
AllowedValues:
- true
- false
Default: false
ProxyVpcSecurityGroupIds:
Type: List<AWS::EC2::SecurityGroup::Id>
ProxyVpcSubnetIds:
Type: List<AWS::EC2::Subnet::Id>
# DB Proxy Target Group
ProxyTargetConnectionBorrowTimeout:
Type: Number
ProxyTargetMaxConnectionsPercent:
Type: Number
ProxyTargetMaxIdleConnectionsPercent:
Type: Number
ProxyTargetDBClusterIdentifiers:
Type: CommaDelimitedList
# Secrets Manager
SecretsManagerRoleName:
Type: String
SecretsManagerName:
Type: String
SecretsManagerKMSKeyId:
Type: String
SecretsManagerManagedPolicyName:
Type: String
RDSProxy:
Type: "AWS::RDS::DBProxy"
Properties:
Auth:
# Secrets Managerを利用してユーザ名とパスワードで認証
# 予めSecretsは作成しておく必要があり
- AuthScheme: SECRETS
IAMAuth: DISABLED
SecretArn: !Sub "arn:aws:secretsmanager:${AWS::Region}:${AWS::AccountId}:secret:${SecretsManagerName}"
# 作成するRDS Proxyの名前
DBProxyName: !Ref ProxyName
# 2020/08/17時点でMySQLとPostgreSQLがサポートされている
EngineFamily: !Ref ProxyEngineFamily
# Proxyとクライアント間の接続がアイドル状態の時に接続切断するまでの秒数
IdleClientTimeout: !Ref ProxyIdleClientTimeout
# TLSが必須かどうか
RequireTLS: !Ref ProxyRequireTLS
# RDS Proxyに設定するIAM Role
# 今回はSecrets Managerから値を取得して復号可能なRoleをアタッチ
RoleArn: !GetAtt SecretsManagerRole.Arn
# RDS Proxyにアタッチするセキュリティグループ
VpcSecurityGroupIds: !Ref ProxyVpcSecurityGroupIds
# RDS Proxyを構築するVPC Subnet
VpcSubnetIds: !Ref ProxyVpcSubnetIds
今回はRDS Proxyの裏にはRDS Auroraが存在すると仮定します。
RDSProxyTargetGroup:
Type: "AWS::RDS::DBProxyTargetGroup"
Properties:
# コネクションプールの設定
ConnectionPoolConfigurationInfo:
# コネクションプールが使用可能になるまでの待機秒数
# Proxyが使用可能な最大接続数を使い切っていて、その全接続を使用中の場合に適用される
ConnectionBorrowTimeout: !Ref ProxyTargetConnectionBorrowTimeout
# RDS 最大接続数のうちProxyが使用可能な接続数の割合
MaxConnectionsPercent: !Ref ProxyTargetMaxConnectionsPercent
# RDSへの接続数のうちアイドル状態の接続数の割合
# 上限はMaxConnectionsPercentで値が大きければ再度接続するオーバーヘッドが減少する
MaxIdleConnectionsPercent: !Ref ProxyTargetMaxIdleConnectionsPercent
# Proxyが接続するRDS Auroraクラスターの識別子
DBClusterIdentifiers: !Ref ProxyTargetDBClusterIdentifiers
# AWS::RDS::DBProxyで作成したRDS Proxyの名前
DBProxyName: !Ref RDSProxy
# ターゲットグループ名はdefaultを無条件に指定
# 2020/08/17時点ではdefaultであることが必須
TargetGroupName: default
IAM Policy
SecretsManagerManagedPolicy:
# 使いまわせるようにインラインポリシーではなくユーザ管理のポリシーを作成
Type: "AWS::IAM::ManagedPolicy"
Properties:
Description: "Get values from Secrets Manager"
ManagedPolicyName: !Ref SecretsManagerManagedPolicyName
Path: /
PolicyDocument:
Version: "2012-10-17"
Statement:
# Secrets ManagerからRDS Proxy用に作成したSecretsを取得
- Effect: Allow
Action:
- "secretsmanager:GetSecretValue"
Resource: !Sub "arn:aws:secretsmanager:${AWS::Region}:${AWS::AccountId}:secret:${SecretsManagerName}"
# 取得したSecretsを復号する
- Effect: Allow
Action:
- "kms:Decrypt"
Resource: !Sub "arn:aws:kms:${AWS::Region}:${AWS::AccountId}:key/${SecretsManagerKMSKeyId}"
Condition:
StringEquals:
kms:ViaService: !Sub "secretsmanager.${AWS::Region}.amazonaws.com"
IAM Role
SecretsManagerRole:
Type: "AWS::IAM::Role"
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
# RoleをRDSに渡す
- Effect: Allow
Principal:
Service:
- "rds.amazonaws.com"
Action:
- "sts:AssumeRole"
Description: "Use for RDS Proxy"
# 作成したユーザ管理ポリシーを指定
ManagedPolicyArns:
- !Ref SecretsManagerManagedPolicy
Path: /
RoleName: !Ref SecretsManagerRoleName
終わりに
アンチパターンとされてきたLambda + RDSの構成を解決するRDS Proxyは素晴らしい
ただSQLによってはピン留めとか発生するのでプロダクションで運用する際には慎重に検討した方がいいでしょう
Reference
Author And Source
この問題について(【AWS】RDS ProxyをCloudFormationで構築する), 我々は、より多くの情報をここで見つけました https://qiita.com/homines22/items/be6c9565ddd615d1d9ac著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .