はじめに
RDS Proxyを手軽に試すためにテンプレート化した際のメモです。
極力管理コンソールの入力項目に合わせてコメントを入れてあります。漏れてたり間違ってたらごめんなさい。
方針
- CloudFormation Nested Stackは使わないこと
- ルートスタック更新から子スタックの変更セット(差分)確認が難しいため
- 作成や削除が柔軟に行えること
- 環境名は以下とすること、ただし他の環境名も追加可能であること
- prod(本番)
- stg(検証)
- dev(開発)
前提
- 最低限必要なIAM ロール、セキュリティグループの作成は同一アカウントの別スタックで既に作成済みでエクスポートされている
- VPCは既に作成済みのリソースがある
- Subnetは既に作成済みのリソースがある
- 作成先のAWSアカウントは環境や用途毎に分かれているが同じアカウントに複数作成することもあるし、異なるアカウントに1つ作成することもある
テンプレート
テンプレート内では他スタックから以下のエクスポート値を読み込んでいます。
事前に別スタックからエクスポートが必要です。
- { "Fn::ImportValue": !Sub "${SysName}-${Env}-rds-monitoring-role-arn" } RDSモニタリングIAMロールARN
- { "Fn::ImportValue": !Sub "${SysName}-${Env}-private-subnet-a-id" } プライベートサブネットID A
- { "Fn::ImportValue": !Sub "${SysName}-${Env}-private-subnet-c-id" } プライベートサブネットID C
- { "Fn::ImportValue": !Sub "${SysName}-${Env}-rds-proxy-sg-id" } RDSProxy用セキュリティグループID
- { "Fn::ImportValue": !Sub "${SysName}-${Env}-rds-secret-arn" } RDS用シークレットARN
AWSTemplateFormatVersion: "2010-09-09"
Description: RDS & RDS Proxy for MySQL Create
Parameters:
SysName:
Type: String
Default: "customapp"
Env:
Type: String
Default: "stg"
AllowedValues:
- dev
- stg
- prod
RDSInstanceType:
Type: String
Default: "db.t2.small"
AllowedValues:
- "db.t2.small"
DBName:
Default: appdb
Description: "database name"
Type: String
MinLength: '1'
MaxLength: '64'
Resources:
# --------------------------------------------------------------------------------
# RDS インスタンス
# --------------------------------------------------------------------------------
DBInstance:
Type: "AWS::RDS::DBInstance"
Properties:
# --------------------------------------------------------------------------------
# エンジンのオプション
# --------------------------------------------------------------------------------
Engine: MySQL
EngineVersion: "5.7.30"
# --------------------------------------------------------------------------------
# 設定
# --------------------------------------------------------------------------------
# DBインスタンス識別子
DBInstanceIdentifier: !Sub "${SysName}-${Env}-rds"
# --------------------------------------------------------------------------------
# 設定 認証情報の設定
# --------------------------------------------------------------------------------
# マスターユーザー名
MasterUsername: !Sub '{{resolve:secretsmanager:${SysName}-${Env}-secret:SecretString:username}}'
# マスターパスワード
MasterUserPassword: !Sub '{{resolve:secretsmanager:${SysName}-${Env}-secret:SecretString:password}}'
# --------------------------------------------------------------------------------
# DB インスタンスサイズ
# --------------------------------------------------------------------------------
# DBインスタンスクラス
DBInstanceClass: !Ref RDSInstanceType
# --------------------------------------------------------------------------------
# ストレージ
# --------------------------------------------------------------------------------
# ストレージタイプ 汎用 SSD(gp2), プロビジョンド IOPS(io1)
StorageType: gp2
# ストレージ割り当て
AllocatedStorage: 50
# --------------------------------------------------------------------------------
# 可用性と耐久性
# --------------------------------------------------------------------------------
MultiAZ: false
# --------------------------------------------------------------------------------
# 接続
# --------------------------------------------------------------------------------
# サブネットグループ
DBSubnetGroupName: !Ref DBSubnetGroup
# パブリックアクセス可能
PubliclyAccessible: false
# VPCセキュリティグループ
VPCSecurityGroups:
- { "Fn::ImportValue": !Sub "${SysName}-${Env}-rds-sg-id" }
# アベイラビリティーゾーン
# AvailabilityZone: ''
# データベースポート
# Port: 3306
# --------------------------------------------------------------------------------
# データベース認証
# --------------------------------------------------------------------------------
# データベース認証オプション
EnableIAMDatabaseAuthentication: false
# --------------------------------------------------------------------------------
# 追加設定 データベースの選択肢
# --------------------------------------------------------------------------------
# 最初のデータベース名
DBName: !Ref DBName
# DBパラメータグループ
DBParameterGroupName: !Ref DBParameterGroup
# --------------------------------------------------------------------------------
# 追加設定 バックアップ
# --------------------------------------------------------------------------------
# バックアップ保持期間
BackupRetentionPeriod: 7
# バックアップウィンドウ
PreferredBackupWindow: "18:00-18:30"
# スナップショットにタグをコピー
CopyTagsToSnapshot: true
# --------------------------------------------------------------------------------
# 追加設定 暗号化
# --------------------------------------------------------------------------------
# 暗号を有効化
StorageEncrypted: true
# マスターキー
# KmsKeyId: ''
# --------------------------------------------------------------------------------
# 追加設定 モニタリング
# --------------------------------------------------------------------------------
# 詳細度
MonitoringInterval: "60"
# モニタリングロール
MonitoringRoleArn: { "Fn::ImportValue": !Sub "${SysName}-${Env}-rds-monitoring-role-arn" }
# --------------------------------------------------------------------------------
# 追加設定 ログのエクスポート
# --------------------------------------------------------------------------------
EnableCloudwatchLogsExports:
- audit
- error
- general
- slowquery
# --------------------------------------------------------------------------------
# 追加設定 メンテナンス
# --------------------------------------------------------------------------------
# マイナーバージョン自動アップグレードの有効化
AutoMinorVersionUpgrade: true
# メンテナンスウィンドウ
PreferredMaintenanceWindow: "sat:19:00-sat:19:30"
# --------------------------------------------------------------------------------
# 追加設定 削除保護
# --------------------------------------------------------------------------------
# 削除保護
DeletionProtection: false
# --------------------------------------------------------------------------------
# タグ
# --------------------------------------------------------------------------------
Tags:
- Key: "Name"
Value: !Sub "${SysName}-${Env}-rds"
- Key: "Env"
Value: !Ref Env
DeletionPolicy: "Delete"
# --------------------------------------------------------------------------------
# DBパラメータグループ
# --------------------------------------------------------------------------------
DBParameterGroup:
Type: "AWS::RDS::DBParameterGroup"
Properties:
Family: "MySQL5.7"
Description: !Sub "${SysName}-${Env}-db-param-group"
Parameters:
time_zone: "Asia/Tokyo"
character_set_client: utf8mb4
character_set_connection: utf8mb4
character_set_database: utf8mb4
character_set_results: utf8mb4
character_set_server: utf8mb4
collation_connection: utf8mb4_bin
collation_server: utf8mb4_bin
skip-character-set-client-handshake: 1
innodb_file_format: Barracuda
innodb_large_prefix: 1
innodb_purge_threads: 4
Tags:
- Key: "Name"
Value: !Sub "${SysName}-${Env}-db-param-group"
- Key: "Env"
Value: !Ref Env
# --------------------------------------------------------------------------------
# DBサブネットグループ
# --------------------------------------------------------------------------------
DBSubnetGroup:
Type: "AWS::RDS::DBSubnetGroup"
Properties:
DBSubnetGroupName: !Sub "${SysName}-${Env}-private-db-subnet-group"
DBSubnetGroupDescription: "-"
SubnetIds:
- { "Fn::ImportValue": !Sub "${SysName}-${Env}-private-subnet-a-id" }
- { "Fn::ImportValue": !Sub "${SysName}-${Env}-private-subnet-c-id" }
Tags:
- Key: "Name"
Value: !Sub "${SysName}-${Env}-db-subnet-group"
- Key: "Env"
Value: !Ref Env
# --------------------------------------------------------------------------------
# RDS Proxy
# --------------------------------------------------------------------------------
RDSProxy:
Type: AWS::RDS::DBProxy
Properties:
# --------------------------------------------------------------------------------
# プロキシ設定
# --------------------------------------------------------------------------------
# プロキシ識別子
DBProxyName: !Sub "${SysName}-${Env}-rds-proxy"
# エンジンの互換性
EngineFamily: MYSQL
# Transport Layer Security が必要
RequireTLS: false
# アイドルクライントの接続タイムアウト
IdleClientTimeout: 300
# --------------------------------------------------------------------------------
# 接続
# --------------------------------------------------------------------------------
# Secrets Manager シークレット
Auth:
- AuthScheme: SECRETS
SecretArn: !Ref RDSSecretAttachment
# IAM 認証
IAMAuth: DISABLED
# IAMロール
RoleArn: !GetAtt RDSProxyRole.Arn
# サブネット
VpcSubnetIds:
- { "Fn::ImportValue": !Sub "${SysName}-${Env}-private-subnet-a-id" }
- { "Fn::ImportValue": !Sub "${SysName}-${Env}-private-subnet-c-id" }
# VPCセキュリティグループ
VpcSecurityGroupIds:
- { "Fn::ImportValue": !Sub "${SysName}-${Env}-rds-proxy-sg-id" }
# --------------------------------------------------------------------------------
# RDS Proxy ターゲットグループ
# --------------------------------------------------------------------------------
RDSProxyTargetGroup:
Type: AWS::RDS::DBProxyTargetGroup
DependsOn:
- DBInstance
Properties:
# --------------------------------------------------------------------------------
# ターゲットグループの設定
# --------------------------------------------------------------------------------
# ターゲットグループ識別子
TargetGroupName: default
# データベース
DBInstanceIdentifiers:
- !Ref DBInstance
# 接続情報
ConnectionPoolConfigurationInfo:
# 接続プールの接続最大数
MaxConnectionsPercent: 25
# RDS Proxyの識別子
DBProxyName: !Ref RDSProxy
# --------------------------------------------------------------------------------
# RDS Proxy ロール
# --------------------------------------------------------------------------------
RDSProxyRole:
Type: AWS::IAM::Role
Properties:
RoleName: !Sub ${SysName}-${Env}-rds-proxy-role
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
Service: rds.amazonaws.com
Action: sts:AssumeRole
Policies:
- PolicyName: AllowGetSecretValue
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Action:
- secretsmanager:GetResourcePolicy
- secretsmanager:GetSecretValue
- secretsmanager:DescribeSecret
- secretsmanager:ListSecretVersionIds
Resource: !Ref RDSSecretAttachment
RDSSecretAttachment:
Type: AWS::SecretsManager::SecretTargetAttachment
Properties:
SecretId: { "Fn::ImportValue": !Sub "${SysName}-${Env}-rds-secret-arn" }
TargetId: !Ref DBInstance
TargetType: AWS::RDS::DBInstance
Outputs:
DBInstanceEndpoint:
Value: !GetAtt DBInstance.Endpoint.Address
Export:
Name: !Sub "${SysName}-${Env}-rds-endpoint"
DBName:
Value: !Ref DBName
Export:
Name: !Sub "${SysName}-${Env}-rds-dbname"
RDSProxyEndpoint:
Value: !GetAtt RDSProxy.Endpoint
Export:
Name: !Sub "${SysName}-${Env}-rds-proxy-endpoint"