Cloud Intelligence™Cloud Intelligence™

Cloud Intelligence™

TerraformでAmazon Aurora MySQLクラスターをデプロイする

By TylerAug 5, 20246 min read

このページはEnglishDeutschEspañolFrançaisItalianoPortuguêsでもご覧いただけます。

クラウド上にデータベースを構築する際は、セキュリティ、スケーラビリティ、運用性のバランスを慎重に見極める必要があります。設定の誤りや最適化不足は、運用上のトラブルや技術的負債を招き、最悪の場合は障害やパフォーマンス劣化を通じて事業に深刻な影響を及ぼしかねません。Amazon Aurora MySQLは、優れたスケーラビリティと堅牢なセキュリティを兼ね備えたリレーショナルデータベースサービスです。

本記事では、Terraformを使ってAmazon Aurora MySQLクラスターのデプロイを自動化する方法を紹介します。読み取りスケーリング向けに複数のリーダーインスタンスを備えた高可用性構成の作り方を中心に解説します。

前提条件:

  • AWSアカウント
  • ローカル環境にTerraformがインストール済みであること
  • AWSサービスとTerraformの基本的な知識
  • GitHubリポジトリで公開しているTerraformコード

プロジェクトの構成: 本Terraformプロジェクトは、見通しの良さと再利用性を重視してモジュール単位に分割しています。主なモジュールは次のとおりです。

  • KMSモジュール: データベース用の暗号化キーを管理します。
  • Auroraクラスターモジュール: Aurora MySQLクラスターのデプロイと設定を担います。

モジュール構成のディレクトリ概要

このディレクトリ構成は、AWS KMSによる暗号化を備えたAmazon Aurora MySQLクラスターをデプロイするためのTerraformコードを、効率よく整理・運用できるよう設計されています。

ルートディレクトリ

main.tfproviders.tfterraform.tfvarsvariables.tfoutputs.tfを配置します。

  • main.tf: 各モジュールを呼び出すメイン設定ファイル。
  • providers.tf: プロバイダー設定とバージョン要件を定義。
  • variables.tf: 設定全体で利用する変数を宣言。
  • terraform.tfvars: 他で定義した変数の上書き値を設定。
  • outputs.tf: Terraform設定からの出力を定義。

Modulesディレクトリ

プロジェクトで使用するモジュールごとにサブディレクトリを設けます。

KMSモジュール: 保管時データを暗号化するためのAWS KMSキーの作成と管理を担います。

  • main.tf: KMSキーを作成するリソースを記述。
  • variables.tf: KMS固有の入力変数を定義。
  • outputs.tf: KMSリソースの出力属性を提供。

Auroraクラスターモジュール: Aurora MySQLクラスターのデプロイを管理します。

  • main.tf: Aurora MySQLクラスターと関連リソースを構成。
  • variables.tf: Aurora MySQLクラスター固有の入力変数を列挙。
  • outputs.tf: データベースエンドポイントなどの属性を出力。

この構成によりコードベースが整理され、Terraformコードの再利用性と保守性が高まります。クラウドリソースをより効率的に管理できるようになります。

1\. KMSモジュールのセットアップ

保管時データの暗号化は、データ保護の基本です。Aurora MySQLクラスターのキー管理にはAWS KMSを利用します。具体的には、AWSカスタマーマネージドキー(CMK)を使い、Auroraクラスターを暗号化するキーをユーザー自身で作成・管理・所有します。AuroraクラスターでAWSマネージドKMSキーではなく独自のKMSキーを管理することには、次のような利点があります。CMKでは、利用・管理できる主体をきめ細かく制御するアクセスポリシーを設定でき、CMKの利用はすべてCloudTrailに記録されるため監査にも活用でき、規制対応の面でも重要です。さらに、利用できるリージョンを限定するといった地理的な制御も可能です。CMKの利用料金(ストレージとAPI利用に対して課金)はAWSマネージドキーよりも見通しやすく透明性も高く、予算策定やコスト管理に役立ちます。

KMSモジュールはこれらのキーの作成と管理を担い、モジュールのoutputs.tfでAuroraモジュールが参照するKMSキー名を出力します。

# KMS Module - variables.tf
variable "rds" {
  description = "Enable customer managed KMS key for RDS"
  default     = true
  type        = bool
}
# KMS Module - main.tf
resource "aws_kms_key" "rds" {
  description             = "KMS key for RDS"
  enable_key_rotation     = true
  deletion_window_in_days = 30
}

解説:

  • キーローテーション: 暗号化キーを定期的に自動更新することで、セキュリティを強化します。
  • 削除待機期間: 削除されたキーが完全に破棄されるまでの猶予期間を指定し、必要に応じて復旧できるようにします。

2\. Auroraクラスターモジュールの設定

Auroraクラスターモジュールは、本デプロイの中核を担う部分です。性能と可用性に関する仕様に沿ってデータベースを構築します。デプロイするデータベースエンジンの指定から、利用する既存のVPCやセキュリティグループの設定、さらにはモジュールからprevent_destroy = trueのlifecycle句を明示的に削除しない限りTerraformによる誤削除を防ぐオプションまで、幅広い設定が可能です。

# Aurora Cluster Module - variables.tf
variable "read_replica_count" {
  description = "Number of Read Replicas in addition to Writer instance"
  type        = number
}
# Aurora MySQL Cluster config
resource "aws_rds_cluster" "aurora_mysql_cluster" {
  cluster_identifier                    = var.name
  engine                                = var.engine
  engine_mode                           = var.engine_mode
  engine_version                        = var.aurora_mysql_cluster_engine_version
  database_name                         = var.database_name

  master_username                       = var.aurora_mysql_cluster_master_username

  # Create and store password in Secrets Manager
  manage_master_user_password           = true
  final_snapshot_identifier             = "${var.name}-snapshot"
  skip_final_snapshot                   = var.skip_final_snapshot
  deletion_protection                   = var.deletion_protection
  backup_retention_period               = var.backup_retention_period
  preferred_backup_window               = var.backup_window
  preferred_maintenance_window          = var.maintenance_window
  port                                  = var.port
  db_subnet_group_name                  = aws_db_subnet_group.db_subnet_group.name
  vpc_security_group_ids                = concat(var.security_group_ids, [aws_security_group.aurora_mysql_sg.id])

  apply_immediately                     = true
  iam_database_authentication_enabled   = false
  copy_tags_to_snapshot                 = true
  storage_encrypted                     = true
  kms_key_id                            = var.kms_key_id

  db_cluster_parameter_group_name       = aws_rds_cluster_parameter_group.cluster_param_group.name

  enabled_cloudwatch_logs_exports = var.engine_mode == "serverless" ? [] : var.enabled_cloudwatch_logs_exports

  tags = merge(var.tags, { "Name" = var.name })

  lifecycle {
    ignore_changes = [ engine_version, scaling_configuration, engine_mode ]
    prevent_destroy = true
  }
}

# Aurora MySQL Instances within Cluster - one Writer and "read_replica_count" Readers
resource "aws_rds_cluster_instance" "aurora_mysql_instance" {
  count                             = var.engine_mode == "serverless" ? 0 : (1 + var.read_replica_count)
  identifier                        = "${var.name}-${count.index}"
  cluster_identifier                = aws_rds_cluster.aurora_mysql_cluster.id
  engine                            = var.engine
  engine_version                    = var.aurora_mysql_cluster_engine_version
  instance_class                    = var.instance_type

  db_subnet_group_name              = aws_db_subnet_group.db_subnet_group.name
  db_parameter_group_name           = aws_db_parameter_group.db_param_group.name

  monitoring_role_arn               = var.create_monitoring_role && var.monitoring_interval > 0 ? aws_iam_role.rds_enhanced_monitoring[0].arn : null
  monitoring_interval               = var.create_monitoring_role && var.monitoring_interval > 0 ? var.monitoring_interval : null
  auto_minor_version_upgrade        = true

  performance_insights_enabled      = true

  tags                              = var.tags

  lifecycle {
    ignore_changes = [ engine_version ]
  }
}

主な設定パラメータ(terraform.tfvarsで指定します):

  • クラスター識別子: Auroraクラスターを一意に識別する値で、クラスター管理に欠かせません。
  • エンジン設定: データベースエンジンとバージョンを指定し、互換性や利用できる機能を確保します。Aurora MySQL 5.7.xとMySQL 8.0.xから選択できますが、AWSは5.7.xのサポートをすでに終了し、有償の延長サポートのみを提供しているため、現時点では8.0.xの利用を強く推奨します。
  • インスタンス数: ライターとあわせて作成するリーダーインスタンスの数を指定し、読み取りスケーリングを実現します。
  • セキュリティとネットワーク: クラスターを特定のVPCおよびセキュリティグループに関連付け、安全に隔離されたネットワーク環境で稼働させます。新しいAurora MySQLクラスターを配置したい既存VPCのサブネットIDなどの値を指定してください。
  • 認証情報の管理: Secrets Managerを使ってデータベースのユーザー名・パスワードを保管し、ベストプラクティスに沿った認証情報管理を実現します。

3\. 出力と運用管理

出力(Outputs)は、デプロイ後のクラスター運用に必要な接続情報を取得するためにも、必要に応じてモジュール間で実行時の値を受け渡すためにも重要です。

# Outputs - outputs.tf
output "aurora_cluster_endpoint" {
  description = "The endpoint at which the Aurora cluster is accessible"
  value       = aws_rds_cluster.aurora.endpoint
}
# Outputs - outputs.tf
output "aurora_cluster_reader_endpoint" {
  description = "The reader endpoint for the Aurora cluster"
  value       = aws_rds_cluster.aurora.reader_endpoint
}

4\. まとめ

TerraformでAmazon Aurora MySQLクラスターをデプロイすれば、構築プロセスがシンプルになり、環境をまたいでも一貫性と再現性を確保できます。KMSカスタマー暗号化キーやAuroraクラスターのきめ細かな設定をモジュール化することで、構成はモジュラーかつ柔軟に調整できる状態を保てます。本ソリューションでは、MySQLのマスターパスワードをSecrets Manager内にネイティブに作成・保管できるAWSの新機能も活用しています。このアプローチは、セキュリティ、スケーラビリティ、ディザスターリカバリーといったクラウドアーキテクチャのベストプラクティスに沿うものです。負荷増加に応じてリーダーをスケールアウトする場面でも、暗号化キーを安全に管理する場面でも、Terraformはシンプルな構成から極めて複雑な構成まで、幅広いユースケースのAWS Aurora MySQLクラスター運用を支える堅牢なソリューションです。

Terraformを使い、ご自身のユースケースに合わせたAurora MySQLクラスターをAWS環境にデプロイするにあたって、本記事の推奨内容に関してご不明な点はありませんか。

お気軽に DoiT International までお問い合わせください。シニアレベルのエンジニアのみで構成された当社は、高度なクラウドコンサルティング、アーキテクチャ設計、デバッグ支援、各種コンサルティングサービスを専門としています。