背景
開発環境で動かしてたアプリケーションをコンテナ化してECSに載せました。
golangで実装されたバックエンドはAPIとして動き、postgresqlのDBと通信します。
ですが、通信できないのです。セキュリティグループも5432/tcpは許可しているのに。
原因
RDSがSSLを要求している一方、アプリケーション側はSSL通信を無効にしているのが原因でした。
ログをみると以下のようにno encryption
と出力されています。
[error] failed to initialize database, got error failed to connect to `user=***** database=*****`: 10.11.6.236:5432 (db.cbaimfixitb4.ap-northeast-1.rds.amazonaws.com): server error: FATAL: no pg_hba.conf entry for host "10.11.3.213", user "*****", database "*****", no encryption (SQLSTATE 28000)
panic: failed to connect database
fallback
golangのコードは以下の記述になっています。ポイントはsslmode=disable
です。
"host=%s user=%s password=%s dbname=%s port=%s sslmode=disable TimeZone=Asia/Tokyo",
golang
考えたこと
sslmode
のdisable
をenable
に変更するのが王道だと思います。
ただ、開発環境で用意しているDBはSSL設定をしていません。SSLを設定するのは手間です。なので、環境変数として扱って、開発環境はdisable
に、ECSではenable
にするのがいいかもと思いました。が、コードの変更は時間がかかりそうです。一方、アプリは急いでECSで動かしたいです。
先に進めることを優先して、一時的にRDSのSSLを無効にすることにしました。
対処方法
カスタムパラメータグループを作成し、RDSインスタンスに適用します。
まずはカスタムパラメータを作成します。ここではrds.force_ssl
を「1(有効)」から「0(無効)」に変更します。
resource "aws_db_parameter_group" "postgres_custom" {
name = "yamada-custom-postgres-params"
family = "postgres16" # PostgreSQL のバージョン
description = "Custom parameter group with rds.force_ssl disabled"
parameter {
name = "rds.force_ssl"
value = "0"
apply_method = "pending-reboot" # 変更を反映させるために再起動が必要な場合
}
}
terraform
これを適用します。
resource "aws_db_instance" "db" {
identifier = "${var.database_name}-db"
db_name = var.database_name
〜省略
parameter_group_name = aws_db_parameter_group.postgres_custom.name
}
terraform
設定前と設定後
デフォルトの定義でrds.force_sslが1になってます。
作成したカスタムパラメータグループのrds.force_sslが0に変わってます。カスタムパラメータグループはデフォルトがベースになっていて、明示的に変更したところだけが変わります。