TerraformでAWS RDSのDBユーザを管理する


はじめに

MySQLやPostgreSQLのユーザをTerraformで管理するときの備忘録としてこの記事を残します。

前提条件

基盤はAWS、DBはPostgreSQLでDBがいるネットワークは内部ネットワークでインターネットのアクセスがないです。TerraformはローカルPC(Mac)から実行するものとします。

実行方法

Terraform

こちらのPostgreSQL用のTerraform providerを使い実行します。

provider "postgresql" {
  scheme   = "awspostgres" # AWSを使う場合はこれを指定
  host     = var.db_host
  username = "postgres"
  port     = 5432
  password = var.db_password

  superuser = false
}

バージョンはこのように指定します。

  required_providers {
    postgresql = {
      source  = "cyrilgdn/postgresql"
      version = "1.11.2"
    }
  }

PostgreSQLのユーザを追加します。

resource "postgresql_role" "my_role" {
  name     = "my_role"
  login    = true
  password = var.my_role_password
}

resource "postgresql_grant" "readonly_my_role" {
  database    = "test_db"
  role        = postgresql_role.my_role.name
  schema      = "public"
  object_type = "table"
  privileges  = ["SELECT"]
}

ローカル

ローカルから直接PostgreSQLを触ることはできないので、踏み台サーバを経由してSSHトンネリングすることで、アクセスします。

sshトンネリング用のコマンドを実行します。

# ssh -N -L [ローカル側で転送に使用するPort(10000〜60000)]:[DBのHostName]:[DBが解放しているPort] -i [IdentityFile(秘密鍵のパス)] -p [踏み台が解放しているPort] [踏み台のUser]@[踏み台のHostName]

ssh -N -L 5432:test_db.XXX.ap-northeast-1.rds.amazonaws.com:5432 -i ~/.ssh/bastion.pem -p 22 ec2-user@XXX

後述するSSL証明書エラーになるので、ホストを偽装します。
/etc/hostslocalhost 127.0.0.1 test_db.XXX.ap-northeast-1.rds.amazonaws.com を追加してください。

これでTerraformを実行するとPostgreSQLへのユーザ追加ができます。

Tips

SSL証明書エラー

上記に記載されているsshトンネリングコマンドを実行し、

ssh -N -L 5432:test_db.XXX.ap-northeast-1.rds.amazonaws.com:5432 -i ~/.ssh/bastion.pem -p 22 ec2-user@XXX

sshトンネリングで localhost5432ポートにアクセスするとPostgreSQLにアクセスできるようになったので、Terraformのproviderのhost名を locahostに指定して、Terraformを実行させます。

provider "postgresql" {
  scheme   = "awspostgres" # AWSを使う場合はこれを指定
  host     = "localhost"
  username = "postgres"
  port     = 5432
  password = var.db_password

  superuser = false
}

そうすると、SSL証明書の確認でホスト名が異なるとエラーが出てしまいます。

Error: error detecting capabilities: error PostgreSQL version: x509: certificate is valid for stg-knew-rds.coh5dxpjppgc.ap-northeast-1.rds.amazonaws.com, not localhost

セッションマネージャーを使ったポートフォワード

セッションマネージャーを使ってポートフォワードができないかと調べたが、
結局ポートフォワードはできなかった。

cf. https://dev.classmethod.jp/articles/port-forwarding-using-aws-system-manager-sessions-manager/