背景
AWS CDKでAurora MySQL 2(5.7互換)を使用していた。しかしAurora Serverless v2の検証をしたいため、Aurora MySQL 3(8互換)にアップグレードをする必要があった。
以下の記事に記載の通り、簡単にアップグレードできるものと踏んでいたが、かなりハマったので試したことをまとめておく。
※おまけでCDK v2.50.0時点でAurora Serverless v2を実装する方法も記載。
前提
今回アップグレード対象のAurora MySQLは独自のDBクラスターパラメータグループ、DBパラメータグループ(カスタムパラメータグループ)を使用しているAuroraクラスターである。
2つのパラメータグループの違いや適用優先度等は以下を参照。
https://dev.classmethod.jp/articles/aurora-parameter-group-priority/
また、アップグレードとしてはAurora MySQL 2.10.0 -> Aurora MySQL 3.02.0であり、インプレースアップグレードがサポートされている。
検証結果
先に結論。No.4の2段階でアップグレードする手順だとうまくいった。
No | 内容 | 結果 |
---|---|---|
1 | カスタムパラメータグループとDBクラスターのバージョンのみ書き換える | エラーになる。 |
2 | カスタムパラメータグループの名称を変更してアップグレード後のものを新規作成する | エラーになる。 |
3 | DBクラスターの定義でカスタムパラメータグループの使用をコメントアウトし、一旦デフォルトを使用する | エラーになる。旧DBパラメータグループが削除されず、参照先がデフォルトになってくれない。※クラスターパラメータグループだけカスタムならこれでできる。 |
4 | DBクラスターの定義で、一旦デフォルトのパラメータグループを使用するよう明示して変更する。その後アップグレードする。 | うまくいった。 |
検証内容詳細
0.事前状態
以下のようにslow_query_log
を設定したカスタムパラメータグループを使用する。
※DBクラスターパラメータグループとDBパラメータグループで同じ項目を設定しても意味はない。あくまでカスタムパラメータグループの例として記載。
// クラスターパラメータグループを作成 const clusterParameterGroup = new rds.ParameterGroup(scope, 'ClusterParameterGroup', { engine: rds.DatabaseClusterEngine.auroraMysql({ version: AuroraMysqlEngineVersion.VER_2_10_0 }), parameters: { 'slow_query_log': '1', } }) //パラメータグループを作成 const instanceParameterGroup = new rds.ParameterGroup(scope, 'InstanceParameterGroup', { engine: rds.DatabaseClusterEngine.auroraMysql({ version: AuroraMysqlEngineVersion.VER_2_10_0 }), parameters: { 'slow_query_log': '1', } }) // DBクラスターを作成 this.dbCluster = new rds.DatabaseCluster(scope, 'Database', { engine: rds.DatabaseClusterEngine.auroraMysql({ version: AuroraMysqlEngineVersion.VER_2_10_0 }), parameterGroup: clusterParameterGroup, // クラスターパラメータグループを指定 instanceProps: { parameterGroup: instanceParameterGroup, // インスタンスパラメータグループを指定 allowMajorVersionUpgrade: true, // メジャーアップグレードを許可 //以下略 })
1. カスタムパラメータグループとDBクラスターのバージョンのみ書き換える
まずはシンプルにバージョンのみ直接書き換えてアップグレードを試してみる。
// クラスターパラメータグループを作成 const clusterParameterGroup = new rds.ParameterGroup(scope, 'ClusterParameterGroup', { engine: rds.DatabaseClusterEngine.auroraMysql({ version: AuroraMysqlEngineVersion.VER_3_02_0 //変更 }), //以下略 }) //パラメータグループを作成 const instanceParameterGroup = new rds.ParameterGroup(scope, 'InstanceParameterGroup', { engine: rds.DatabaseClusterEngine.auroraMysql({ version: AuroraMysqlEngineVersion.VER_3_02_0 //変更 }), //以下略 }) // DBクラスターを作成 this.dbCluster = new rds.DatabaseCluster(scope, 'Database', { engine: rds.DatabaseClusterEngine.auroraMysql({ version: AuroraMysqlEngineVersion.VER_3_02_0 //変更 }), //以下略 })
しかし以下のようにエラーになる。エンジンバージョンを変える場合は新しいパラメータグループを指定せよと言われる。
The current DB instance parameter group cdkfargatebastionstack-instanceparametergroupa9fcf4ba-1ecfumiwyxog is custom. You must explicitly specify a new DB instance parameter group, either default or custom, for the engine version upgrade. (Service: Rds, Status Code: 400, Request ID: d3b0aab7-d2a1-4da4-957e-3859697c4028)
2. カスタムパラメータグループの名称を変更してアップグレード後のものを新規作成する
調査したところCloudFormationに関して以下の記事を見つけた。
カスタムパラメータグループを使用している状態でアップグレードする場合、パラメータグループの論理IDを変更して新規作成扱いにすればうまくいくというものである。
https://dev.classmethod.jp/articles/upgrade-amazon-rds-using-aws-cloudformation/
そのため以下のように変更してみた。1との差分は論理IDに該当する部分にNew
をつけて新規作成扱いしている点である。
// クラスターパラメータグループを作成 const clusterParameterGroup = new rds.ParameterGroup(scope, 'NewClusterParameterGroup', { //変更 engine: rds.DatabaseClusterEngine.auroraMysql({ version: AuroraMysqlEngineVersion.VER_3_02_0 //変更 }), //以下略 }) //パラメータグループを作成 const instanceParameterGroup = new rds.ParameterGroup(scope, 'NewInstanceParameterGroup', { //変更 engine: rds.DatabaseClusterEngine.auroraMysql({ version: AuroraMysqlEngineVersion.VER_3_02_0 //変更 }), //以下略 }) // DBクラスターを作成 this.dbCluster = new rds.DatabaseCluster(scope, 'Database', { engine: rds.DatabaseClusterEngine.auroraMysql({ version: AuroraMysqlEngineVersion.VER_3_02_0 //変更 }), //以下略 })
これはうまくいくかと思ったが、残念ながらうまくいかなかった。1と同じエラーになった。
The current DB instance parameter group cdkfargatebastionstack-instanceparametergroupa9fcf4ba-1ecfumiwyxog is custom. You must explicitly specify a new DB instance parameter group, either default or custom, for the engine version upgrade. (Service: Rds, Status Code: 400, Request ID: a631d2d4-8754-4651-87ad-ee5f559bf61f)
3. DBクラスターの定義でカスタムパラメータグループの使用をコメントアウトし、一旦デフォルトを使用する
ここで作戦を変更し、一旦Aurora MySQL2の状態でデフォルトパラメータグループを使用の状態に変更→その後アップグレードという2段階で行うことを考えた。
初手として以下のようにカスタムパラメータグループの使用箇所をコメントアウトしてデプロイを試みる。
// DBクラスターを作成 this.dbCluster = new rds.DatabaseCluster(scope, 'Database', { engine: rds.DatabaseClusterEngine.auroraMysql({ version: AuroraMysqlEngineVersion.VER_2_10_0 }), //parameterGroup: clusterParameterGroup, // コメントアウト instanceProps: { //parameterGroup: instanceParameterGroup, // コメントアウト //以下略 })
しかしこれもうまくいかない、DBクラスターパラメータグループはデフォルトになってくれたが、DBパラメータグループがデフォルトにならない。削除しようとするが、インスタンスが使用中という状態になり、削除を試行→失敗を繰り返した後デプロイ失敗となってしまった。
上記のためDBクラスターパラメータだけカスタムしている場合は、これでもうまくいく。
One or more database instances are still members of this parameter group cdkfargatebastionstack-instanceparametergroupa9fcf4ba-1ecfumiwyxog, so the group cannot be deleted (Service: Rds, Status Code: 400, Request ID: c554810f-de50 -46fa-8934-6e19f3998862)
4. DBクラスターの定義で、一旦デフォルトのパラメータグループを使用するよう明示して変更する。その後アップグレードする(うまくいった手順)
3と同じく2段階だが、初手のデフォルトパラメータグループを明示する方法に変更してやってみた。
まず以下のように明示的にデフォルトパラメータグループを指定する。
// DBクラスターを作成 this.dbCluster = new rds.DatabaseCluster(scope, 'Database', { engine: rds.DatabaseClusterEngine.auroraMysql({ version: AuroraMysqlEngineVersion.VER_2_10_0 }), parameterGroup: rds.ParameterGroup.fromParameterGroupName(scope, 'DefaultClusterParameterGroup', 'default.aurora-mysql5.7'), //明示的にデフォルトを指定 instanceProps: { allowMajorVersionUpgrade: true, parameterGroup: rds.ParameterGroup.fromParameterGroupName(scope, 'DefaultParameterGroup', 'default.aurora-mysql5.7'),//明示的にデフォルトを指定 // },
この状態でcdk diff
を取ると以下のようにカスタムパラメータグループは削除、かつクラスターやインスタンスはデフォルトのパラメータグループを参照する形となる。
Resources [-] AWS::RDS::DBClusterParameterGroup ClusterParameterGroupF60E75FA destroy [-] AWS::RDS::DBParameterGroup InstanceParameterGroupA9FCF4BA destroy [~] AWS::RDS::DBCluster Database DatabaseB269D8BB └─ [~] DBClusterParameterGroupName └─ @@ -1,3 +1,1 @@ [-] { [-] "Ref": "ClusterParameterGroupF60E75FA" [-] } [+] "default.aurora-mysql5.7" [~] AWS::RDS::DBInstance Database/Instance1 DatabaseInstance1844F58FD └─ [~] DBParameterGroupName └─ @@ -1,3 +1,1 @@ [-] { [-] "Ref": "InstanceParameterGroupA9FCF4BA" [-] } [+] "default.aurora-mysql5.7"
これでデプロイすると、デフォルトのパラメーターグループになった!
2段階目として、カスタムパラメータグループとDBクラスターのバージョンを変更する。この際DBクラスターはカスタムパラメータグループを参照するようにする。
// クラスターパラメータグループを作成 const clusterParameterGroup = new rds.ParameterGroup(scope, 'ClusterParameterGroup', { engine: rds.DatabaseClusterEngine.auroraMysql({ version: AuroraMysqlEngineVersion.VER_3_02_0 //変更 }), parameters: { 'slow_query_log': '1', } }) //パラメータグループを作成 const instanceParameterGroup = new rds.ParameterGroup(scope, 'InstanceParameterGroup', { engine: rds.DatabaseClusterEngine.auroraMysql({ version: AuroraMysqlEngineVersion.VER_3_02_0 //変更 }), parameters: { 'slow_query_log': '1', } }) // DBクラスターを作成 this.dbCluster = new rds.DatabaseCluster(scope, 'Database', { engine: rds.DatabaseClusterEngine.auroraMysql({ version: AuroraMysqlEngineVersion.VER_3_02_0 //変更 }), parameterGroup: clusterParameterGroup, // カスタムパラメータグループを指定 instanceProps: { parameterGroup: instanceParameterGroup, // カスタムパラメータグループを指定 allowMajorVersionUpgrade: true, //以下略 })
この状態でデプロイを行うと、アップグレードに成功した。またDBクラスターもカスタムパラメータグループを参照している。めでたしめでたし。
オマケ
CDK v.2.50.0ではAurora Serverlessv2用のL2 Constructは存在しない。しかしCloudFormationは対応しているので、以下のようにEscape Hatchesを使用すれば簡単に実装できる。
this.dbCluster = new rds.DatabaseCluster(scope, 'Database', { // 中略 instanceProps: { instanceType: new ec2.InstanceType('serverless'), //インスタンスタイプでserverlessを指定 // }) // Escape Hatchesを使用して設定。 const cfnCluster = this.dbCluster.node.defaultChild as rds.CfnDBCluster; cfnCluster.addPropertyOverride('ServerlessV2ScalingConfiguration', { 'MaxCapacity': 5, 'MinCapacity': 0.5, }); cfnCluster.addPropertyDeletionOverride('EngineMode');
この状態でデプロイすれば以下の通りServerless v2のインスタンスが作成される。
おわりに
簡単にアップグレードできると思いきや意外にハマってしまった... カスタムパラメータグループ使ってるとなかなか厄介。