Amazon RDS Custom for SQL Serverを試してみた #reinvent

2021.12.04

しばたです。

re:Inventで発表されたAmazon RDS CustomのSQL Serverサポートを簡単にですが実際に試してみました。

RDS Custom とは?

RDS CustomはRDSに追加された新たな管理レイヤーで従来のRDSでAWSの責任下にあったいくつかの領域をユーザーとAWSで共有することでより柔軟な構成を採ることができるものとなります。
こちらはユーザーガイドにある以下の表をご覧いただくのが手っ取り早いでしょう。

(Shared responsibility model より引用)

OSおよびRDBMSのインストールやパッチ当て、冗長化やバックアップといった行為に対する責任が「 Shared (共有) 」となっているのがお分かりいただけるでしょう。

このためRDS Customを採用する場合は「丸投げではなくAWSと共にRDSを運用する覚悟」が必要となります。
ただカジュアルに「RDSをお気楽にカスタマイズできるものではない」ので決して誤解しないようにしてください。
覚悟を代償により柔軟な構成を得ることができる、という類のものです。

従来RDS Customを採用できるRDBMSはOracle Databaseのみでしたが今回SQL Serverが新たに加わる形となりました。
RDS Custom for Oracleを利用するにはインストールメディアが必要でBYOL必須など試すまでのハードルが高かったのですが、RDS Custom for SQL Serverの場合は試用する分には比較的容易に環境構築ができたので今回記事にしています。

前述の通り本番環境での利用には 覚悟 が必要ですが、最初に試用してみるぶんにはカジュアルに使うと良いと思います。

制限事項

現在のRDS Custom for SQL Serverでは以下の制限があります。

  • RDSパラメーターグループ、オプショングループは非サポートです
    • デフォルトパラメーターグループ、オプショングループの使用が強制されます
  • Single-AZ構成のみ初期構築可能です
    • ドキュメントを見る限り後からMulti-AZ構成(Alwasy-On可用性グループ)にする方法は存在する模様 (ただしリンク切れのため詳細不明)
  • 一度割り当てたストレージ容量を増やすことができません
  • 独自にEBSボリュームを追加する行為は非サポートです
  • Performance Insightsは使えません
  • RDSを停止することはできません
  • OSのCドライブに対する変更はインスタンス切り替え時 *1に消失します
  • その他詳細はユーザーガイドをご確認ください

加えてAWS側から定期的に構成に対するチェックが入り、非サポートとなる構成を検出した場合はいくつかの行為が制限されます。
詳細は以下のドキュメントをご覧ください。

このドキュメントからいくつか抜粋すると、非サポートの構成を検出した場合

  • DBインスタンスの変更不可
  • DBスナップショットの取得不可
  • 自動バックアップが作成されなくなる

といった制限がかかります。

前提条件

RDS CustomはRDSインスタンスを作成するものの、その実体は利用者のVPC環境にEC2インスタンスとして表出します。
このため従来AWS基盤側で担っていた部分などを事前に準備しておく必要があります。

RDS Custom for SQL Serverを利用するには以下の2つのリソースが必要です。

1. EC2に割り当てるIAM Role + インスタンスプロファイル

RDSの実体となるEC2がAWSの各種サービスにアクセスするためIAM Roleをアタッチする必要があります。
IAM Roleを作るためのテンプレートが custom-sqlserver-iam.json で公開されているので事前にCloudFormationから作成しておきます。

2. Custom KMS Key (対称キー)

RDS Customでは暗号化が必須となっており、デフォルト以外のCustom KMS Keyが必要となります。 対称キーであればその他条件は問われない模様です。

3. AWSサービスへのアクセス要件

また上記2リソース以外に、ネットワーク要件として、RDSが使う以下のサービスに対するアクセスも可能にしておく必要があります。

各サービスへのアクセスはインターネット経由でも良いですし、VPCエンドポイントを用意する形でも構いません。
(ドキュメント上ではVPC Endpointを作るCFn Template custom-vpc.json の適用を推奨しています)

  • S3 (Gateway Endpoint)
  • EC2
    • com.amazonaws.<リージョン名>.ec2
    • com.amazonaws.<リージョン名>.ec2messages
  • CloudWatch
    • com.amazonaws.<リージョン名>.monitoring
    • com.amazonaws.<リージョン名>.logs
  • EventBridge
    • com.amazonaws.<リージョン名>.events
  • Systems Manager
    • com.amazonaws.<リージョン名>.ssm
    • com.amazonaws.<リージョン名>.ssmmessages
    • com.amazonaws.<リージョン名>.ssm
  • Secrets Manager
    • com.amazonaws.<リージョン名>.secretsmanager

試してみた

ここまでを踏まえて実際に環境を作っていきます。

0. 前提条件

私の検証アカウントの東京リージョンで環境構築を行います。
VPC環境は事前に構築済みでRDSを作るサブネットからインターネットアクセス可能としています。

ざっくりイメージとしては下図の様な形になります。

今回はAWS CLI (Ver.2.4.4) on PowerShell 7.2.0の環境でCLIメインで環境を作っていきます。

C:\> aws --version
aws-cli/2.4.4 Python/3.8.8 Windows/10 exe/AMD64 prompt/off
C:\> $PSVersionTable | Select-Object -ExpandProperty PSVersion

Major  Minor  Patch  PreReleaseLabel BuildLabel
-----  -----  -----  --------------- ----------
7      2      0

1. 事前準備 (IAM Role)

まずは事前準備を行います。

公開されているcustom-sqlserver-iam.jsonからCFn Stackを作成します。

$template = Invoke-WebRequest -Uri https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/images/custom-sqlserver-iam.json |
    Select-Object -ExpandProperty Content
aws cloudformation create-stack --stack-name "my-custom-rds-sql-server-role" `
    --template-body "$($template -replace '"','\"' )" `
    --capabilities 'CAPABILITY_NAMED_IAM'

このStackによりAWSRDSCustomSQLServerInstanceRole-<リージョン名>という名のIAM Roleと同名のインスタンスプロファイルが作成されます。

このロールにはざっくり以下の権限が含まれています。

  • SSM関連の権限 (SSM Session接続、パッチ適用など)
  • EC2関連の権限 (EBSスナップショット作成)
  • S3関連の権限 (do-not-delete-rds-customで始まる名前のバケットに対する権限)
  • Secrets Managerの権限 (do-not-delete-rds-customで始まるシークレットに対する権限)
  • CloudWatch Metricsの権限 (rdscustom/rds-custom-sqlserver-agent名前空間のメトリクス)
  • CloudWatch Logsの権限 (rds-custom-instance-で始まるロググループに対する権限)

2. 事前準備 (Custom KMS Key)

次にRDS Custom用のキーを作ります。
対称キーであればその他の条件は問われない様です。今回は念のためマルチリージョンキーでmy-custom-rds-sql-server-keyという名前のエイリアスを割り当てることにします。

# キー作成
$result = aws kms create-key --description 'Key for RDS Custom for SQL Server' `
    --key-usage 'ENCRYPT_DECRYPT' `
    --origin 'AWS_KMS' `
    --multi-region `
    --output json
Write-Output ($result | ConvertFrom-Json).KeyMetadata

# エイリアスの割り当て
aws kms create-alias --alias-name 'alias/my-custom-rds-sql-server-key' `
    --target-key-id (($result | ConvertFrom-Json).KeyMetadata.KeyId)

なお、既存の対称キーがある環境であればそれを流用しても構いません。

3. RDS Custom for SQL Serverの作成 (パラメーター関連)

RDS Custom for SQL ServerではRDSのパラメーターで事前にサブネットグループは用意しておく必要がありますが、制限事項で触れた通りパラメーターグループ、オプショングループは使用できません。

このため事前にサブネットグループのみ用意しておきます。
今回はmy-custom-rds-sql-server-dbsgという名前で作っておきます。

# サブネットグループ 
$subnetId1 = 'subnet-1234567890' # Set your subnet id1
$subnetId2 = 'subnet-1111111111' # Set your subnet id2
aws rds create-db-subnet-group --db-subnet-group-name 'my-custom-rds-sql-server-dbsg' `
    --db-subnet-group-description 'Subnet group for RDS Custom for SQL Server' `
    --subnet-ids "[\`"$subnetId1\`",\`"$subnetId2\`"]"

ちなみにAWS的にはcustom-sqlserver-<エディション>-<エンジンバージョン>パラメーターグループファミリーが事前定義されていますがユーザーが利用することはできません。

4. RDS Custom for SQL Serverの作成 (インスタンス)

ここから実際にRDS Custom for SQL Serverのインスタンスを作成していきます。
現時点ではSQL Server 2019のEnterprise Edition、Standard Edition、Web Editionが作成可能となっています。

まずは通常のRDSとの違いを確認するのも兼ねてマネジメントコンソールから作ってみます。

エンジンタイプで「Microsoft SQL Server」を選択すると新しくマネジメントタイプの選択が増えており「Amazon RDS Custom」を選択可能になっています。

今回は「Standard Edtion」で作ることにします。

インスタンス識別子などは従来通りよしなに設定、

接続情報も変わりありません。

次にRDS Custom用のIAMロールおよびKSMキーを指定します。
事前準備で用意したIAMロール及びCustom KMS Keyを指定します。

追加のバックアップ設定などはよしなに設定し「データベースの作成」をクリックします。

あとはRDSインスタンスが出来上がるまでしばらく待ちます。

エラー無く作成完了するとこんな感じになります。

CLIからの作成

CLIからRDS Custom for SQL Serverを作成する場合はaws rds create-db-instanceコマンドを使います。
--custom-iam-instance-profileパラメーター以外は大体通常RDSと同じ感じです。

$securityGroupId = 'sg-1234567890'
aws rds create-db-instance `
	--engine 'custom-sqlserver-se' `
	--engine-version '15.00.4073.23.v1' `
	--db-instance-identifier 'my-custom-rds' `
	--db-instance-class 'db.m5.xlarge' `
	--allocated-storage 20 `
	--db-subnet-group 'my-custom-rds-sql-server-dbsg' `
    --vpc-security-group-ids "$securityGroupId" `
	--master-username 'admin' `
	--master-user-password 'mycustomrdspassword' `
	--no-multi-az `
	--port 1433 `
	--kms-key-id 'alias/my-custom-rds-sql-server-key' `
	--custom-iam-instance-profile 'AWSRDSCustomSQLServerInstanceProfile-ap-northeast-1'

接続確認など

RDS Customの場合作成されたインスタンスはEC2インスタンスの形で存在します。
do-not-delete-rds-custom-で始まるインスタンスがそれに該当します。

AWS管理アカウントにあるRDS Custom用のAMIを利用者のアカウントに共有して使う形となっています。

また同時にdo-not-delete-rds-custom-で始まるキーペアも作成されます。
このキーペアの内容はSecrets Managerにdo-not-delete-rds-custom-rdp-privatekey-で始まる名前で登録されています。

この秘密鍵からAdministratorの初期パスワードを取得可能です。

RDS CustomではSSMが使えますのでSSM Sessionでコンソール接続、ポートフォーワードでRDP接続することができます。
不具合なのか制限事項なのかわかりませんでしたが、SSM Fleet ManagerからのRDP接続は内部エラーとなってしまいました。

RDPでインスタンス内部に入るとこんな感じです。
あとはよしなに必要なカスタマイズを行う形となります。

データベース内部設定の差異などは詳しい方にお任せします...

最後に

簡単ですが以上となります。

今回はとりあえず作ってみるまでを試しましたが実際にRDS Customの採用を考える場合は他にも多くの考慮事項があります。
以下のドキュメントを読み込んだ上で実際に利用すべきかを検討してください。

脚注

  1. 手動スナップショットからの復元などで発生