背景

開発環境で動かしてたアプリケーションをコンテナ化して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

考えたこと

sslmodedisableenableに変更するのが王道だと思います。

ただ、開発環境で用意している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に変わってます。カスタムパラメータグループはデフォルトがベースになっていて、明示的に変更したところだけが変わります。