背景

VPSに配置したアプリケーションから、AWSのRDSに接続したいという要望がありました。

技術的には可能だと思うのですが、本当にできるのかなどを検証しました。検証は環境の構築→検証→破壊→構築→検証→破壊を繰り返します。そういうビルド・アンド・スクラップをしやすくするためにterraformを使用しました。terraformを使用する中で得たワタクシ的なノウハウを記録します。

なお、インターネット経由の通信に特化した内容だけではなく、RDS全般に言えることも書いています。

インターネットからRDSにアクセスするためのノウハウ

VPCの定義

VPCは以下が必要

    enable_dns_support = "true"
    enable_dns_hostnames = "true"

なお、trueにしないで、未設定(デフォルトがfalse)と以下のようなエラーが出ます。

 Error: creating RDS DB Instance (test-db): InvalidVPCNetworkStateFault: Cannot create a publicly accessible DBInstance.  The specified VPC does not support DNS resolution, DNS hostnames, or both. Update the VPC and then try again
 	status code: 400, request id: 0fc9bcc2-e7f5-4e64-9bc6-35c9dcc9f9e3

DBの定義

インターネットからのアクセスを許可するために、dbインスタンスには以下を入れます。

publicly_accessible     = true

RDS共通のノウハウ

  • storageは最低でも20GBないと起動しない
  • AZは2つ設定しないと起動しない(1つはNG)
  • パスワードは8文字以上が必要
  • DBの起動に3分30秒ぐらいかかる

destroy時のポイントはskip_final_snapshotをtrueにすることです。これを入れないとsnapshotが存在するため、素直にdestoryしてくれません。

skip_final_snapshot = true

以下の記事を参考にしました。

RDSはリソース削除時にデフォルトでスナップショットの作成が求められるため、terraform destroyを行うためにはtfファイルにskip_final_snapshotのオプションをtrueに指定する必要があります。デフォルトはfalse。本番環境で行う場合は注意しましょう。(AWSのEC2とRDSをTerraformで構築する Terraform3分クッキング - Qiita)

実際の定義

少し変更していますが、以下のような定義になります。参考として。

vpc

resource "aws_vpc" "dev-env" {
    cidr_block = "10.0.0.0/16"
    instance_tenancy = "default"
    enable_dns_support = "true"
    enable_dns_hostnames = "true"
    tags = {
      Name = "dev-env"
    }
}

DB

resource "aws_db_instance" "test-db" {
  identifier           = "test-db"
  allocated_storage    = 20
  storage_type         = "gp3"
  engine               = "postgres"
  engine_version       = "14.6"
  instance_class       = "db.t4g.micro"
  db_name              = "testdb"
  username             = "test"
  password             = "testtest"
  vpc_security_group_ids  = ["${aws_security_group.praivate-db-sg.id}"]
  db_subnet_group_name = "${aws_db_subnet_group.public-db.name}"
  skip_final_snapshot = true
  publicly_accessible     = true
}