Aurora Serverless v2をterraformで作ってみた

## はじめに
Amazon Aurora Serverlessとは、AWSのサーバーレスのデータベースサービスです。

Aurora Serverless v2 の概要ページにあるように負荷の変動が激しいワークロードに適しています。
イベントなどで急に負荷が高まるような環境に向いていますね。

```
## Aurora Serverless v2 の概要から抜粋
Amazon Aurora Serverless v2 は、最も変化が激しく、要求の厳しいワークロードに適しています。
用途の例としては、データベースの使用負荷が短時間の間だけ増大し、その後に軽いアクティビティが長時間続くか、
またはアクティビティがまったく発生しなくなるケースが挙げられます。
例えば、定期的に販売促進イベントを行う小売り、ゲーム、スポーツなどのウェブサイト、
必要なときにレポートを作成するレポートデータベースなどがあります。
```

https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/aurora-serverless-v2.how-it-works.html

v2ということは当然v1がありまして、下記公式サイトにv1/v2の比較が一覧されています。
Multi-AZに対応、水平スケールも可能になっているなど、素晴らしいアップグレードです。

https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/aurora-serverless-v2.upgrade.html#aurora-serverless.comparison

とはいえ、採用の際にはユースケースに沿ったサービスか等、公式ドキュメントを参照の上ご判断ください。下記にユースケース/利点の情報がまとまっております。

https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/aurora-serverless-v2.html

## terraformで作ってみる
サンプルとしてterraformで作成してます。
使用バージョンは下記の通り。

| Name | Version |
|--|--|
|terraform| 1.3.4|
|hashicorp/aws| 4.38.0|

hashicorp/aws v4.12.0でaurora serverless v2がサポートされるようです。

https://github.com/hashicorp/terraform-provider-aws/blob/main/CHANGELOG.md#4120-april-28-2022

Aurora Serverless v2 mysql互換のものを想定した設定です。
`aws_rds_cluster`の`engine_mode`で`provisioned`にし、`serverlessv2_scaling_configuration`でmax/minの容量を設定して、`aws_rds_cluster_instanceでinstance_class`を`db.serverless`にすることでaurora serverless v2の環境を設定してます。
```
// rds paramater groupの設定
resource "aws_rds_cluster_parameter_group" "rds" {
  name   = "rds-cluster"
  family = "aurora-mysql8.0"

  parameter {
    name  = "character_set_database"
    value = "utf8mb4"
  }

  parameter {
    name  = "character_set_server"
    value = "utf8mb4"
  }

  parameter {
    name  = "collation_server"
    value = "utf8mb4_bin"
  }

}

// rds subnet groupの設定。
resource "aws_db_subnet_group" "group" {
  name       = "db-subnet"
  subnet_ids = local.subnet_ids
}

// cluster設定
resource "aws_rds_cluster" "cluster" {
  cluster_identifier = "db-cluster"
  engine             = "aurora-mysql"
  // aurora serverless v2は engine_modeがprovisionedになります
  engine_mode                     = "provisioned"
  availability_zones              = local.availability_zones
  engine_version                  = "8.0.mysql_aurora.3.02.0"
  db_subnet_group_name            = aws_db_subnet_group.group.name
  database_name                   = "app_db"
  master_username                 = var.rds_username
  master_password                 = var.rds_password
  backtrack_window                = 0
  backup_retention_period         = local.backup_retention_period
  db_cluster_parameter_group_name = aws_rds_cluster_parameter_group.rds.name
  port                            = 3306
  skip_final_snapshot             = false
  storage_encrypted               = true
  vpc_security_group_ids          = local.vpc_security_group_ids

  // aurora serverless v2のmax/minの容量を設定
  serverlessv2_scaling_configuration {
    min_capacity = local.min_capacity
    max_capacity = local.max_capacity
  }

  deletion_protection       = true
  apply_immediately         = true
  final_snapshot_identifier = "final-snapshot-db-cluster"

  lifecycle {
    ignore_changes = [
      master_password,
      availability_zones
    ]
  }
}

resource "aws_db_parameter_group" "rds" {
  name   = "db-instance"
  family = "aurora-mysql8.0"
}

// rds instanceの設定
resource "aws_rds_cluster_instance" "instance" {
  // instance数を設定
  count = local.rds_num_nodes
  // instance数に応じて順次az設定
  availability_zone  = local.availability_zones[count.index % length(local.availability_zones)]
  cluster_identifier = aws_rds_cluster.cluster.id
  // instance数に応じて01、02とinstance名を連番に設定
  identifier                 = "db-instance${format("%02d", count.index + 1)}"
  engine                     = aws_rds_cluster.cluster.engine
  engine_version             = aws_rds_cluster.cluster.engine_version
  // serverlessを指定
  instance_class             = "db.serverless"
  db_subnet_group_name       = aws_db_subnet_group.group.name
  db_parameter_group_name    = aws_db_parameter_group.rds.name
  publicly_accessible        = false
  auto_minor_version_upgrade = false
}
```
パスワードはvariableで設定するようにします。
```
variable "rds_username" {
  description = "RDS のユーザー名"
  type        = string
}

variable "rds_password" {
  description = "RDS のパスワード"
  type        = string
}
```
capacityなどの設定値は用途によって変更があるかと思いますので
local変数で変更できるように設定しております。
```
locals {
  // インスタンスを配置するサブネットの指定
  subnet_ids              = ["subnet-xxxxxxxxxxxxxxxxx", "subnet-xxxxxxxxxxxxxxxxx", "subnet-xxxxxxxxxxxxxxxxx"]
  // インスタンスを配置するazの指定
  availability_zones      = ["ap-northeast-1a", "ap-northeast-1c", "ap-northeast-1d"]
  // 自動バックアップ世代数の指定
  backup_retention_period = 7
  // セキュリティグループの指定
  vpc_security_group_ids  = ["sg-xxxxxxxxxxxxxxxxx"]
  // Aurora Serverless v2の最小容量の指定
  min_capacity            = 0.5
  // Aurora Serverless v2の最大容量の指定
  max_capacity            = 1
  // instance数の指定
  rds_num_nodes           = 3
}
```

## おわりに
こちらでterraformを使用してAurora Serverless v2が作成できました。
ユースケースに合うようであればどんどん活用していきたいですね！


### 参考
こちらを参考にさせていただきました！

https://kiririmode.hatenablog.jp/entry/20220529/1653807751