DMSを使用したRDSデータのS3ファイル出力

## はじめに

AWS上でRDSのデータを使用して何らかの処理を行う場合、DBに接続して直接操作する方法やファイル出力を行い、出力したファイルに対して処理を行う方法などが考えられるかと思います。
今回は後者のRDSデータのファイル出力に焦点を当て、DMS・S3を利用して実装します。
本記事ではRDSからDMSを利用してS3へデータ出力を行う際の各種設定手順とエラーポイントについてまとめていきます。

## 前提条件

・コンソール操作で各種リソースを作成
・データベースはMySQLを使用
・RDS、DMSは異なるVPCに配置
・CDCは実施しない

## RDSの作成

①VPCの作成
・作成するリソースで「**VPCなど**」を選択
・VPCエンドポイントで「**なし**」を選択
・その他の設定はデフォルト

②DBサブネットグループの作成
・①で作成したVPCを選択
・①で作成したVPCのサブネットが存在するAZを2つとも選択
・①で作成したVPCのプライベートサブネットを2つとも選択

③データベースの作成

・作成方法で「**標準作成**」を選択
・エンジンのタイプは「**MySQL**」を選択
・テンプレートは「**無料利用枠**」を選択
・認証情報管理は「**セルフマネージド**」を選択
・①で作成したVPCを選択
・②で作成したDBサブネットグループを選択
・その他の設定はデフォルト

**※セキュリティグループは一旦、「default」のまま**

## RDS・DMS間の接続設定

①VPCの作成
・作成するリソースで「**VPCなど**」を選択
・VPCエンドポイントで「**なし**」を選択
・IPv4 CIDR ブロックで①のVPCと重複しないようCIDRを設定
・その他の設定はデフォルト

②ピアリング接続の作成
・①で作成したVPCおよびRDSが配置されているVPCをそれぞれ選択
・ステータスが「**承諾の保留中**」になるため、アクションからリクエストを承諾

③ルートテーブルの修正
・EC2およびRDSが配置されているサブネットに紐づくルートテーブルへルートを追加
・通信先には通信先のVPCのCIDRを指定
・ターゲットで「**ピアリング接続**」を選択し、①で作成したピアリング接続を選択

④セキュリティグループ（DMS用）の作成
・DMS用のセキュリティグループを作成
・①で作成したVPCを選択

⑤セキュリティグループ（RDS用）の作成
・RDS用のセキュリティグループを作成
・RDSを配置しているVPCを選択
・インバウンドルールに④で作成したセキュリティグループからのポート3306のTCP接続（タイプで「**MYSQL/Aurora**」を選択）を許可するルールを設定

・RDSで使用しているセキュリティグループを変更

⑥セキュリティグループ（DMS用）の修正
・DMS用のセキュリティグループを修正
・アウトバウンドルールに⑤で作成したセキュリティグループへのポート3306のTCP接続（タイプで「**MYSQL/Aurora**」を選択）を許可するルールを設定

## S3の作成

①S3の作成
・各種設定はデフォルト

②エンドポイントの作成
・タイプは「**AWSのサービス**」を選択
・サービスは「**com.amazonaws.<リージョン>.s3**」のGatewayタイプを選択
・VPCはDMS用のVPCを選択
・ルートテーブルはプライベートサブネット用のテーブルを選択

③セキュリティグループの修正
・S3エンドポイントで指定したS3のマネージドプレフィックスリストに対するHTTPSでのアウトバウンドルールを追加

## DMSの作成

①レプリケーションサブネットグループの作成
・VPCはDMS用のVPCを選択
・サブネットはプライベートサブネットを2つとも選択

②エンドポイント（RDS）の作成
・エンドポイントタイプ は「**ソースエンドポイント**」を選択
・RDS DBインスタンスで作成したRDSを選択
・エンドポイントデータベースへのアクセスは「**アクセス情報を手動で提供する**」を選択

③IAMポリシーの作成
・以下のようなポリシーを作成

```text:policy
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:ListBucket",
                "s3:PutObjectTagging",
                "s3:DeleteObject"
            ],
            "Resource": [
                "arn:aws:s3:::[バケット名]/*",
                "arn:aws:s3:::[バケット名]"
            ]
        }
    ]
}
```

④IAMロールの作成
・信頼されたエンティティタイプは「**AWS のサービス**」を選択
・ユースケースは「**DMS**」を選択
・許可ポリシーは③で作成したポリシーを選択

⑤エンドポイント（S3）の作成
・エンドポイントタイプ は「**ターゲットエンドポイント**」を選択
・ターゲットエンジンは「**Amazon S3**」を選択
・サービスアクセスロールの Amazon リソースネーム (ARN)は④で作成したIAMロールのARNを入力
・バケット名は作成したS3バケット名を入力

⑥レプリケーションインスタンスの作成
・インスタンスクラスは「**dms.t3.micro**」を選択
・シングルAZ構成を選択
・VPCはDMS用のVPCを選択
・レプリケーションサブネットグループは①で作成したサブネットグループを選択
・パブリックアクセス可能は無効化
・詳細設定でセキュリティグループをDMS用のセキュリティグループへ変更
・その他の設定はデフォルト

## 動作確認

①エンドポイント（RDS）の接続テスト
・エンドポイントの接続タブよりテストを作成
・作成したレプリケーションインスタンスを選択したうえでテストの実行

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3637963/66622d81-e5d3-2176-27a2-a417a3fa8e92.png)

②エンドポイント（S3）の接続テスト
・エンドポイントの接続タブよりテストを作成
・作成したレプリケーションインスタンスを選択したうえでテストの実行

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3637963/ad77d8b6-de75-787b-63f8-d4a018f25872.png)

③データベース移行タスクの作成
・作成したレプリケーションインスタンスを選択
・作成したソースデータベースエンドポイントを選択
・作成したターゲットデータベースエンドポイントを選択
・移行タイプは「**既存のデータを移行する**」を選択
・CloudWatch ログを有効化
・テーブルマッピングで適切なスキーマ、テーブルを入力
・移行前評価を無効化
・その他の設定はデフォルト

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3637963/ca9fbf34-cac8-61fa-c7ce-e12bfb5c5d0b.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3637963/07152663-3ea9-603a-c4f2-8a21be516691.png)

## エラーポイント

<font color=red>※エンドポイントの接続エラーはエラーメッセージから原因を特定するのが困難なためエラー発生時に確認するべき設定箇所を列挙します。</font>

①ソースエンドポイント（RDS）
・接続先RDSのステータス
・ルートテーブルの設定（VPCが異なる場合）
・セキュリティグループの設定
・DMSエンドポイントの設定
・DMSサブネットグループの設定

②ターゲットエンドポイント（S3）
・ルートテーブルの設定（S3エンドポイントの設定）
・セキュリティグループの設定
・DMSエンドポイントの設定
・DMSサブネットグループの設定

<font color=red>※移行タスクでのエラーは権限回りや設定不備が主になります。</font>

①IAMロールの権限不足

```text:実行結果（CloudWatchログ）
2024-11-18T04:46:25 [TASK_MANAGER    ]E:  AccessDenied: User: arn:aws:sts::<アカウントID>:assumed-role/<ロール名>/dms-session-for-replication-engine is not authorized to perform: <権限> on resource: "arn:aws:s3:::<バケット名>/dms/<スキーマ名>/<テーブル名>LOAD00000001.csv" because no identity-based policy allows the <権限> action [1001705]  (transfer_client.cpp:510)
```

②テーブルマッピングの選択ルールの設定不備（スキーマ・テーブルの設定ミス）

```text:実行結果
Last Error No tables were found at task initialization. Either the selected table(s) or schemas(s) no longer exist or no match was found for the table selection pattern(s). If you would like to start a Task that does not initially capture any tables, set Task Setting FailOnNoTablesCaptured to false and restart task. Stop Reason FATAL_ERROR Error Level FATAL
```

## まとめ
DMSを使用したRDSデータのS3ファイル出力を実施してみました。
エンドポイントの接続エラーが発生した場合は、原因特定が困難なためネットワーク周りの設定は慎重に行いたいところですね。
次はフルロードではなくCDCを利用したS3ファイル出力をまとめていきたいと思います。