個人的備忘録：ECS のマイグレーションコンテナが RDS と通信できない場合の回避策をまとめてみた

# はじめに
AWS ECS でマイグレーションコンテナを利用する際、RDS への接続がうまくいかないことがあります。

特に、ECS のセキュリティグループ (`ecs_sg`) では RDS (`rds_sg`) への TCP/3306 アクセスが許可されているにもかかわらず通信できない場合、どのようにしたら良いのか自分なりに調べたことをまとめていきます。

:::note alert
**※内容は個人の備忘録レベルのため、参考程度にご覧ください。**
:::

# 書こうと思ったきっかけ
現在、受講している IT スクールのハッカソンに参加しており、その中で AWS 環境を用いたアプリケーションの開発に取り組んでいます。

**実際のAWS構成図**

![Screenshot 2025-02-21 at 7.29.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/14c68cef-7863-4742-97de-dc012a8dfd49.png)

その過程で、ECS のマイグレーションコンテナが RDS と通信できない問題に直面しました。

**この問題を解決するために調査し、実際に試した回避策をまとめることで、同じ問題に直面している人の参考になればと思い、本記事を書くことにしました。**

## ECS のマイグレーションコンテナが RDS と通信できない場合の回避策（自分調べ）

ECS (`ecs_sg`) のセキュリティグループでは RDS (`rds_sg`) への TCP/3306 アクセスが許可されているにもかかわらず通信できない場合、以下の方法で回避できます。

### 回避策の簡単な表（自分調べ）

| 方法 | 説明 | メリット | デメリット |
|------|------|----------|------------|
| **1. ECS を RDS と同じサブネット (private3, private4) に配置** | ECS を RDS のサブネットに移動 | NAT ゲートウェイ不要で直接接続可能 | サブネットの変更が必要 |
| **2. AWS Lambda を使う** | Lambda を RDS のサブネットに配置 | 自動実行・管理が楽 | Lambda のタイムアウト制限あり |
| **3. EC2 でマイグレーション** | EC2 から RDS に接続して実行 | 確実に動作 | コストと管理が必要 |
| **4. バスティオンホスト (EC2) を使う** | パブリック EC2 から RDS に接続 | ECS の制約を回避 | セキュリティリスク |
| **5. AWS SSM Session Manager** | SSM で RDS に接続 | SSH 不要、IAM で管理可能 | 事前設定が必要 |


## **1. ECS タスクを RDS と同じサブネット (`private3`, `private4`) に配置**

RDS のサブネット (`private3`, `private4`) に ECS タスク（マイグレーションコンテナ）を配置することで、直接通信可能にする。

### **手順**
1. `aws_ecs_service.main` の `network_configuration` の `subnets` を RDS がある `private3`, `private4` に変更。
2. ECS のセキュリティグループ (`ecs_sg`) を RDS (`rds_sg`) に直接関連付ける。

### **変更例**
```hcl
network_configuration {
  subnets         = [aws_subnet.private3.id, aws_subnet.private4.id]  # RDS と同じサブネットに変更
  security_groups = [aws_security_group.ecs_sg.id]
  assign_public_ip = false
}
```

効果: NAT を経由せず、RDS のサブネット内で直接通信可能になる。

## **2. AWS Lambda を使ってマイグレーションを実行**

ECS のマイグレーションコンテナの代わりに、AWS Lambda を使って RDS に直接接続し、マイグレーションを実行する。

### **手順**
1. Lambda の VPC 設定で `private3`, `private4` を指定（RDS と同じサブネット）。
2. Lambda のセキュリティグループに RDS への TCP/3306 接続を許可。
3. マイグレーション用スクリプト（SQL / Python / Bash）を Lambda に組み込む。

効果:
- ECS ではなく Lambda で直接実行できるため、NAT や VPC 接続の問題を回避できる。
- RDS と同じサブネットで実行すれば、通信は確実に成功する。

## **3. EC2 インスタンスを使ってマイグレーション**

EC2 を RDS のあるサブネット (`private3`, `private4`) にデプロイし、そこでマイグレーションを実行する。

### **手順**
1. EC2 を `private3` または `private4` にデプロイ。
2. EC2 のセキュリティグループ (`ecs_sg` or `rds_sg`) に TCP/3306 で RDS への接続を許可。
3. SSH で EC2 にログインし、マイグレーションを実行。
4. マイグレーション完了後、EC2 を削除。

効果:
- 確実に RDS へ接続できる環境を作成できる。
- 手動で管理する必要があるが、緊急対応として有効。

## **4. マイグレーション用のバスティオンホストを用意する**

マイグレーション専用のバスティオンホスト（EC2）を作成し、そこから RDS へ接続する。

### **手順**
1. パブリックサブネット (`public1` or `public2`) に EC2 をデプロイ。
2. この EC2 に `private3`, `private4` の RDS へ接続できるようにセキュリティグループを設定。
3. EC2 からマイグレーションスクリプトを実行。

効果:
- ECS の制約を回避し、手動で RDS へのアクセスを確保できる。
- マイグレーションが完了したら、EC2 を削除すればコストを最小限に抑えられる。

## **5. AWS Systems Manager (SSM) を使って RDS に接続**

AWS Systems Manager (SSM) の Session Manager を使って RDS へ接続し、マイグレーションを実行する。

### **手順**
1. SSM Agent を EC2 / ECS にインストールし、Session Manager を有効化。
2. AWS CLI で Session Manager を使い、RDS に接続。
3. 必要なマイグレーションスクリプトを実行。

効果:
- EC2 や ECS へ SSH 接続不要で RDS へ接続可能。
- IAM ロールを適切に設定すれば、管理が楽になる。

## まとめ（自分調べ）

### **最適な回避策の選び方**
- すぐに試せる方法 → **① ECS を RDS と同じサブネットに配置**
- 簡単に管理したい → **② AWS Lambda を使う**
- 確実に実行したい → **③ EC2 を使う**
- 一時的な対応が必要 → **④ バスティオンホストを使う**
- セキュリティ重視 → **⑤ AWS SSM Session Manager を使う**

オススメ: 最初に「ECS を RDS と同じサブネットに配置」し、それでもダメなら AWS Lambda を試すのがベスト。