【Rails】SSMを使用してRDSのポートフォワーディングをローカルでセットアップする方法
セキュリティに考慮しつつ、Railsアプリケーション上でRDSのデータベースにアクセスしたいなぁ...というケースがあったので、備忘録的に書き残しております。
2024年04月17日
前提条件
- AWS CLI がインストールされていること
- 動作中のRDSインスタンスが存在していること
- 適切な IAM ロールとポリシーが設定されていること(SSMがRDSへのアクセス権限を持っている)
- Railsアプリがすでにあること
セッションを開始
RailsアプリケーションからリモートのRDSインスタンスにアクセスしたいので、AWS-StartPortForwardingSessionToRemoteHost
を指定しましょう。
aws ssm start-session --target instance-id \
--document-name AWS-StartPortForwardingSessionToRemoteHost \
--parameters '{"host":["your-rds-endpoint"],"portNumber":["3306"], "localPortNumber":["9999"]}'
- instance-id: Session Manager 経由で接続する EC2 インスタンスの ID です。
- parameters.host: RDSインスタンスのエンドポイント(xxxx.ap-northeast-1.rds.amazonaws.com)
- parameters.portNumber: RDS インスタンスのポート番号(MySQL の場合は通常 3306)。
- parameters.localPortNumber: ローカルマシン上で使用するポート番号
疎通確認(MySQL)
MySQLを例にして疎通確認をしてみます。
パスワードの入力を求められるので、RDSで設定しているものを。
$ mysql -h 127.0.0.1 -P 9999 -u root -p
疎通確認ができれば大丈夫です。
Rails側の設定
難しいことはなく、先ほどの疎通確認で入力したものを設定していくだけです。
- database: RDSの対象DB名
- username: RDSのusername(基本root)
- port: SSMで入力したlocalPortNumber
- host: localhostを指定
default: &default
adapter: mysql2
encoding: utf8mb4
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
development:
<<: *default
database: database
username: root
port: 9999
password: password
host: 127.0.0.1
ただ、dockerでは一癖あります。
勘の良い方はお分かりの通り、SSMをホストマシンで動かしているので、少し工夫が必要です。
dockerの場合
まずはdocker用のhostに変えておきます。
database.yml
development:
<<: *default
database: database
username: root
port: 9999
password: password
host: host.docker.internal # ここ
※ Docker 20.04 以降でLinux環境でも host.docker.internal
が使用できるようになったみたいです。
あとはネットワークモードをhostに変更。
docker-compose.yml
# 例です
mysql:
environment:
MYSQL_ALLOW_EMPTY_PASSWORD: "yes"
network_mode: "host" # この設定をしよう
以上です。