RDS for SQL Serverで別アカウントのS3バケットを使用してインポートとエクスポートを試してみた

RDS for SQL Server で完全バックアップファイル (.bak ファイル) を使用したネイティブバックアップとリストアを別のアカウントにある S3 バケットで試してみました。
2022.05.25

こんにちは、大阪オフィス所属の望月です。
RDS for SQL Server で完全バックアップファイル (.bak ファイル) を使用したネイティブバックアップとリストアが行えることを知ってますか。
今回オンプレにある SQL Server から取得したバックアップファイルが配置されている S3 バケットが別 AWS アカウントにある状況でリストアを試してみました。
ネイティブバックアップとリストアについて詳しくは以下公式ドキュメントを確認してください。

SQL Server データベースのインポートとエクスポート

前提

  • RDS for SQL Server を作成する AWS アカウント
    • 以降、アカウント A
  • S3 バケットを作成する AWS アカウント
    • 以降、アカウント B

やってみた

S3 バケットの作成

アカウント B で S3 バケットを作成し S3 バケットには .bak ファイルを配置します。
検証のため Microsoft が提供しているサンプルデータベースを利用しました。以下サイトからリンクされている Github から WideWorldImporters-Full.bak をダウンロードし、S3 バケットにアップロードします。

WideWorldImporters: The new SQL Server sample database - Microsoft SQL Server Blog

IAM ロール作成

アカウント A で RDS 用の IAM ロールを作成します。
作成時には AWS のサービスを「RDS - Add Role to Database」に選択し、以下ポリシーを割り当てて作成します。

  • bucket_name はアカウント B の S3 バケットを指定してください
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:ListBucket",
                "s3:GetBucketLocation"
            ],
            "Resource": [
                "arn:aws:s3:::<bucket_name>"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:GetObject",
                "s3:PutObject",
                "s3:ListMultipartUploadParts",
                "s3:AbortMultipartUpload"
            ],
            "Resource": [
                "arn:aws:s3:::<bucket_name>/*"
            ]
        }
    ]
}

オプショングループの作成

オプショングループをエンジンとメジャーエンジンバージョンを作成する SQL Server の種類、バージョンと合わせる形で作成を行います。
作成したオプショングループにオプション追加でオプション名 SQLSERVER_BACKUP_RESTORE を選択し、IAM ロールには先ほど作成した IAM ロールを選択します。

  • 作成したオプショングループを選択し「オプションを追加」を選択

  • オプション名 SQLSERVER_BACKUP_RESTORE を選択

  • 先ほど作成した IAM ロールを選択します。

RDS for SQL Server での作業は以上となります。

S3 バケットのバケットポリシー設定

別アカウントからのアクセスを許可するためバケットポリシーの設定をします。IAM ロールを指定することで特定のアカウント及び IAM ロール以外からのアクセスは許可しません。

  • bucket_name はアカウント B の S3 バケットを指定してください
  • IAM Role ARN はアカウント A で作成した IAM ロールを指定してください
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Permission to cross account",
            "Effect": "Allow",
            "Principal": {
                "AWS": "<IAM Role ARN>"
            },
            "Action": [
                "s3:ListBucket",
                "s3:GetBucketLocation"
            ],
            "Resource": "arn:aws:s3:::<bucket_name>"
        },
        {
            "Sid": "Permission to cross account 2",
            "Effect": "Allow",
            "Principal": {
                "AWS": "<IAM Role ARN>"
            },
            "Action": [
                "s3:GetObject",
                "s3:PutObject",
                "s3:ListMultipartUploadParts",
                "s3:AbortMultipartUpload"
            ],
            "Resource": "arn:aws:s3:::<bucket_name>/*"
        }
    ]
}

データベースのリストア

リストアを行うため、EC2 インスタンス経由で RDS for SQL Server にログインをします。
EC2 インスタンスには Amazon Linux 2 を利用するため、SQL Server のコマンドラインツールをインストールします。
Amazon Linux 2 なので RHEL 7 のリポジトリを利用します。( ARM 版は提供されてないので注意しましょう。最初インストールできないなーと悩みました…

Linux に SQL Server コマンドライン ツールをインストールする - SQL Server

sudo curl https://packages.microsoft.com/config/rhel/7/prod.repo > /etc/yum.repos.d/msprod.repo
sudo yum install mssql-tools unixODBC-devel
echo 'export PATH="$PATH:/opt/mssql-tools/bin"' >> ~/.bash_profile
source ~/.bash_profile

コマンドラインツールをインストールできたら、RDS for SQL Server にログインしリストアを実行します。

  • endpoint, user, password はアカウント A の RDS for SQL Server の情報を入力してください
  • bucket_name はアカウント B の S3 バケットを指定してください
sqlcmd -S <endpoint> -U <user> -P <password>

exec msdb.dbo.rds_restore_database 
	@restore_db_name='testdb', 
	@s3_arn_to_restore_from='arn:aws:s3:::<bucket_name>/WideWorldImporters-Full.bak',
	@with_norecovery=0;
go

## Task ID が 1 として登録されます
Task created successfully.
Task Id: 1

登録されたタスクの状況を以下コマンドにて確認することができます。

exec msdb.dbo.rds_task_status
	@db_name='testdb',
	@task_id=1;
go

## SUCCESS が表示されるのを確認する

select name from sys.databases;

..
testdb
..

## testdb が表示されるのを確認する

データベースのバックアップ

RDS for SQL Server にログインしバックアップを実行します。

  • bucket_name はアカウント B の S3 バケットを指定してください
exec msdb.dbo.rds_backup_database
	@source_db_name='testdb', 
	@s3_arn_to_backup_to='arn:aws:s3:::<bucket_name>/testdb.bak';

S3 バケットを確認してみるとバックアップが取れていることを確認できました。

まとめ

RDS for SQL Server のインスタンスとバックアップファイルが保存される S3 バケットのアカウントが違う場合もリストアとバックアップが行えることが確認できました。
アカウントを分ける必要がある場合もバックアップファイルを移動させずに対応することができるので、そういった場面に遭遇したときはぜひ試してみてください。