メインコンテンツへスキップ

RDS(MySQL)をTerraformで構築

·
インフラ AWS Terraform ハンズオン・チュートリアル
目次

今日学んだこと
#

TerraformでRDS(MySQL)を構築しました。DBサブネットグループにはシングルAZ構成でも2つの異なるAZのサブネットが必須であること、パスワード管理の本番向け手法を学びました。

学習内容
#

背景
#

「Amazon Web Services 基礎からのネットワーク&サーバー構築」ではEC2上にMariaDBを構築していましたが、実務ではマネージドサービスのRDSを使うことが多いため、Terraformで構築しました。

構築するリソース
#

リソース名前説明
DB Subnet Grouppractice-db-subnet-groupRDS配置用(2AZ必須)
RDS Instancepractice-db-instanceMySQL 8.0

DBサブネットグループの作成
#

resource "aws_db_subnet_group" "main" {
  name       = "practice-db-subnet-group"
  subnet_ids = [aws_subnet.private_1.id, aws_subnet.private_2.id]

  tags = {
    Name = "practice-db-subnet-group"
  }
}

RDSはDBサブネットグループに最低2つの異なるAZのサブネットを要求します。これはマルチAZ配置でなくても必須です。

設定サブネット要件理由
シングルAZ2AZ必須将来のマルチAZ化に備えた設計
マルチAZ2AZ必須スタンバイを別AZに配置

RDSインスタンスの作成
#

resource "aws_db_instance" "main" {
  identifier     = "practice-db-instance"
  engine         = "mysql"
  engine_version = "8.0"

  instance_class    = "db.t3.micro"
  allocated_storage = 20
  storage_type      = "gp2"

  db_name  = "wordpress"
  username = "admin"
  password = "YourPassword123!"  # 学習用

  db_subnet_group_name   = aws_db_subnet_group.main.name
  vpc_security_group_ids = [aws_security_group.rds.id]

  publicly_accessible = false
  skip_final_snapshot = true  # 学習用

  tags = {
    Name = "practice-db-instance"
  }
}

設定項目の解説
#

基本設定
#

項目説明
identifierpractice-db-instanceRDSの識別子(エンドポイント名に使用)
enginemysqlDBエンジン(mysql, postgres, mariadb等)
engine_version8.0メジャーバージョン指定(マイナーは自動)

インスタンス設定
#

項目説明
instance_classdb.t3.microインスタンスタイプ(無料枠対象)
allocated_storage20ストレージ容量(GB)
storage_typegp2汎用SSD(gp3も選択可)

セキュリティ設定
#

項目説明
publicly_accessiblefalseインターネットから直接アクセス不可
vpc_security_group_ids[rds-sg]SGでアクセス制御

publicly_accessible = false を設定するとパブリックIPが付与されず、VPC内からのみ接続可能になります。本番環境では基本的にfalseを設定します。

学習用と本番用の設定の違い
#

項目学習用本番推奨
password直書きSecrets Manager or 変数
skip_final_snapshottruefalse(削除時にスナップショット作成)
deletion_protectionなしtrue(誤削除防止)
multi_azfalsetrue(高可用性)
backup_retention_period07以上(自動バックアップ)

パスワード管理(本番向け)
#

方法1: 変数で外部化
#

variable "db_password" {
  type      = string
  sensitive = true
}

resource "aws_db_instance" "main" {
  # ...
  password = var.db_password
}
# 実行時に指定
terraform apply -var="db_password=SecurePassword123!"

方法2: Secrets Manager(推奨)
#

data "aws_secretsmanager_secret_version" "db" {
  secret_id = "prod/db/password"
}

resource "aws_db_instance" "main" {
  # ...
  password = jsondecode(data.aws_secretsmanager_secret_version.db.secret_string)["password"]
}

Security Group設計(復習)
#

resource "aws_vpc_security_group_ingress_rule" "rds_mysql" {
  security_group_id            = aws_security_group.rds.id
  description                  = "MySQL from web server"
  from_port                    = 3306
  to_port                      = 3306
  ip_protocol                  = "tcp"
  referenced_security_group_id = aws_security_group.web.id
}

WebサーバーのSGをソースに指定することで、Webサーバーからのみ接続を許可します。

作成にかかる時間
#

RDSは作成に5〜10分かかります。terraform apply 実行後、気長に待ちます。

aws_db_instance.main: Still creating... [5m0s elapsed]
aws_db_instance.main: Still creating... [5m10s elapsed]
aws_db_instance.main: Creation complete after 5m15s

接続確認
#

WebサーバーからRDSに接続します。

# WebサーバーにSSH接続後
mysql -h practice-db-instance.xxxxx.ap-northeast-1.rds.amazonaws.com \
      -u admin -p
# パスワード入力後
mysql> use wordpress;

エンドポイントは terraform output またはAWSコンソールで確認できます。

output "rds_endpoint" {
  value = aws_db_instance.main.endpoint
}

EC2上のDB vs RDS
#

観点EC2上のDBRDS
管理負担高(パッチ、バックアップ自前)低(マネージド)
可用性自前で構築マルチAZオプションあり
コスト低め高め
柔軟性高(何でもできる)制限あり

基本はRDS推奨です。特殊な要件がある場合のみEC2を検討します。

まとめ
#

トピック内容
DBサブネットグループ2AZ必須(シングルAZ構成でも)
publicly_accessiblefalse でVPC内からのみ接続
skip_final_snapshot学習用はtrue、本番はfalse
パスワード管理直書きは学習のみ。本番はSecrets Manager
作成時間5〜10分かかる

参考
#