投稿

AWS SQL Server 構築チュートリアル:作成から接続までの実践手順

AWSでRDS for SQL Serverを作成する手順を、DBサブネットグループ、DBパラメータグループ、オプショングループ、ストレージ、接続、バックアップ、Terraformまで整理します。

AWS SQL Server 構築チュートリアル:作成から接続までの実践手順

SQL Server は、エンタープライズシステムでよく使われるリレーショナルデータベースです。オンプレミス環境や VM で運用する場合、DBA やシステム管理者が SQL Server をインストールし、OS を調整し、バックアップを計画し、監視を設定してから、アプリケーションに利用させる流れが一般的です。

AWS 上では、これらの作業をすべて自分たちで抱える必要はありません。特別な OS 権限、RDS がサポートしていない SQL Server 機能、または独自のライセンス要件がなければ、Amazon RDS for SQL Server のほうが運用しやすい選択肢になることが多いです。RDS は基盤ホスト、ストレージ、バックアップ、メンテナンスウィンドウ、監視連携、高可用性機能を管理しやすくしてくれるため、チームはデータモデル、クエリ性能、アクセス制御、復元訓練により多くの時間を使えます。

この記事では、RDS for SQL Server DB インスタンスを作成する手順を、次の 2 つの方法で整理します。

  • AWS マネジメントコンソールで作成する。
  • Terraform で基本リソースを作成する。

例は開発環境またはテスト環境を想定しています。本番環境では、データ量、RPO、RTO、セキュリティ要件、可用性要件に応じて設計を調整してください。

RDS for SQL Server でサポートされるバージョンは、AWS と Microsoft のサポートポリシーに応じて変わります。実装時は、対象リージョンの AWS マネジメントコンソール、または aws rds describe-db-engine-versions の結果を正としてください。

事前に確認すること

RDS を作成する前に、まず次の項目を確認しておくことをおすすめします。

項目確認内容
VPC とサブネットDB をどの VPC に配置するか、プライベートサブネットのみに配置するか
セキュリティグループどの送信元から SQL Server の 1433 port に接続できるか
SQL Server バージョンアプリケーションが対応している SQL Server major/minor version
エディションExpress、Web、Standard、Enterprise の機能とライセンス差異
ストレージ容量初期容量、最大容量、IOPS、Throughput、成長速度
バックアップAutomated Backup のバックアップ保持期間、PITR や AWS Backup が必要か
メンテナンスウィンドウメンテナンスやバージョン更新をいつ適用できるか
パラメータとオプションカスタム DB パラメータグループやオプショングループが必要か

これらは事前準備の細かい確認に見えますが、データベースで怖いのは、作成後にネットワーク配置が間違っている、バージョンが合わない、バックアップ戦略が要件を満たしていない、またはセキュリティグループを広く開けすぎていることに気づくケースです。

方法 1:AWS マネジメントコンソールで作成する

AWS マネジメントコンソールで RDS のページを開きます。

Amazon and RDS dashboard page

RDS の作成フロー自体は難しくありません。ただし、最初は次の「グループ」の違いが混ざりやすいです。

  • DB サブネットグループ:RDS が利用できるサブネットを決める。
  • DB パラメータグループ:データベースエンジンのパラメータを管理する。
  • オプショングループ:SQL Server のネイティブバックアップおよび復元など、エンジン固有の追加機能を有効化する。
  • セキュリティグループ:DB に接続できる送信元を制御する。

以下では、構築順にそれぞれ作成します。

DB サブネットグループを作成する

RDS を初めて構築する場合は、通常 DB サブネットグループから設計します。

VPC 内に複数のサブネットがあっても、すべてのサブネットがデータベース配置に適しているわけではありません。一般的に、データベースをパブリックサブネットに直接配置したり、インターネットから直接到達できるようにしたりするべきではありません。よくある構成は、複数のアベイラビリティーゾーンにまたがるプライベートサブネットに RDS を配置し、アプリケーションのセキュリティグループまたは内部ネットワーク範囲からのみ接続を許可する方法です。

新しい環境では、DB サブネットグループの一覧が空の場合があります。そのまま作成ボタンを押して開始します。

RDS Subnet Group list page

作成ページでは、まず VPC を選択します。VPC を選択すると、その VPC 配下のアベイラビリティーゾーンとサブネットを選べるようになります。

RDS Subnet Group create page

少なくとも 2 つの異なるアベイラビリティーゾーンのプライベートサブネットを選ぶことをおすすめします。将来マルチ AZ を有効化する場合や、メンテナンスおよびフェイルオーバーの場面で、RDS の高可用性設計に合わせやすくなります。

Subnet Group create sample

作成が完了すると、DB サブネットグループが一覧に表示されます。

Subnet Group create result

DB パラメータグループを作成する

各データベースエンジンには調整可能なパラメータがあります。自前運用の SQL Server であれば、SQL Server Management Studio、T-SQL、またはホストレベルの設定で調整することがあります。しかし RDS では基盤 OS に直接ログインできず、完全な sysadmin 権限も得られません。そのため、RDS が許可しているパラメータは DB パラメータグループで管理します。

まだカスタム DB パラメータグループがない場合、一覧は空です。

RDS Parameter Group list page

作成を選択すると、DB パラメータグループの作成ページに進みます。

RDS Parameter Group create page

DB パラメータグループは、データベースエンジンと major version に紐づきます。つまり SQL Server 2019 と SQL Server 2022 では、それぞれ互換性のある parameter group family を使う必要があります。作成時は、これから作成する RDS のバージョンに合う family を選択してください。

RDS Parameter Group create sample

作成後、DB パラメータグループの一覧に表示されます。

RDS Parameter Group create result

一部のパラメータ変更はすぐに適用できますが、DB の再起動が必要なものもあります。本番環境で変更する前に、非本番環境で検証し、メンテナンスウィンドウを確認してください。

オプショングループを作成する

オプショングループは、RDS の設定の中でも見落とされやすいものです。一般的なデータベースパラメータではなく、特定のデータベースエンジン向けの追加機能を有効化するために使います。

SQL Server の場合、ネイティブバックアップおよび復元を使って .bak ファイルを S3 にバックアップしたり、S3 から復元したりするには、オプショングループに SQLSERVER_BACKUP_RESTORE オプションを追加し、S3 権限を持つ IAM ロールを RDS に使わせる必要があります。

RDS Option Group list page

オプショングループを作成するときも、SQL Server エンジンと対応するバージョンを選択します。

RDS Option Group create page

デモでは、まず空のオプショングループを作成しても構いません。後でネイティブバックアップおよび復元が必要になったら、SQLSERVER_BACKUP_RESTORE を追加します。

RDS Option Group create sample

作成が完了すると、オプショングループが一覧に表示されます。

RDS Option Group create result

RDS の Automated Backup と PITR だけを使う場合、SQL Server のネイティブバックアップおよび復元は必須ではありません。.bak ファイルのインポート/エクスポートや、既存の SQL Server バックアップ運用と接続したい場合に、このオプションを検討します。

SQL Server のオプショングループを設定する

この RDS for SQL Server DB インスタンスでネイティブバックアップおよび復元を使う場合、つまり SQL Server の .bak ファイルを S3 に置いて RDS に復元したり、RDS から .bak を S3 にバックアップしたりする場合は、空のオプショングループだけでは足りません。

この機能では、次の 3 つのコンポーネントを接続する必要があります。

コンポーネント用途
S3 バケットSQL Server の .bak バックアップファイルを保存する
IAM ロールとポリシーRDS が指定した S3 バケットを読み書きできるようにする
オプショングループSQLSERVER_BACKUP_RESTORE を追加し、IAM role ARN を指定する

設定順序は次のようになります。

  1. SQL Server バックアップファイル専用の S3 バケットを作成する。
  2. IAM ロールを作成し、信頼関係で rds.amazonaws.com がロールを引き受けられるようにする。
  3. IAM ロールに S3 アクセス権限ポリシーをアタッチする。
  4. SQL Server のオプショングループに SQLSERVER_BACKUP_RESTORE を追加する。
  5. オプション設定 IAM_ROLE_ARN に IAM role ARN を指定する。
  6. RDS DB インスタンスを作成または変更し、このオプショングループを SQL Server にアタッチする。

S3 バケットは RDS DB インスタンスと同じリージョンに置くことをおすすめします。RDS for SQL Server のネイティブバックアップおよび復元では、別リージョンの S3 バケットへのバックアップまたは別リージョンの S3 バケットからの復元はサポートされていません。バックアップファイルが別リージョンにある場合は、S3 Replication などで RDS と同じリージョンへ先にコピーします。

IAM ロールの信頼関係は、次の考え方で設定できます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "rds.amazonaws.com"
      },
      "Action": "sts:AssumeRole",
      "Condition": {
        "StringEquals": {
          "aws:SourceAccount": "<account-id>"
        },
        "ArnLike": {
          "aws:SourceArn": [
            "arn:aws:rds:<region>:<account-id>:db:<db-instance-id>",
            "arn:aws:rds:<region>:<account-id>:og:<option-group-name>"
          ]
        }
      }
    }
  ]
}

S3 アクセス権限ポリシーでは、少なくとも RDS がバケットを一覧表示し、バケットの場所を取得し、バックアップオブジェクトを読み書きできる必要があります。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:ListBucket",
        "s3:GetBucketLocation"
      ],
      "Resource": "arn:aws:s3:::<bucket-name>"
    },
    {
      "Effect": "Allow",
      "Action": [
        "s3:GetObjectAttributes",
        "s3:GetObject",
        "s3:PutObject",
        "s3:ListMultipartUploadParts",
        "s3:AbortMultipartUpload"
      ],
      "Resource": "arn:aws:s3:::<bucket-name>/<prefix>/*"
    }
  ]
}

バックアップファイルを KMS で暗号化する場合は、IAM ロールに対象 KMS key への kms:DescribeKeykms:GenerateDataKeykms:Encryptkms:Decrypt を追加し、KMS key policy でもこの IAM ロールの利用を許可する必要があります。

専用 bucket、または少なくとも sqlserver-native-backup/ のような専用 prefix を使うことをおすすめします。prefix を空にすると、複数ファイル復元時に RDS が bucket 内の無関係なファイルまで対象にする可能性があり、トラブルシューティングが面倒になります。

データベースを作成する

DB サブネットグループ、DB パラメータグループ、オプショングループを用意したら、RDS DB インスタンスを作成できます。

RDS Database list page

データベースの作成を選ぶと、コンソールには多くの設定項目が表示されます。データベースのネットワーク、セキュリティ、バックアップ、メンテナンスウィンドウは明示的に設定したほうがよいため、簡略化されたデフォルトフローではなく、完全な設定フローを使うことをおすすめします。

RDS Database create page

設定例は次のとおりです。

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
エンジンオプション
> SQL Server

テンプレート
> 開発/テスト

設定
> データベース管理タイプ
>> Amazon RDS

> エディション
>> SQL Server Express Edition

> エンジンバージョン
>> コンソールで現在サポートされているバージョンを選択。例:SQL Server 2022

> DB インスタンス識別子
>> sql-server-express-demo

認証情報の設定
> マスターユーザー名
>> admin

> 認証情報管理
>> セルフマネージド、または会社標準に応じて Secrets Manager

> マスターパスワード
>> 強力なパスワードを設定

ここではデモとテストのために Express Edition を使っています。本番環境では、機能要件、ライセンス、データベースサイズ、性能要件に応じて適切なエディションを選んでください。

DB インスタンスクラスについては、開発環境やテスト環境であれば小さめの t クラスから始められます。

1
2
3
DB インスタンスクラス
> バースト可能クラス
>> db.t3.small

ただし本番環境では CPU と Memory だけで判断しないでください。SQL Server の workload は、IOPS、Throughput、接続数、TempDB 使用量、クエリパターン、ロック動作の影響を受けやすいです。既存環境の監視データを使って、必要なスペックを見積もることをおすすめします。

ストレージを設定する

ストレージ設定は特に注意が必要です。初期容量だけでなく、ストレージの自動スケーリングを有効化するか、IOPS や Throughput を指定する必要があるかも考えます。

RDS Database create page storage spec

少なくとも次を確認してください。

  • 初期容量が現在のデータ量と短期的な成長に足りているか。
  • 最大ストレージ容量が予算とリスク管理に合っているか。
  • gp3 で IOPS / Throughput を指定する必要があるか。
  • FreeStorageSpace に対する CloudWatch Alarm を作成するか。

ストレージの自動スケーリングは、データベース容量不足のリスクを下げられます。ただし容量計画の代替ではありません。RDS ストレージは拡張後に直接縮小できないため、成長が制御できない場合は、最終的にコストとガバナンスの問題になります。

接続とセキュリティグループを設定する

接続設定では、先ほど作成した DB サブネットグループ を選択します。

RDS Database create page connection

セキュリティグループのルールを 0.0.0.0/0 に開かないでください。SQL Server のデフォルト接続 port は 1433 です。許可する送信元は、必要なものだけにします。

  • アプリケーションサーバーのセキュリティグループ。
  • Bastion Host または VPN のセキュリティグループ。
  • 会社の内部ネットワーク範囲。ただし、より厳格なネットワーク制御と組み合わせること。

開発やテストであれば、一時的に VPC CIDR から 1433 への接続を許可する場合もあります。本番環境では、ネットワーク範囲全体を開けるより、セキュリティグループ参照を使ってアプリケーションリソースに追従するルールにするほうがよいです。

監視、バックアップ、メンテナンスを設定する

監視は、まず CloudWatch のデフォルトメトリクスから始められます。より細かい OS レベルのメトリクスが必要な場合は Enhanced Monitoring を有効化します。DB load、待機イベント、SQL レベルのボトルネックを確認したい場合は、Performance Insights または CloudWatch Database Insights を有効化します。

RDS Database create page addition config

その他の設定では、次も確認します。

  • 先ほど作成した DB パラメータグループを選択しているか。
  • 先ほど作成したオプショングループを選択しているか。
  • バックアップ保持期間が要件を満たしているか。
  • バックアップウィンドウがピーク時間を避けているか。
  • メンテナンスウィンドウが運用時間帯に合っているか。
  • 削除保護を有効化する必要があるか。
  • タイムゾーンと照合順序がアプリケーション要件に合っているか。

タイムゾーンと照合順序は、作成後に簡単に変更できるとは限りません。特に照合順序は、並べ替え、比較、大文字小文字の扱いに影響します。本番環境では、アプリケーション、レポート、既存データベースの設定と先に合わせてください。

設定を確認したら作成し、RDS のステータスが Available になるまで待ちます。作成後、エンドポイントを取得し、SQL Server Management Studio、Azure Data Studio、DBeaver、またはアプリケーションから接続をテストします。

接続情報はおおよそ次の形です。

1
2
3
4
5
Server / Host: <rds-endpoint>
Port: 1433
User: admin
Password: 作成時に設定したパスワード
Database: 必要に応じて指定、またはまず既定のデータベースに接続

接続できない場合は、まず次を確認します。

  1. RDS が Available になっているか。
  2. Client が許可されたネットワーク位置にあるか。
  3. セキュリティグループの inbound が送信元から 1433 への接続を許可しているか。
  4. Route table、NACL、VPN、Bastion が正しいか。
  5. SQL Server のユーザー名とパスワードが正しいか。
  6. DNS が RDS エンドポイントを解決できるか。

方法 2:Terraform で作成する

本番環境のインフラを Terraform で管理している場合は、RDS も Terraform に含めることをおすすめします。AWS マネジメントコンソールでの変更による設定ドリフトを避けやすくなります。

以下は、DB サブネットグループ、DB パラメータグループ、セキュリティグループ、S3 バケット、IAM ロール、オプショングループ、RDS DB インスタンスの関係を示す簡略化した例です。実環境では、VPC、Subnet、KMS、パスワード、Tag、命名規則を既存モジュールに接続してください。

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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
data "aws_caller_identity" "current" {}

data "aws_region" "current" {}

variable "vpc_id" {
  type = string
}

variable "private_subnet_ids" {
  type = list(string)
}

variable "app_security_group_id" {
  type = string
}

variable "db_password" {
  type      = string
  sensitive = true
}

variable "backup_bucket_name" {
  type = string
}

variable "backup_prefix" {
  type    = string
  default = "sqlserver-native-backup"
}

resource "aws_db_subnet_group" "sqlserver" {
  name       = "sqlserver-demo-subnet-group"
  subnet_ids = var.private_subnet_ids

  tags = {
    Name = "sqlserver-demo-subnet-group"
  }
}

resource "aws_security_group" "sqlserver" {
  name        = "sqlserver-demo-sg"
  description = "Allow application access to RDS SQL Server"
  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"]
  }
}

resource "aws_s3_bucket" "sqlserver_backup" {
  bucket = var.backup_bucket_name

  tags = {
    Name = var.backup_bucket_name
  }
}

resource "aws_s3_bucket_public_access_block" "sqlserver_backup" {
  bucket = aws_s3_bucket.sqlserver_backup.id

  block_public_acls       = true
  block_public_policy     = true
  ignore_public_acls      = true
  restrict_public_buckets = true
}

resource "aws_iam_role" "sqlserver_backup_restore" {
  name = "rds-sqlserver-backup-restore"

  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
          }
          ArnLike = {
            "aws:SourceArn" = [
              "arn:aws:rds:${data.aws_region.current.name}:${data.aws_caller_identity.current.account_id}:db:*",
              "arn:aws:rds:${data.aws_region.current.name}:${data.aws_caller_identity.current.account_id}:og:*"
            ]
          }
        }
      }
    ]
  })
}

resource "aws_iam_policy" "sqlserver_backup_restore" {
  name = "rds-sqlserver-backup-restore-s3"

  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Effect = "Allow"
        Action = [
          "s3:ListBucket",
          "s3:GetBucketLocation"
        ]
        Resource = aws_s3_bucket.sqlserver_backup.arn
      },
      {
        Effect = "Allow"
        Action = [
          "s3:GetObjectAttributes",
          "s3:GetObject",
          "s3:PutObject",
          "s3:ListMultipartUploadParts",
          "s3:AbortMultipartUpload"
        ]
        Resource = "${aws_s3_bucket.sqlserver_backup.arn}/${var.backup_prefix}/*"
      }
    ]
  })
}

resource "aws_iam_role_policy_attachment" "sqlserver_backup_restore" {
  role       = aws_iam_role.sqlserver_backup_restore.name
  policy_arn = aws_iam_policy.sqlserver_backup_restore.arn
}

resource "aws_db_parameter_group" "sqlserver" {
  name   = "sqlserver-demo-parameter-group"
  family = "sqlserver-ex-16.0"

  tags = {
    Name = "sqlserver-demo-parameter-group"
  }
}

resource "aws_db_option_group" "sqlserver" {
  name                     = "sqlserver-demo-option-group"
  option_group_description = "Option group for SQL Server demo"
  engine_name              = "sqlserver-ex"
  major_engine_version     = "16.00"

  option {
    option_name = "SQLSERVER_BACKUP_RESTORE"

    option_settings {
      name  = "IAM_ROLE_ARN"
      value = aws_iam_role.sqlserver_backup_restore.arn
    }
  }

  tags = {
    Name = "sqlserver-demo-option-group"
  }

  depends_on = [
    aws_iam_role_policy_attachment.sqlserver_backup_restore
  ]
}

resource "aws_db_instance" "sqlserver" {
  identifier = "sqlserver-express-demo"

  engine         = "sqlserver-ex"
  engine_version = "16.00"
  license_model  = "license-included"

  instance_class        = "db.t3.small"
  allocated_storage     = 20
  max_allocated_storage = 100
  storage_type          = "gp3"

  username = "admin"
  password = var.db_password
  port     = 1433

  db_subnet_group_name   = aws_db_subnet_group.sqlserver.name
  vpc_security_group_ids = [aws_security_group.sqlserver.id]
  parameter_group_name   = aws_db_parameter_group.sqlserver.name
  option_group_name      = aws_db_option_group.sqlserver.name

  backup_retention_period = 7
  backup_window           = "18:00-19:00"
  maintenance_window      = "sun:19:00-sun:20:00"

  multi_az            = false
  publicly_accessible = false
  deletion_protection = false
  skip_final_snapshot = true

  enabled_cloudwatch_logs_exports = ["error", "agent"]

  tags = {
    Name = "sqlserver-express-demo"
  }
}

この Terraform はデモ用です。本番環境では、少なくとも次を調整してください。

  • .tf ファイルにパスワードを直接書かない。Secrets Manager、SSM Parameter Store、または CI/CD secret を使う。
  • 本番環境では deletion_protection を有効化する。
  • 本番環境では通常 skip_final_snapshot = true を使わない。
  • データベースが重要なサービスであれば、multi_az を評価する。
  • familyengine_versionmajor_engine_version は実際にサポートされるバージョンに合わせる。
  • CloudWatch log exports の対応項目はエンジンとバージョンにより異なるため、対象バージョンで確認する。
  • S3 バケットは RDS DB インスタンスと同じリージョンに置く。
  • S3 バケット名はグローバルで一意なので、例の backup_bucket_name は自分の名前に置き換える。
  • KMS で .bak ファイルを暗号化する場合、IAM policy と KMS key policy の両方で、この role が key を使用できるようにする。
  • Trust policy の例では、同一アカウント・同一リージョンの RDS DB とオプショングループ ARN pattern に権限を絞っている。本番環境では、明示的な DB インスタンス ARN とオプショングループ ARN にさらに絞ることもできる。
  • backup_prefix は、実際のバックアップおよび復元で使う S3 object path と合わせる。

バックアップと復元戦略

RDS for SQL Server では、主に次の 3 つのバックアップ方式を使います。

方式用途
Automated BackupRDS の自動バックアップ。バックアップ保持期間内の PITR をサポート
Manual Snapshot特定時点の DB snapshot を手動作成
ネイティブバックアップおよび復元.bak ファイルと S3 を使って SQL Server データベースをインポート/エクスポート

Automated Backup は最も基本的で、通常は有効化すべきバックアップ機能です。設定したバックアップ保持期間内で Point-in-Time Recovery を利用できます。誤削除、誤ったデプロイ、バッチ処理によるデータ破損が起きた場合、指定した時点へ復元できます。

RDS の PITR は元の DB を直接上書きするものではなく、新しい DB インスタンスを作成します。これは通常、より安全です。先にデータを検証し、その後でアプリケーション接続を切り替えるか、必要なデータを元のデータベースへ戻すか、事故分析用として保持するかを選べます。

Manual Snapshot は、アップグレード、パラメータ調整、大規模なバッチ更新など、重要な変更前に役立ちます。Automated Backup の代替ではありませんが、変更前の明確な復旧ポイントになります。

ネイティブバックアップおよび復元は、既存の SQL Server 運用と接続したい場合に向いています。たとえば、オンプレミス SQL Server を .bak ファイルとして S3 にバックアップし、それを RDS に復元できます。または RDS のデータベースを S3 にバックアップし、別環境で使うこともできます。この場合、オプショングループに SQLSERVER_BACKUP_RESTORE を追加し、S3 権限を持つ IAM ロールを用意します。

本番環境のバックアップ戦略では、少なくとも次の 3 つに答えられる必要があります。

質問意味
RPO はどれくらいか許容できる最大データ損失
RTO はどれくらいかサービス復旧までに許容できる最大時間
復元訓練をどれくらいの頻度で行うかバックアップのステータスが成功しているだけでなく、本当に使えることを確認する

バックアップがあることと、復元できることは別です。非本番環境で定期的に復元訓練を行い、復元時間、切り替え手順、権限差異、DB パラメータグループ、オプショングループ、セキュリティグループ、アプリケーション接続設定を記録することをおすすめします。

RDS for SQL Server を使う利点

監視を導入しやすい

EC2 やオンプレミスで SQL Server を自前運用する場合、通常は Agent を導入し、log を収集し、監視基盤と連携して、ようやくデータベースを観測できる状態になります。

RDS では、CPU、接続数、ストレージ、IOPS、Latency など、多くの CloudWatch メトリクスがデフォルトで提供されます。より詳細が必要な場合は、Enhanced Monitoring、Performance Insights、CloudWatch Database Insights を有効化できます。

少なくとも、次の基本アラームを設定することをおすすめします。

メトリクス観察目的
CPUUtilization通常の基準値を長時間上回っていないか
FreeableMemoryメモリ不足が起きていないか
FreeStorageSpaceストレージが不足しそうか
DatabaseConnections接続数が異常に増えていないか
ReadLatency / WriteLatencyストレージ遅延が悪化していないか
ReadIOPS / WriteIOPSI/O がボトルネックに近づいていないか

ストレージ拡張が比較的シンプル

オンプレミスや EC2 の自前運用データベースでは、ディスク容量不足に遭遇することがあります。特にアプリケーションやバッチ処理が大量の log、一時データ、履歴データを誤ってデータベースに書き込むと、容量が急に埋まることがあります。

RDS では、ストレージの自動スケーリングを使って、空き容量がしきい値に近づいたときにストレージを自動的に増やせます。容量計画とコスト管理は引き続き必要ですが、深夜に手動でディスク、ファイルシステム、mount point を拡張する負担は下げられます。

バックアップとメンテナンスを管理しやすい

RDS は Automated Backup、Manual Snapshot、PITR、メンテナンスウィンドウを提供します。これらの機能は、DBA やエンジニアがデータベースを完全に気にしなくてよいという意味ではありません。多くの低レイヤー運用を、設定可能で追跡可能、かつ訓練可能なプロセスに変えるものです。

組織ですでに AWS Backup を使っている場合は、RDS を集中管理されたバックアップ計画に含め、保持期間、クロスアカウントまたはクロスリージョンコピー、監査要件を管理できます。

高可用性を標準化しやすい

本番環境でデータベースが重要なコンポーネントであれば、マルチ AZ を評価すべきです。RDS マルチ AZ は、複数のアベイラビリティーゾーンにまたがって可用性と耐久性を高め、一部のメンテナンスや障害シナリオで影響を下げます。

マルチ AZ は読み取り負荷分散のための機能ではありません。読み取りトラフィックを分散したい場合は、リードレプリカまたはアプリケーションレベルの読み書きルーティングを別途検討します。

高可用性では、SQL Server のエディションと engine version の両方を確認してください。 RDS for SQL Server のマルチ AZ は主に Standard / Enterprise をサポートします。SQL Server 2022 Web Edition では、ブロックレベルレプリケーションに 16.00.4215.2 以降が必要です。Express Edition はマルチ AZ をサポートしていません。

RDS for SQL Server の制限

完全な sa 権限や OS 権限はない

RDS for SQL Server で作成時に指定する master user は、自前運用 SQL Server でよく使う sa と同じではありません。また、完全な sysadmin 権限も持ちません。これは AWS が利用を許可している範囲で最も強い権限を持つユーザーです。

つまり、OS アクセス、インスタンスレベルのアクセス、または sysadmin 権限が必要な操作は実行できない場合があります。導入前に、既存システム、運用スクリプト、バックアップ運用、DBA の操作習慣がこれらの権限に依存していないか確認してください。

一部の SQL Server 機能はサポートされない

RDS for SQL Server はマネージドサービスであるため、自前運用 SQL Server のすべての機能を公開することはできません。よくある制限には、サーバーレベルのトリガーを使えないこと、一部の OS アクセスが必要な機能を使えないこと、基盤ファイルシステムを任意に変更できないことなどがあります。

既存システムが SQL Server Agent Job、Linked Server、CLR、SSIS、SSRS、特殊なバックアップフロー、その他の高度な機能に強く依存している場合は、導入前に各要件を RDS のサポート状況と照合してください。

バージョン、エディション、リソースクラスが機能に影響する

SQL Server の機能は、エディション、バージョン、RDS のサポート範囲に影響されます。Express Edition はデモや小規模テストに適していますが、本番環境では容量、リソース、機能の制限を受けやすいです。Web、Standard、Enterprise Edition も、コストと利用可能な機能が異なります。

テスト環境で動いたからといって、その設定をそのまま本番環境へ持ち込まないでください。本番環境では、先に次を確認します。

  • データベースサイズがエディションの制限を超えないか。
  • アプリケーションが必要とする機能がサポートされているか。
  • RDS インスタンスクラスが対象エンジンとエディションをサポートしているか。
  • ライセンスコストが予算に合っているか。

作成後のチェックリスト

RDS を作成した後、接続テストが 1 回成功しただけで終わらせないでください。少なくとも次を確認します。

  • RDS がパブリックアクセス可能ではなく、正しいプライベートサブネットに配置されている。
  • セキュリティグループが必要な送信元から 1433 への接続だけを許可している。
  • アプリケーションまたは管理ツールから正常に接続できる。
  • Automated Backup が有効で、バックアップ保持期間が要件を満たしている。
  • メンテナンスウィンドウとバックアップウィンドウがピーク時間を避けている。
  • DB パラメータグループとオプショングループが正しいバージョンを使っている。
  • CloudWatch Alarm が設定されている。少なくともストレージ容量と接続数は含める。
  • Enhanced Monitoring または Performance Insights を有効化する必要があるか確認している。
  • 削除保護が環境要件に合っている。
  • 復元テストを実施し、バックアップが単なるチェック項目ではないことを確認している。

まとめ

RDS for SQL Server を作成することは、EC2 上のデータベースをマネージドサービスに置き換えるだけではありません。重要なのは、データベース運用をネットワーク、セキュリティ、バージョン、パラメータ、ストレージ、バックアップ、監視、メンテナンス、復元といった管理可能な領域に分けることです。

開発やテストであれば、小さな SQL Server Express の RDS はすぐに作成できます。しかし本番環境では、作成できたかどうかだけでなく、長期的に運用、監視、バックアップ、復元できるかを確認する必要があります。

RDS はすべてのデータベース責任を消すものではありません。それでも、多くの低レイヤーなプラットフォーム作業を減らしてくれます。データベースプラットフォーム運用が会社の差別化ポイントでないなら、その作業をマネージドサービスに任せるほうが、自分たちで基盤を作って運用し続けるより現実的です。

参考資料

この投稿は投稿者によって CC BY 4.0 の下でライセンスされています。

トレンドのタグ