🐈

Terraform で RDS を作成する時のパスワードって結局どう扱えば良いの?

2020/12/21に公開

Terraform で RDS インスタンスを作成する機会がありました。

この時、どうやって DB のパスワードを安全に設定するか悩んだのでその結果をまとめておきます🙌

結論

  • tfstate ファイルそれ自体を confidential なものとして扱う(state ファイルを保存する S3 バケットに対してのパブリックアクセスが禁じられているか必ず確認する)
  • テンプレートにはパスワードをベタで書かずに、変数として外から入れる

解説

RDS インスタンスのテンプレートを用意します。
https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/db_instance

rds.tf
variable "rds_password" {}

resource "aws_db_instance" "default" {
  allocated_storage        = 20
  storage_type             = "gp2"
  engine                   = "postgres"
  engine_version           = "12.3"
  instance_class           = "db.t2.micro"
  name                     = "rails_db_instance"
  username                 = "admin"
  password                 = var.rds_password
  port                     = 5432
  availability_zone        = "ap-northeast-1a"
  db_subnet_group_name     = aws_db_subnet_group.default.id
  publicly_accessible      = true
  vpc_security_group_ids   = [aws_security_group.rds.id]
}

シンプルに var.rds_password で外からパスワードを注入します。
auto.tfvars ファイルに記述するのがおすすめです。

credential.auto.tfvars
rds_password  = "k3jehufeio2938eurfjkd2ujefgy2"

.gitignore への追加をお忘れなく!!

注意点としては、このやり方だとテンプレートからはパスワードが消えますが、 tfstate ファイルにはパスワードが平文で保存されます。
これは Terraform 公式も認識していることのようで、ベストプラクティスとして 「tfstate ファイルそれ自体を confidential なものとして扱う」というのが推奨されるようです🧐

CI から実行する時には環境変数を使いましょう。
https://www.terraform.io/docs/configuration/variables.html#environment-variables

TF_VAR_ の prefix から始まる環境変数を Terraform は自動で読み込んでくれます。上の例に当てはめると、
TF_VAR_rds_password の値を CI ツールに設定しておけば問題なく読み込んでくれます🏄‍♂️

余談

  • チームの事情などで、どうしても state ファイルにパスワードを平文で保存したくない場合には適当なパスワード ("password" とか)をベタ書きして、インスタンス作成後に DB に接続してコマンドから本物のパスワードに変更するという方法もあるようです
  • ECS で使用する場合にはこのパスワードを System Manager の パラメータストアなどにセキュアに保存し、それをコンテナから参照するのがベストかと思います。

参考にさせて頂いた記事

Discussion