RDS Customを使ってみた（SQL Server編）

# 1. はじめに

[前の記事](https://qiita.com/kenichi_matsunaga/items/467a92d4713da3ffcfcd)ではRDS Custom for Oracle, SQL Serverについて、主に環境面でRDSとの比較を行いました。今回の記事では実際にRDS Customを操作しながら、構築や運用の観点でRDSとの比較を行います。ただ、RDS Custom for Oracleは利用するためのEnterprise Editionのライセンスが用意できないので、RDS Custom for SQL Serverのみを対象にします。

なお、本記事は2022年3月上旬時点での確認結果を元に記載しています。他のAWSサービスと同様にRDS Customでも機能追加・改善され、本記事の内容と合わなくなるケースもあると思いますので、ご注意ください。

RDSとの比較に関する内容となるため、RDSについてある程度の知識や操作経験がある読者を前提としています。

:::note warn
注意
RDS Customはマネージドサービスではありますが、OSやDBを直接操作・設定変更できてしまいます。今回は動作検証ということで、マニュアルに記載のない操作も実行していますが、AWSサポートへ確認はしておらずサポートされていない操作の可能性があります。みなさまが本番環境で利用する場合は、サポートされる構成・操作であることを事前に[最新マニュアル](https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/rds-custom.html)やAWSサポートで確認してください。
:::


# 2. RDS Custom for SQL Serverの構築

RDS CustomでもRDSと同様に、OS・DBMSのインストールとDB作成はAWSコンソールやAWS CLIを使って簡単に短時間で実行できます。
今回は[RDSマニュアル](https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/rds-custom.html)に沿って構築していきます。

### (1) RDS Custom for SQL Server の環境設定

RDS CustomではRDSに比べて事前作成が必要なリソースがたくさんあるので、計画立てて準備しましょう。具体的には、RDSマニュアルの「[Amazon RDS Custom for SQL Server の環境設定](https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/custom-setup-sqlserver.html)」に記載の下記リソースが必要です。いくつかのリソースはRDSマニュアルで提供されるCloudFormationテンプレート([custom-sqlserver-iam.json](https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/images/custom-sqlserver-iam.json), [custom-vpc.json](https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/images/custom-vpc.json))で作成可能です。本記事ではこれらのテンプレートを使ってリソースを作成する方針とします。

| 必要リソース | 説明 |
|:-----|:-----|
| VPC、サブネット| RDS Customを配置するVPCとサブネットを作成します。マルチAZ構成としない場合でもサブネットは複数AZに作成しておく必要があります。また、CFnテンプレート「custom-vpc.json」で作成するVPCエンドポイントはDNS名有効化で設定するので、VPCはDNSホスト名・DNSサポートを有効化しておきましょう。 | 
| ルートテーブル | マニュアルには明記されていませんが、RDS Customを配置するサブネットには専用のルートテーブルを作成しておいた方がいいです。CFnテンプレート「custom-vpc.json」でS3ゲートウェイエンドポイントを作成するので、ルートテーブルに更新が入るためです。 | 
| カスタマー管理型の対称型KMSキー | RDSはAWSマネージド型キーを使用できましたがRDS Customはサポートしないので、カスタマー管理型の対称型KMSキーを作成しておく必要があります。 |
| IAMロール、インスタンスプロファイル | RDS Custom for SQL Serverインスタンス向けのIAMロール・インスタンスプロファイルを作成します。CFnプロファイル「custom-sqlserver-iam.json」で作成できます。 | 
| セキュリティグループ | RDS Custom for SQL Serverインスタンスに割り当てるセキュリティグループです。インバウンドではSQL Serverへの接続に加え、OS(Windows)へのRDP接続するための設定が必要です。アウトバウンドでは各種エンドポイントへの接続や運用で必要な通信の設定をしておきましょう。 | 
| サブネットグループ | これもマニュアルには明記されていませんが、RDSと同様にサブネットグループを事前に作成しておく必要があります。CFnテンプレート「custom-vpc.json」で作成されます。 | 
| VPCエンドポイント | RDSではCloudWatchなど他のAWSサービスとの連携は利用者からは見えないところで設定がされていましたが、RDS Customでは利用者が明示的に設定する必要があります。具体的にはNATゲートウェイなどを作成してパブリックIP経由で接続するか、VPCエンドポイントを作成して接続するかを選択します。今回はCFnテンプレート「custom-vpc.json」で以下のサービス向けのVPCエンドポイントを作成します。<BR> ・Systems Manager : ssm, ssmmessages <BR> ・Secrets Manager : secretsmanager <BR> ・CloudWatch : events, logs, monitoring <BR> ・EC2 : ec2, ec2messages <BR> ・S3 : s3 | 

### (2) RDS Custom for SQL Serverインスタンスの作成

事前の環境設定の完了後、[RDS Custom for SQL Serverインスタンスを作成](https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/custom-creating-sqlserver.html#custom-creating-sqlserver.create)できますが、RDSの経験があれば特に迷うことなく作成できるでしょう。RDSにはなかったRDS Custom for SQL Serverに特有の設定項目は以下のとおりです。

<dl>
  <dt>・IAMインスタンスプロファイル </dt>
  <dd> 環境設定で事前に作成したインスタンスプロファイルを設定しましょう。 </dd>
  <dt>・RDS Customオートメーションモード </dt>
  <dd> DBの監視・自動復旧の設定で、インスタンス作成時は「完全なオートメーション」のみ設定可能です。（「3. RDS Custom for SQL Serverの運用」に詳細を記載します。） </dd>
</dl>

RDS Custom for SQL Serverインスタンスを作成すると、RDSコンソールにはロールが「インスタンス(RDS Custom)」というインスタンスが表示されます。インスタンス作成から、作成完了してステータスが「利用可能」状態になるまでには30分ぐらいかかりました。

RDS Custom for SQL Serverインスタンスの作成により、以下のリソースも作成されます。RDSでも作成されていたけど利用者からは参照できなかったリソースもあれば、RDS Custom特有のリソースもあります。

| リソース | 説明 |
|:-----|:-----|
| EC2 | 「do-not-delete-rds-custom-\<DB識別子\>」という名前のEC2インスタンスが表示されます。OSへセッションマネージャでCLI接続する場合や、EC2インスタンスIDが必要になる場合はここを参照します。 |
| EBS | 「do-not-delete-rds-custom-\<DB識別子\>-root」「do-not-delete-rds-custom-\<DB識別子\>-storage」という名前の2つのEBSボリュームが表示されます。前者はシステム領域でgp3/40GB、後者はデータ領域で指定した設定で作成されます。 |
| スナップショット | 「do-not-delete-rds-custom-rds:\<DB識別子\>-\<yyyy-mm-dd-HH-MM\>」という名前で、RDS Customのデータ領域のスナップショットが表示されます。|
| キーペア, <BR> Secrets Manager | EC2用のキーペアが「do-not-delete-rds-custom-rdp-privatekey-\<DB識別子\>-\<ランダム値\>」という名前で作成され、キーペアのコンテンツ（RSAプライベートキー）がSecrets Managerに同名のシークレットとして保存されます。<BR> RDS Custom for SQL ServerインスタンスのOSにRDPでログインする際、Administratorユーザのパスワードにこのシークレットを使用します。 |
| CloudWatch | CloudWatch Logsには、ロググループ「rds-custom-instance-agent-log」の下にEC2インスタンスIDのログストリームが作成され、RDS Custom Agentのログが保管されます。DBのエラーログは保管されないようです。<BR> CloudWatchメトリクスには性能情報が保管されますが、RDSではなくEC2で分類されます。 |
| CloudTrail | 「do-not-delete-rds-custom-\<AWSアカウントID\>-\<リージョン名\>-\<ランダム値\>」という名前のCloudTrailの証跡が作成され、下に記載のS3バケットに保管されます。 |
| S3 | 「do-not-delete-rds-custom-\<AWSアカウントID\>-\<リージョン名\>-\<ランダム値\>」という名前のS3バケットが作成されます。この中にはCloudTrailのログと、RDS Customのポイントインタイムリカバリで使用するトランザクションログのバックアップが保管されます。 |

RDSでは参照できなかったリソースが参照・設定変更できる状態になっていますが、設定変更したり削除してしまうとRDS Customインスタンスが正常に動作できなくなることがありますので注意しましょう。


### (3) RDS Custom for SQL Serverインスタンスへの接続

RDS Custom for SQL ServerのDBインスタンスへは、RDSと同様にエンドポイント「\<DB識別子\>.\<ランダム値\>.\<リージョン名\>.rds.amazonaws.com」に対して1433番ポート（もしくは作成時に指定したポート番号）で接続できます。

RDS Custom for SQL ServerのOSへは、EC2(Windows)と同じ方法で接続できます。Systems ManagerのFleet ManagerのようにRDPで接続する場合には、インバウンド3389番ポートを開放する必要があります。[マニュアル](https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/custom-creating-sqlserver.html#custom-creating-sqlserver.rdp)にはセキュリティグループに加えて、OSのWindows Defender Firewallでのポート開放も必要とありますが、Windows Defender Firewallはデフォルトで開放されているようで設定変更しなくても接続できました。OSのAdministratorユーザのパスワードは、Secrets Managerに登録されたシークレット（RSAプライベートキー）を使用します。


### (4) RDS Custom for SQL Serverインスタンスのディスク構成

OSのディスク構成を見て気づいたんですが、EC2インスタンスには2つのEBSボリュームが割り当てられているのに対して、OSではディスクが3つあることを確認できます。下にDisk Management画面とDisk 2のProperties画面の画像と、ディスクの概要を表で示しますが、EBSボリューム以外にDRBD Diskというのが存在します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1736452/2729cd47-41fa-d95b-1510-60024b903c46.jpeg" width="700">

| ディスク | 説明 |
|:--|:--|
| Disk 0 (C:) | EBSボリューム「do-not-delete-rds-custom-\<DB識別子\>-root」に対応するディスクデバイス。 | 
| Disk 1 (W:) | EBSボリューム「do-not-delete-rds-custom-\<DB識別子\>-storage」に対応するディスクデバイス。 WinDRBDを使ってこのディスクを別サーバに同期しているようです。OS上では、W:ドライブは使用できない状態になっています。 |
| Disk 2 (D:) | DRBD Diskと表示されるディスクデバイス。OSから見ると、このディスク上にDBのデータが保管されています。 | 

WinDRBDはクラウドでマルチAZのHAクラスタを構成する場合などに、ディスクをサーバ間でミラーリングするのに使用するツールです。詳細まで確認していませんが、RDS Custom for SQL Serverではデータ領域はWinDRBDを使って別サーバのドライブへデータ同期しているように見えます。RDS Custom for SQL Serverでディスク拡張できない制約があるのは、このあたりが原因なのかなと思います。

サーバ間のディスクミラーリングを行っている場合、ディスクI/Oの性能影響が気になります。性能影響はサーバ間の距離（同一AZ内 / AZまたぎ）や、ミラーリングのモード（同期モード / 非同期モード）などによって変わります。RDS Custom for SQL Serverを使用する場合は、同一インスタンスクラス・ストレージ構成でシングルAZのRDS for SQL ServerとIOPSやレイテンシの比較検証を実施したほうがいいでしょう。


# 3. RDS Custom for SQL Serverの運用

RDS Customの運用に関して、RDSにはないRDS Custom特有の考え方が2つありますので把握しておきましょう。

<dl>
  <dt> ・RDS Customオートメーション </dt>
  <dd> RDS CustomではDBインスタンスの状態を監視して、障害を検知したら自動で復旧しようとします。OSやDBの設定変更で一時的にDB停止する場合などでは、勝手に自動復旧されないようにするためオートメーションの一時停止が必要になります。<BR>オートメーションの一時停止は最小1時間から最大24時間まで分単位で期間指定できます。期間が終わると、自動でオートメーションが再開します。 </dd>
  <dt> ・サポートペリメータ </dt>
  <dd> サポートペリメータはRDS CustomのOSやDBがサポートされる構成かを確認する機能です。サポートされない構成を検知すると、RDS Customインスタンスは「サポートされていない設定」というステータスになります。このステータスになるとすぐにDBが利用不可になるわけではないですが、スナップショットが取得できないなどの制限があります。マニュアルには「サポートペリメータ」でなく「周辺サポート」と記載されている箇所もあるので注意しましょう。 </dd>
</dl>

以下、個々の運用項目について見ていきます。

### (1) RDS Custom for SQL Serverの停止・起動

RDSではコンソール画面からインスタンスの停止・起動を実行できましたが、RDS Custom for SQL Serverではコンソール画面からの停止・起動は実行できません。OSやDBの設定変更のためにDBインスタンスの停止・起動が必要な場合は、OSにログインしてSQL Server構成マネージャなどから実行します。停止する場合は、事前にRDS Customオートメーションモードを「一時停止」にしましょう。

OSの停止・起動について、EC2インスタンス停止・起動とOSシャットダウン・EC2インスタンス起動の2つの方法で試してみました。前者の方法は正常に停止・起動できましたが、後者の方法ではOSシャットダウンを行うとEC2が「終了済み」(EC2を削除した状態) になってしまいました。EC2インスタンスのシャットダウン動作が「終了」となっていたので、これが原因でしょう。この設定を変更していいかはAWSサポートに確認が必要です。変更不可の場合、RDS CustomではOSシャットダウンは実行しないようにしましょう。OSリブートは問題なく実行できました。

なお、RDSでは利用していない時間帯にインスタンスを停止することでコストを削減できましたが、RDS CustomではOS停止中もコストは発生するようです。RDS CustomはEC2停止状態では「サポートされていない設定」というステータスになり、そもそもRDS Customに停止という概念がないようです。いずれにせよ、RDS Customではインスタンス停止によるコスト削減ができないので注意しましょう。



### (2) RDS Custom for SQL Serverのインスタンスクラス変更

RDS Custom for SQL Serverのインスタンスクラスの変更は、RDSと同様にRDSコンソール画面から実行できます。
ということで、インスタンスクラスを変更してみたのですが、バックグラウンドでは以下のような処理が行われるようです。

 1. 既存のEC2インスタンスとは別に、変更後インスタンスクラスの新規EC2インスタンスとEBSボリューム（システム領域のみ）を作成
 1. 既存EC2インスタンスを停止し、データ領域のEBSボリュームを新規EC2インスタンスへ付け替え
 1. 旧EC2インスタンスを削除

上記のような変更方法のため、インスタンスの初期構築以降にシステム領域に対して実行した変更（DBMSへの変更は除く）は引き継がれないようです。動作確認ではシステム領域に作成しておいたファイルがなくなっていました。下に記載するリストアも同様ですが、運用中にシステム領域が初期化されるケースを想定して準備をしておくことが必要です。


### (3) RDS Custom for SQL Serverのストレージ設定変更

RDS Custom for SQL Serverでは、ストレージの設定変更（既存ボリュームの拡張・タイプ変更、新規ボリュームの追加）は不可のようです。EBSボリュームに対して直接変更することはできそうですが、やらない方がいいでしょう。

なお、プロビジョンドIOPS(io1)を使用している場合、DBのリストア時にIOPSのみ変更することが可能です。


### (4) RDS Custom for SQL Serverのパッチ適用

RDS Custom for SQL ServerインスタンスでのSQL Serverのパッチ適用は、RDSと同様にRDSコンソールから実行できます。ただ、2022年3月上旬時点では、SQL Serverのパッチレベルは1つしか選択できないので、パッチ適用の動作確認はできない状況です。RDSと比較すると、現時点でRDS for SQL Serverで適用可能なパッチの最新レベル（SQL Server 2019 15.00.4153.1.v1）は、RDS Custom for SQL Serverでは適用可能になっていません。このようにRDSとRDS Customで最新パッチレベルにタイムラグがあることも、RDS Custom利用時の制約となります。

また、実際にSQL Serverパッチ適用を実施できていないため未確認ではありますが、既存のDBに対してパッチ適用を行うのではなく、インスタンスクラス変更のようにパッチ適用後のAMIから作成したシステム領域のEC2インスタンスに入れ替えるという処理が実行される可能性があります。どちらの処理が実行されるかで運用が大きく変わるので、新しいパッチが利用可能になったら動作確認した方がいいです。


OSのパッチについて、EC2(Windows)と同様にWindows Updateで実行できるかなと思ったのですが、下の画面のようにGroup Policyで禁止されているようでアップデートできませんでした。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1736452/b297e68e-9f6b-d8bf-92f8-52abe88b22bc.jpeg" width="500">

OSの設定を変更すればアップデートできるようになると思いますが、変更はしない方がいいかなと思います（サポート未確認ですが）。この場合、OSに対して個別パッチの適用はできず、SQL Serverのパッチ適用と同時にAWSが選定したOSパッチを適用することしかできなさそうです。

### (5) RDS Custom for SQL Serverのバックアップ・リストア

RDS Custom for SQL Serverのバックアップは、RDSと同様に自動バックアップ・手動スナップショットを取得可能です。リストアもRDSと同様にスナップショットからの復元と特定時点への復元(PITR)が可能で、既存インスタンスのDBを置き換えるのではなく、新規にRDS Custom for SQL Serverインスタンスを作成します。

RDS Custom for SQL Serverではシステム領域はバックアップ対象にはなりません。リストアではシステム領域が新規に作成され、データ領域がバックアップからリストアされます。DBMSの設定変更はデータ領域にエクスポートされるので、リストア時に自動反映されます。この仕様はRDSでは問題なかったのですが、利用者がシステム領域を変更できるRDS Customでは大きな問題になります。

既存インスタンスでシステム領域に対して実施していた設定変更は、リストア後に再度実施する必要があります。実運用を考えるとシステム領域に対する設定はスクリプト化するなどして、できるだけ手動操作なくすべての設定を完了できるようにした方がよさそうです。また、本番稼働後に実施した設定変更も漏れなくスクリプト/手順に反映させる必要があり、運用はかなり大変になりそうです。

ちなみに、[マニュアル](https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/custom-reqs-limits.html#custom-reqs-limits.limitsMS)には、RDS Custom for SQL Serverの制限として「Microsoft Windows オペレーティングシステムまたは C: ドライブへの変更は、Amazon EC2 インスタンスを交換すると保持されません。」とあり、リストアやインスタンスタイプ変更がこれに該当するのかなと思います。RDS Custom for Oracleに関してはこのような記載はないので、RDS Custom for Oracleではシステム領域まで含めてバックアップ・リストアできるのかもしれません。


### (6) RDS Custom for SQL Serverの監視

RDS for SQL Serverではインスタンス作成時にエラーログをCloudWatch Logsへエクスポートする設定が可能でしたが、RDS Custom for SQL Serverではインスタンス作成時に設定することはできません。ただ、OSの設定変更は可能なので、手動でCloudWatch Agentを設定してCloudWatchへ連携して監視したり、監視ツールをOSに導入して直接エラーログを監視することはできそうです（確認してませんが。。。）。

RDS Custom for SQL Serverのメトリクス監視について、デフォルトではEC2で取得可能なメトリクスのみが詳細モニタリングでCloudWatchに記録されます。RDSで取得できていたDB接続数や空きストレージ容量はデフォルトでは記録されません。特に空きストレージ容量については、ストレージがオートスケール不可のため容量不足にならないよう、CloudWatch Agentや監視ツールを使って監視設定を行う必要があるでしょう。また、RDS CustomではPerformance Insightsは利用できないので、必要に応じてDBの性能分析ができるツールを導入しましょう。


# 4. おわりに

今回の記事では、RDS Custom for SQL Serverを操作しながら構築や運用についてRDSとの比較を行いました。[前の記事](https://qiita.com/kenichi_matsunaga/items/467a92d4713da3ffcfcd)での環境面の比較と同様、やっぱりRDS Customには制約が多いなという印象です。


特にリストアなどによりシステム領域が初期化されてしまうケースがあるのは非常に大きな制約で、運用への影響が大きいと思います。このあたりが改善されると、使用できるケースが増えるのかなと思います。

以上、2022年3月上旬時点の調査結果ではありますが、RDSかRDS Customのどちらを採用するか、もしくはEC2にSQL Serverを導入して利用するかを検討する際の参考になればと思います。


***

 - AWS は、米国その他の諸国における Amazon.com, Inc. またはその関連会社の商標です。
 - その他、本資料に記述してある会社名、製品名は、各社の登録商品または商標です。