Aurora/AuroraServerless(V1/V2)をCloudFormationで構築するサンプルとTips

# 序文
みなさん、Aurora/Aurora Serverless使ってますか？
弊社ではほとんどの案件でDBにAurora（MySQL互換）ファミリーのいずれかを採用しています。
理由は簡単で、DBのスケールに関してほぼおまかせできる、という点に尽きます。

また、2022/04/21にGAとなったAurora Serverless V2も、2022/10/05よりCloudFormationにて構築できるようになりました。
そこで今回はAuroraファミリーそれぞれをCloudFormationで構築するサンプルをご紹介していこうと思います。
なお、記述は対象となるAuroraを最低限起動できるだけのものとしていますので、必要に応じてドキュメントを参照しつつ、追加していくことを想定しています。

あ、MySQLでしか試していませんのでご了承下さいませ :bow:

# Aurora (provisioned) / Engine: aurora
はい、トップバッターの無印Auroraです。
Serverlessとの区別のためにあえて「provisioned（プロビジョンド）」と言ったりもします。
また、後述しますがエンジンをauroraと指定するとMySQL5.6互換のものとなります。
ここではあえて2台（Writer/Reader各1台ずつ）のインスタンスを持たせていますが、当然1台でも問題ありません。

```yaml 
AWSTemplateFormatVersion: 2010-09-09
Resources:
  DBCluster:
    Type: AWS::RDS::DBCluster
    Properties:
      Engine: aurora
      MasterUsername: user
      MasterUserPassword: password
  DBInstance1:
    Type: AWS::RDS::DBInstance
    Properties:
      DBClusterIdentifier: !Ref DBCluster
      Engine: aurora
      DBInstanceClass: db.t2.small
  DBInstance2:
    Type: AWS::RDS::DBInstance
    Properties:
      DBClusterIdentifier: !Ref DBCluster
      Engine: aurora
      DBInstanceClass: db.t2.small
```

## DBクラスタ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/39622/b44ef1b2-a188-ad5f-91d8-023a4093eeed.png)

エンジンに `aurora` とだけ指定するとMySQL5.6互換のクラスタが作成されます。
今回は `5.6.mysql_aurora.1.22.5` が作成されましたが、実行時期により変動します。
事前にどのバージョンが作られるかを調べる際にはAWS CLIで以下のように実行すると分かります。

```console
$ aws rds describe-db-engine-versions --engine aurora --default-only | jq -r '.DBEngineVersions[].EngineVersion'
5.6.mysql_aurora.1.22.5
```

## DBインスタンス
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/39622/17d51459-4363-1216-d564-914990873ee8.png)

インスタンスクラスに関してはエンジン・エンジンバージョンにより指定可能なもの・不可能なものがありますが、指定しないと起動できないという良く分からない縛りがあります。
指定可能なものについてはAWS CLIにて取得可能です。

```console
$ aws rds describe-orderable-db-instance-options --engine aurora --engine-version 5.6.mysql_aurora.1.22.5 | jq -r '.OrderableDBInstanceOptions[].DBInstanceClass'
db.r3.2xlarge
db.r3.4xlarge
db.r3.8xlarge
db.r3.large
db.r3.xlarge
db.r4.16xlarge
db.r4.2xlarge
db.r4.4xlarge
db.r4.8xlarge
db.r4.large
db.r4.xlarge
db.r5.12xlarge
db.r5.16xlarge
db.r5.24xlarge
db.r5.2xlarge
db.r5.4xlarge
db.r5.8xlarge
db.r5.large
db.r5.xlarge
db.t2.medium
db.t2.small
db.t3.medium
db.t3.small
```

# Aurora (provisioned) / Engine: aurora-mysql
続いて無印Auroraのエンジンを `aurora-mysql` としたものです。
上のものと比較すると `Engine: aurora-mysql` の部分しか違いがないことが確認できます。

```yaml
AWSTemplateFormatVersion: 2010-09-09
Resources:
  DBCluster:
    Type: AWS::RDS::DBCluster
    Properties:
      Engine: aurora-mysql
      MasterUsername: user
      MasterUserPassword: password
  DBInstance1:
    Type: AWS::RDS::DBInstance
    Properties:
      DBClusterIdentifier: !Ref DBCluster
      Engine: aurora-mysql
      DBInstanceClass: db.t2.small
  DBInstance2:
    Type: AWS::RDS::DBInstance
    Properties:
      DBClusterIdentifier: !Ref DBCluster
      Engine: aurora-mysql
      DBInstanceClass: db.t2.small
```

## DBクラスタ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/39622/a1bf7917-f0de-c2bb-a355-c4f9f43fb344.png)

エンジンに `aurora-mysql` と指定すると現在はMySQL5.7互換のクラスタが作成されますが、もしかするといずれはMySQL8.0互換となるかもしれません。

```console
$ aws rds describe-db-engine-versions --engine aurora-mysql --default-only | jq -r '.DBEngineVersions[].EngineVersion'
5.7.mysql_aurora.2.10.2
```

## DBインスタンス
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/39622/8da41dac-64d9-0080-5b18-0e3330949c23.png)

こちらは特に違いがありませんね。

# Aurora Serverless (v1) / Engine: aurora
ServerlessのV1です。
Serverless V1はインスタンスサイズが負荷状況に応じて自動的にスケールするのでインスタンスというものを指定する必要がありません。
そのためテンプレートもすごくシンプルです。

```yaml
AWSTemplateFormatVersion: 2010-09-09
Resources:
  DBCluster:
    Type: AWS::RDS::DBCluster
    Properties:
      Engine: aurora
      EngineMode: serverless
      MasterUsername: user
      MasterUserPassword: password
```

## DBクラスタ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/39622/f8c82e4a-ab93-6530-be8f-b613863faef5.png)

何故かServerlessだと設定変更画面に行かないとバージョンが表示されないのですが、provisionedのときと同様に、エンジンに `aurora` だけを指定するとMySQL5.6互換となります。
AWS CLIでServerlessに限定して調べる際には以下のようなフィルタを指定します。

```console
$ aws rds describe-db-engine-versions --engine aurora --filters Name=engine-mode,Values=serverless --default-only | jq -r '.DBEngineVersions[].EngineVersion'
5.6.mysql_aurora.1.22.3
```

## 設定項目
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/39622/4d2a1c6a-3a16-2db3-d1da-6f3ae581dae8.png)

Serverlessで設定される項目は上記の通りとなります。
テンプレートで以下のようなものを書いたのと同じ・・・と言いたいところですが、「オートスケーリングのタイムアウト」時間を指定（`SecondsBeforeTimeout`）することが（執筆時点では）できません。

:::note warn
`Undefined` ではなく `Not Permitted` として怒られる
> Properties validation failed for resource DBCluster with message: #/ScalingConfiguration: extraneous key [SecondsBeforeTimeout] is not permitted
:::

```yaml
      ScalingConfiguration:
        MinCapacity: 2
        MaxCapacity: 16
        # SecondsBeforeTimeout: 300
        TimeoutAction: RollbackCapacityChange
        AutoPause: true
        SecondsUntilAutoPause: 300
```

# Aurora Serverless (v1) / Engine: aurora-mysql
Serverless V1のエンジン指定です。
変更点は `Engine: aurora-mysql` 部分だけですね。

```yaml
AWSTemplateFormatVersion: 2010-09-09
Resources:
  DBCluster:
    Type: AWS::RDS::DBCluster
    Properties:
      Engine: aurora-mysql
      EngineMode: serverless
      MasterUsername: user
      MasterUserPassword: password
```

## DBクラスタ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/39622/d29dce3b-9393-0dde-795d-54755c05bf1a.png)

完全に予想通りの結果かと思います。

```console
aws rds describe-db-engine-versions --engine aurora-mysql --filters Name=engine-mode,Values=serverless --default-only | jq -r '.DBEngineVersions[].EngineVersion'
5.7.mysql_aurora.2.08.3
```

# Aurora Serverless V2（失敗集）
さて、Aurora Serverless V2ですがいささか複雑です。[以前の記事](https://qiita.com/edg_aim/items/7b9c765352318537c53d)でも触れたように、ServerlessのV2というよりはProvisionedにServerlessを組み合わせた感じになっています。
そのためテンプレートのベースはServerlessではなく、Provisionedの方に近く、DBインスタンスのクラス `DBInstanceClass` に `db.serverless` を指定したものがServerless V2インスタンスとなります。
また、Serverless V1と違い、設定項目が必須となっている部分が多数存在します。

エンジンには `aurora` ではなく `aurora-mysql` を指定していますが理由は後述します。
まずはできそうでできないパターンをいくつか。

## （失敗例）バージョン指定なし、スケール設定なし

`Aurora (provisioned) / Engine: aurora-mysql` のテンプレートとほとんど一緒になります。

```yaml
AWSTemplateFormatVersion: 2010-09-09
Resources:
  DBCluster:
    Type: AWS::RDS::DBCluster
    Properties:
      Engine: aurora-mysql
      MasterUsername: user
      MasterUserPassword: password
  DBInstance1:
    Type: AWS::RDS::DBInstance
    Properties:
      DBClusterIdentifier: !Ref DBCluster
      Engine: aurora-mysql
      DBInstanceClass: db.serverless
  DBInstance2:
    Type: AWS::RDS::DBInstance
    Properties:
      DBClusterIdentifier: !Ref DBCluster
      Engine: aurora-mysql
      DBInstanceClass: db.serverless
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/39622/046b6904-29d9-e982-83cb-9b16edf55d76.png)

（処理タイミングによるかもしれませんが）「スケール設定をしなさい」と怒られます。

## （失敗例）バージョン指定なし
言われた通り、スケール設定だけをしてみたらこうなります。

```yaml
AWSTemplateFormatVersion: 2010-09-09
Resources:
  DBCluster:
    Type: AWS::RDS::DBCluster
    Properties:
      Engine: aurora-mysql
      MasterUsername: user
      MasterUserPassword: password
      ServerlessV2ScalingConfiguration:
        MinCapacity: 0.5
        MaxCapacity: 1.0
  DBInstance1:
    Type: AWS::RDS::DBInstance
    Properties:
      DBClusterIdentifier: !Ref DBCluster
      Engine: aurora-mysql
      DBInstanceClass: db.serverless
  DBInstance2:
    Type: AWS::RDS::DBInstance
    Properties:
      DBClusterIdentifier: !Ref DBCluster
      Engine: aurora-mysql
      DBInstanceClass: db.serverless
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/39622/c2d78a06-eb41-11ce-0b7b-8dd08d2bfa98.png)

ちょっと長いですが、 `db.serverless` インスタンスは `5.7.mysql_aurora.2.10.2` では指定できません、的なことで怒られます。
ここで `5.7.mysql_aurora.2.10.2` が出てきたのはエンジンに `aurora-mysql` だけを指定したので、デフォルトのバージョンが選択された、ということになります。

## （失敗例）スケール設定なし
両方設定しないとならないんだろうな、とは思うものの、せっかくなのでバージョンは指定したけどスケール設定をしなかった場合。
※ バージョン指定部分については後述します

```yaml
AWSTemplateFormatVersion: 2010-09-09
Resources:
  DBCluster:
    Type: AWS::RDS::DBCluster
    Properties:
      Engine: aurora-mysql
      EngineVersion: 8.0.mysql_aurora.3.02.1
      MasterUsername: user
      MasterUserPassword: password
  DBInstance1:
    Type: AWS::RDS::DBInstance
    Properties:
      DBClusterIdentifier: !Ref DBCluster
      Engine: aurora-mysql
      DBInstanceClass: db.serverless
  DBInstance2:
    Type: AWS::RDS::DBInstance
    Properties:
      DBClusterIdentifier: !Ref DBCluster
      Engine: aurora-mysql
      DBInstanceClass: db.serverless
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/39622/839be818-599a-6115-88f9-552fa99ac12d.png)

バージョン指定なし、スケール設定なしの時と同じように「スケール設定をしなさい」と怒られました。

# Aurora Serverless V2
お待ちかね、V2のテンプレートです。
先に述べた通り、基本的にはProvisionedのAuroraをベースに、クラスタには（適切なバージョンと）スケール設定をし、DBインスタンスクラスとして `db.serverless` を指定したものがServerless V2となります。
しかしながら、Provisionedの時と同様に「エンジン・エンジンバージョンにより指定可能なもの」が決められています。
「DBインスタンスクラスにコレを指定できるやつ」はAWS CLIで以下のようにすることで参照できます。

```console
$ aws rds describe-orderable-db-instance-options --engine aurora --db-instance-class db.serverless | jq -r '.OrderableDBInstanceOptions[].EngineVersion'
```
※ 結果なし

```console
$ aws rds describe-orderable-db-instance-options --engine aurora-mysql --db-instance-class db.serverless | jq -r '.OrderableDBInstanceOptions[].EngineVersion'
8.0.mysql_aurora.3.02.0
8.0.mysql_aurora.3.02.1
8.0.mysql_aurora.3.02.2
```
※ 執筆時にコマンド実行してみたら `8.0.mysql_aurora.3.02.2` が増えてましたが、実験時には `8.0.mysql_aurora.3.02.1` が最新だったのでテンプレート等もそれで通しています

ということで、Serverless V2に対応したクラスタを構築する際にはエンジンを `aurora-mysql` にし、エンジンバージョンには `8.0.mysql_aurora.3.02.x` を指定する必要がる、ということになります。

```yaml
AWSTemplateFormatVersion: 2010-09-09
Resources:
  DBCluster:
    Type: AWS::RDS::DBCluster
    Properties:
      Engine: aurora-mysql
      EngineVersion: 8.0.mysql_aurora.3.02.1
      MasterUsername: user
      MasterUserPassword: password
      ServerlessV2ScalingConfiguration:
        MinCapacity: 0.5
        MaxCapacity: 1.0
  DBInstance1:
    Type: AWS::RDS::DBInstance
    Properties:
      DBClusterIdentifier: !Ref DBCluster
      Engine: aurora-mysql
      DBInstanceClass: db.serverless
  DBInstance2:
    Type: AWS::RDS::DBInstance
    Properties:
      DBClusterIdentifier: !Ref DBCluster
      Engine: aurora-mysql
      DBInstanceClass: db.serverless
```

## DBクラスタ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/39622/72ae0ffa-107c-7229-1181-f95b13f42e7f.png)

DBクラスタ自体はProvisionedと大差ありませんね。

## DBインスタンス
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/39622/70ed2939-a5dd-c1ad-0a3a-ed541eb62ecd.png)

インスタンスタイプが `Serverless v2` となっています。

# Aurora Serverless V2 (provisioned-mix)
テンプレート的にはProvisionedとServerless V2にほとんど差がないことがお分かりいただけたと思います。
これはインスタンスの片方をProvisionedなものにしても動作する、ということでもあります。

ちなみにインスタンスクラスに `db.t4g.medium` を指定しているのは `8.0.mysql_aurora.3.02.1` で指定できるインスタンスで一番（安くて）小さいサイズだから、という理由です。

```console
$ aws rds describe-orderable-db-instance-options --engine aurora-mysql --engine-version 8.0.mysql_aurora.3.02.1 | jq -r '.OrderableDBInstanceOptions[].DBInstanceClass'
db.r5.12xlarge
db.r5.16xlarge
db.r5.24xlarge
db.r5.2xlarge
db.r5.4xlarge
db.r5.8xlarge
db.r5.large
db.r5.xlarge
db.r6g.12xlarge
db.r6g.16xlarge
db.r6g.2xlarge
db.r6g.4xlarge
db.r6g.8xlarge
db.r6g.large
db.r6g.xlarge
db.r6i.12xlarge
db.r6i.16xlarge
db.r6i.24xlarge
db.r6i.2xlarge
db.r6i.32xlarge
db.r6i.4xlarge
db.r6i.8xlarge
db.r6i.large
db.r6i.xlarge
db.serverless
db.t3.large
db.t3.medium
db.t4g.large
db.t4g.medium
```

## `db.serverless` + `db.t4g.medium`
```yaml
AWSTemplateFormatVersion: 2010-09-09
Resources:
  DBCluster:
    Type: AWS::RDS::DBCluster
    Properties:
      Engine: aurora-mysql
      EngineVersion: 8.0.mysql_aurora.3.02.1
      MasterUsername: user
      MasterUserPassword: password
      ServerlessV2ScalingConfiguration:
        MinCapacity: 0.5
        MaxCapacity: 1.0
  DBInstance1:
    Type: AWS::RDS::DBInstance
    Properties:
      DBClusterIdentifier: !Ref DBCluster
      Engine: aurora-mysql
      DBInstanceClass: db.serverless
  DBInstance2:
    Type: AWS::RDS::DBInstance
    Properties:
      DBClusterIdentifier: !Ref DBCluster
      Engine: aurora-mysql
      DBInstanceClass: db.t4g.medium
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/39622/90646a18-10e3-31df-35ca-5c34d7d1d8a7.png)

からのフェイルオーバーもばっちり。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/39622/ecbc7b35-bca5-6f45-b2d4-598970d6773c.png)



## `db.t4g.medium` + `db.serverless`
```yaml
AWSTemplateFormatVersion: 2010-09-09
Resources:
  DBCluster:
    Type: AWS::RDS::DBCluster
    Properties:
      Engine: aurora-mysql
      EngineVersion: 8.0.mysql_aurora.3.02.1
      MasterUsername: user
      MasterUserPassword: password
      ServerlessV2ScalingConfiguration:
        MinCapacity: 0.5
        MaxCapacity: 1.0
  DBInstance1:
    Type: AWS::RDS::DBInstance
    Properties:
      DBClusterIdentifier: !Ref DBCluster
      Engine: aurora-mysql
      DBInstanceClass: db.t4g.medium
  DBInstance2:
    Type: AWS::RDS::DBInstance
    Properties:
      DBClusterIdentifier: !Ref DBCluster
      Engine: aurora-mysql
      DBInstanceClass: db.serverless
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/39622/da7cc587-3184-3fd7-791d-87e95cd0fead.png)

こちらも当然フェイルオーバー問題なしです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/39622/80fe8e2a-e889-dc4d-c98f-5eb6497482b4.png)