ECS fargate 経由で RDSに接続

# やりたいこと

ローカルから、ECS Fargate のコンテナ経由 で RDS に接続

## 🚀 より簡単な方法をお探しの方へ(2025/06/20)

この記事の手順を自動化したCLIツールを作りました！
対話的なUIで誰でも簡単にECS経由でRDSに接続できます。

**▶️ [AWS ECS経由でRDSに簡単接続のためのセキュアなポートフォワーディングCLIツールを作ってみた](https://qiita.com/k_bobchin/items/7449501688fdf11b23df)**

```bash
# 1コマンドで対話的に接続可能
npx ecs-pf connect
```

手動での接続方法を理解したい方は、このまま読み進めてください！

# 必要な情報

1 ~ 3 のうち、1 だけわかっていれば、後述する方法で芋づる式で情報とれます。
aws のコンソール画面からも確認可能です。

4 ~ 7 は RDS 接続のための基本情報です。

1. ECS Cluster 名 (CLUSTER_NAME)
2. TaskID (TASK_ID)
3. RuntimeID (RUNTIME_ID)
4. RDS Host (RDS_HOST)
5. RDS Port (RDS_PORT)
6. RDS User
7. RDS Password

# 接続してみた

## 1. aws ssm コマンドを ローカル の ターミナルで実行

各変数は書き換えてください。
`localPortNumber`は `8888` としてますが任意です。

```sh
aws ssm start-session \
        --target ecs:${CLUSTER_NAME}_${TASK_ID}_${RUNTIME_ID} \
        --parameters "{\"host\":[\"${RDS_HOST}\"],\"portNumber\":[\"${RDS_PORT}\"], \"localPortNumber\":[\"8888\"]}" \
        --document-name AWS-StartPortForwardingSessionToRemoteHost
```

上記コマンドで、自分の PC の localhost（`127.0.0.1`）の`localPortNumber`にポートフォワーディングされ・・・

![スクリーンショット 2023-06-15 16.20.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183059/ba310eec-8064-5a31-f1b5-15189c99fa6d.png)|
|:-:|

成功すると、「Waiting for connections...」と出ます。

## 2. RDS に接続

Tableplus で接続 (mysql、psql コマンドでもなんでも OK)

接続成功画面

![スクリーンショット 2023-06-15 15.01.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183059/eb6983fc-2de8-319f-851f-8a4c1c58eaa8.png)

- `Host`:`127.0.0.1`
- `Port`:任意で入力した`localPortNumber`
- `User`, `Password`, `Database`は RDS に接続するときの情報です。

無事、ローカルから、RDSへ接続できました

# 前提

1. RDS に接続する ECS Fargate コンテナがある（大体サーバーサイド）
2. aws cli がローカルにインストール
3. 対象 ECS Service が ecs exec 可能

# ケース

ECS 構築していて、よく「ECS fargate(サーバーサイド)　+ RDS + α」を作るけど、
ステージング等で、パフォーマンス・チューニングや設定確認等で DB に接続

# メリット

- RDS に 「 接続のため 」の「 下準備 」が省ける

## RDS に接続するためにやっていた下準備の例

1. RDS・ALB・VPC のセキュリティグループに、特定の IP アドレス・VPN だけ 接続許可の追加
2. RDS をパブリックサブネットに置いて IAM ロールで接続許可するような仕組み・設定
3. RDS に接続する ECS Fargate コンテナ に データベース接続のためのコマンド（mysql, psql 等）をインストール
4. 踏み台サーバー用意

# 試したローカル環境

```sh
aws --version
aws-cli/2.11.27 Python/3.11.4 Darwin/22.5.0 source/x86_64 prompt/off
```

tableplus: Version 5.3.8

![スクリーンショット 2023-06-15 13.52.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183059/2e7f7d10-49b2-215d-dd46-8d92f3abe046.png)

# 推奨 VSCode 拡張

- [AWS Toolkit](https://marketplace.visualstudio.com/items?itemName=AmazonWebServices.aws-toolkit-vscode)

これがあると、

1. 対象の ECS クラスター名、タスク ID 等を取得するのが容易
2. 対象サービスが(ecs exec)可能か把握が容易

になります。

# AWSコンソールいかなくても、拡張あればECSの情報は揃う

必要な情報の中でも、前提条件の「ECS Exec 対応しているか」 と　下記 1 ~ 3 は

1. ECS Cluster 名 (CLUSTER_NAME)
2. TaskID (TASK_ID)
3. RuntimeID (RUNTIME_ID)

aws コンソール画面で確認するのが面倒なので VSCode の拡張([AWS Toolkit](https://marketplace.visualstudio.com/items?itemName=AmazonWebServices.aws-toolkit-vscode))を使うと確認が簡単になります。

## 1. ECS Exec に対応しているか確認

[AWS Toolkit](https://marketplace.visualstudio.com/items?itemName=AmazonWebServices.aws-toolkit-vscode)で ECS → 対象 Cluster → Service とプルダウンしていき、コンテナを右クリックしたときに出てくるメニューが選択できる

![スクリーンショット 2023-06-15 15.36.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183059/3131c28b-4a13-70e4-1ea4-a64c1d87e449.png)

→ 選択できない場合は、「ECS Exec」が 対応 できてない可能性が高い

まだ、対応されていない場合は下記記事を参考にしてみてください

[[アップデート] 実行中のコンテナに乗り込んでコマンドを実行できる「ECS Exec」が公開されました](https://dev.classmethod.jp/articles/ecs-exec/)

## 2-1 必要情報を揃える ECS Cluster名

[AWS Toolkit](https://marketplace.visualstudio.com/items?itemName=AmazonWebServices.aws-toolkit-vscode)で ECS → 対象 Cluster → Service とプルダウンしていき、サービスを右クリックしたときに出てくるメニューで「Copy ARN」

![スクリーンショット 2023-06-15 15.46.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183059/da71f30f-cfee-db84-54d1-a9706d7b30b5.png)

`arn:aws:ecs:region:accountID:service/ClusterName/ServiceName`

の構造になっているので、`ClusterName`だけコピー

## 2-2 必要情報を揃える TASK_ID

```sh
aws ecs list-tasks --cluster $CLUSTER_NAME
```

`TaskARN` が出力され

`arn:aws:ecs:region:accountID:task/ClusterName/TaskID`

構造になっているので、`TaskID`が取り出せる

## 2-3 必要情報を揃える RUNTIME_ID

2-2 で取得した `TaskARN`から

```sh
aws ecs describe-tasks --cluster $CLUSTER_NAME --tasks $TASK_ARN
```

tasks → containers → runtimeId のように辿っていけば、`RuntimeID`が取り出せる

サーバーサイドとタスクがひとつしかないようであれば下記で`runtimeId`が返されます

```sh
aws ecs describe-tasks --cluster $CLUSTER_NAME --tasks $TASK_ARN --query tasks[0].containers[0].runtimeId
```

# 参考

- [ECS Fargate を踏み台にポートフォワードして VPC 内の RDS に接続する](https://zenn.dev/quiver/articles/1458e453118254#%E8%A3%9C%E8%B6%B3%3Aecsta%E3%81%AE%E3%82%B3%E3%83%BC%E3%83%89%E3%81%8B%E3%82%89session-manager%E3%81%AEecs%E7%94%A8%E3%82%BF%E3%83%BC%E3%82%B2%E3%83%83%E3%83%88id%E7%94%9F%E6%88%90%E7%AE%87%E6%89%80%E3%82%92%E7%A2%BA%E8%AA%8D)
- [[アップデート] 実行中のコンテナに乗り込んでコマンドを実行できる「ECS Exec」が公開されました](https://dev.classmethod.jp/articles/ecs-exec/)