prismaのmigrateをプライベートサブネットのRDSに対して実行する

ローカルで実行してた以下みたいなコマンドってRDSでDB構築した場合どうすれば良いのか
```bash
npx prisma migrate dev
```

# 手順
- 踏み台用EC2を起動
- ローカルPCから踏み台経由でRDSにsshトンネル
- migrate実行

RDSは作成されている前提で進めます。今回はPostgreSQLで進めます。
RDSのセキュリティグループには踏み台サーバーのセキュリティグループを設定しておいてください。
![スクリーンショット 2024-10-09 11.14.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/920917/d531cf5a-d02f-620e-b12d-349804d3fa09.png)



# EC2の作成
RDSがプライベートサブネットにある限り外から接続するには踏み台かVPNを使用した接続を確立するしかないので今回は簡単に踏み台サーバー立てます

![スクリーンショット 2024-10-06 11.46.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/920917/57d1b305-e9b3-a27d-736a-cb0b6c2876d6.png)

開発者がRDSに接続するためだけのサーバーなので基本デフォルトで余計な設定はしなくてOKです。

![スクリーンショット 2024-10-06 11.51.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/920917/f0409ca6-3cb9-2d79-ff1c-2f04b9cc260a.png)


![スクリーンショット 2024-10-06 11.51.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/920917/9fa35041-78d9-0741-d67f-785a7c73aeae.png)

キーペアを作成したらダウンロードフォルダからデスクトップとかに持ってきて.sshフォルダに移動しておきましょう。
```bash
# デスクトップで
mv キーペア名.pem ~/.ssh
```

![スクリーンショット 2024-10-06 11.52.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/920917/b02c2aa9-ba24-8b6a-b7a3-951fb31e00ad.png)

唯一気をつける箇所はデフォルトだとパブリックIPが付与されないので編集で有効化にしておく。
セキュリティグループは自分のIPのみを許可。

:::note warn
自宅や会社のwi-fiの関係でこの自分のIP変わることがあります。昨日接続できたのに何故か今日接続できない！みたいな時はセキュリティグループのインバウンドルールをまた設定し直してください
:::

## 接続確認
無事にインスタンスが起動できれば「接続」タブから接続の方法が見られるのでその通りにssh接続できるか試してみる。

![スクリーンショット 2024-10-06 12.03.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/920917/5b7f26cc-82c7-3d97-2a9e-dace28fae302.png)

```bash
# sshフォルダへ移動
cd ~/.ssh

# 読み取り権限のみ与える
chmod 400 "キーペア名.pem"

# 接続タブでは@以降はパブリック IPv4 DNSだがどっちでもOK
ssh -i "キーペア名.pem" ec2-user@パブリックIP


# 以下のように接続できればOK

 newer release of "Amazon Linux" is available.
  Version 2023.5.20241001:
Run "/usr/bin/dnf check-release-update" for full release and version update info
   ,     #_
   ~\_  ####_        Amazon Linux 2023
  ~~  \_#####\
  ~~     \###|
  ~~       \#/ ___   https://aws.amazon.com/linux/amazon-linux-2023
   ~~       V~' '->
    ~~~         /
      ~~._.   _/
         _/ _/
       _/m/'
Last login: Sat Oct  5 02:23:08 2024 from 60.115.146.89

```

# ローカルのPCから踏み台経由でSSHトンネル
SSHトンネルを作成すると、ローカルPCのポートがRDSにリダイレクトされ、あたかもローカルPC上でRDSが動作しているように接続できます。
```bash
cd ~/.ssh
ssh -L 5432:RDSのエンドポイント:5432 ec2-user@踏み台のパブリックIP -i キーペア名.pem

# 接続できればOK。接続したままにしておいてください。
A newer release of "Amazon Linux" is available.
  Version 2023.5.20241001:
Run "/usr/bin/dnf check-release-update" for full release and version update info
   ,     #_
   ~\_  ####_        Amazon Linux 2023
  ~~  \_#####\
  ~~     \###|
  ~~       \#/ ___   https://aws.amazon.com/linux/amazon-linux-2023
   ~~       V~' '->
    ~~~         /
      ~~._.   _/
         _/ _/
       _/m/'
Last login: Sun Oct  6 03:30:16 2024 from 60.115.159.102


```
5432ポートがすでに他の開発のdockerとかで使われてると以下のエラーで接続できない時がある。すでに使われてるよ〜って。
```bash
bind [127.0.0.1]:5432: Address already in use
channel_setup_fwd_listener_tcpip: cannot listen to port: 5432
Could not request local forwarding.
```

そしたら5432を5433とか5434とかに変えてみてください
```bash
ssh -L 5433(ここ変える):RDSのエンドポイント:5432 ec2-user@踏み台のパブリックIP -i キーペア名.pem
```
# マイグレーション実行

たぶんprisma.schemaファイルに以下の記述があると思います。
```scheme
datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
 }

```
なので.envの環境変数を以下のようにします

```.env
DATABASE_URL="postgresql://DBユーザー名:DBパスワード@127.0.0.1:5432/DB名(識別子じゃないよ)"

```

SSHトンネル接続した状態で以下コマンド
```bash
# 本番環境では以下のコマンドが推奨されています
npx prisma migrate deploy

```
無事migrateが実行されて、テーブルが作成されているはずです。


# ついでに
ECSにデプロイしたい時は.envを以下に変更してSSHトンネルした状態でbuild
じゃないとbuild中に以下のエラーでコケる

```bash

#11 18.32 Environment variables loaded from .env
#11 18.32 Prisma schema loaded from prisma/schema.prisma
#11 18.34 Datasource "db": PostgreSQL database "maji_database", schema "public" at "127.0.0.1:5432"
#11 18.80 
#11 18.80 Error: P1001: Can't reach database server at `127.0.0.1:5432`
#11 18.80 
#11 18.80 Please make sure your database server is running at `127.0.0.1:5432`.

```

```.env
# DATABASE_URL="postgresql://DBユーザー名:DBパスワード@127.0.0.1:5433/DB名"


# 127.0.0.1はあくまでローカルPCのIPです。buil時は以下のようにすることでDockerの中のIPを指定できる

DATABASE_URL="postgresql://DBユーザー名:DBパスワード@host.docker.internal:5432/DB名"
```

prisma使ったらsupabase使ってVercelデプロイとかが一般なのかな？と思いつつもお役に立てれば幸いです。