インフォ・ラウンジ Advent Calendar 2023 の9日目です。
summary
AWS CDKの2.82.0から、AuroraServerlessV2がL2で作成できるようになっています。ただし、旧バージョンのCDKでAuroraServerlessV2を作成した場合、そのままアップデートしてcdk deploy
してしまうと、インスタンスのリプレイスが発生し、運用に支障が出ることがわかりました。諸々の問題がありましたが、2.89.0で新方式に切り替えることができました。機能が追加された際にはドキュメントよく確認してアップデートを行いましょう
(DEPRECATED)CDK 2.82.0未満を使用していた頃
先にも書きましたが、Aurora Serverless V2がCDKでL2対応したのは2.82.0からです
それ以前のバージョンでは、直接L2 Constructでは記述が不可能であったため普通にデータベースクラスターを作成したあと、別枠で定義されていたServerlessV2ScalingConfigurationProperty
を使って以下のような形でDBクラスターにキャパシティを割り当てていました。これで作成は可能で運用はできていたのですが、エスケープハッチと呼ばれる手法を使用しており、ベストな方法なのかはわからず少しモヤモヤしていました。
const dbCluster = new rds.DatabaseCluster(this, 'DbCluster', {
engine: rds.DatabaseClusterEngine.auroraMysql({
// Aurora Serverless v2に対応した3系を指定
version: rds.AuroraMysqlEngineVersion.VER_3_02_1
}),
instances: 2,
instanceProps: {
vpc: props.vpc,
// インスタンスタイプにサーバーレスを指定
instanceType: new ec2.InstanceType('serverless'),
vpcSubnets: vpc.selectSubnets({ subnetType: ec2.SubnetType.PRIVATE_ISOLATED }),
}
// ServerlessV2に対応していないので、Aspectsを使って設定を書き換える
Aspects.of(dbCluster).add({
visit(node) {
if (node instanceof rds.CfnDBCluster) {
node.serverlessV2ScalingConfiguration = {
minCapacity: 0.5,
maxCapacity: 4
}
}
}
})
}
エスケープハッチとは、L2の機能をL1を使って変更するもので、ここではAspectsを使って書き換えています。動くには動いていたのですが、説明すると深いのでこの点は今回は割愛します(参考リンクを置いておきます)。
CDK2.82.0以上を使用する
満を持してリリースされた2.82.0以降では、以下のようにしてAuroraServerlessV2のクラスタをエスケープハッチ無しで直接立ち上げることができるようになりました。
const dbCluster = new rds.DatabaseCluster(this, 'DbCluster', {
engine: rds.DatabaseClusterEngine.auroraMysql({
version: rds.AuroraMysqlEngineVersion.VER_3_02_1
}),
vpc: props.vpc,
vpcSubnets: props.vpc.selectSubnets({ subnetType: ec2.SubnetType.PRIVATE_ISOLATED }),
writer: rds.ClusterInstance.serverlessV2('Writer', {
instanceType: new ec2.InstanceType('serverless')
}),
readers: [
rds.ClusterInstance.serverlessV2('Reader', {
scaleWithWriter: true
})
],
serverlessV2MinCapacity: 0.5,
serverlessV2MaxCapacity: 4
})
変更点としては、instances
およびinstanceProps
が非推奨となり、writer
とreaders
、serverlessV2MaxCapacity
とserverlessV2MinCapacity
が追加になりました。
(writer
は単数形、readers
は複数形ですね。)
これにより、書き込みインスタンスと読み込みインスタンスそれぞれに個別の設定がすることができるようになり、キャパシティ設定もAspectsを使うことなくプロパティとして割り当てるように記述できるようになりました。わかりやすいですね。
今から新たに作成するときはこちらが良いでしょう。
(はまった)cdkを2.82.0未満から以上へバージョンアップするとインスタンスの置換が発生してしまう。
問題が発生するのは、このバージョンをまたいでCDKをアップデートした場合です。
バージョンアップをしてから、cdk diff
を行うと、インスタンスが再作成されるよと警告が出ます。
$ cdk --version
2.82.0
$ cdk diff DatabaseStack
(略)
Resources
[-] AWS::RDS::DBInstance DbCluster/Instance1 DatabaseInstance1XXXXX destroy
[+] AWS::RDS::DBInstance DbCluster/Writer DatabaseWriterYYYYY
それでは困るので調べて見ると、Identifierが変更されてしまうらしいことがわかったので、以下のようにインスタンスの識別名を既存インスタンスに従うようにしました。
(Identifierがすべての環境で一緒とは限らないので、それぞれの環境でよく確認してください)
// 'Instance1' と明示的に指定する
writer: rds.ClusterInstance.provisioned('Instance1', {
instanceType: new ec2.InstanceType('serverless'),
}),
readers: [
rds.ClusterInstance.serverlessV2('Instance2', {
scaleWithWriter: true
})
],
しかし、それだけではdestroyの表示が消えません。
これはインスタンスが一度消え、同じ名前で再作成されるように見えます。
Resources
[-] AWS::RDS::DBInstance DbCluster/Instance1 DatabaseInstance1XXXXX destroy
[+] AWS::RDS::DBInstance DbCluster/Instance1 DatabaseInstance1XXXXX
そこで改めてドキュメントを参照してみると、isFromLegacyInstanceProps
というマイグレーション時に使うものが実装されていることがわかったので利用してみます。
Only used for migrating existing clusters from using instanceProps to writer and readers.
// 'Instance1' と名前を指定しつつマイグレーション用のフラグを立てる
writer: rds.ClusterInstance.serverlessV2('Instance1', {
instanceType: new ec2.InstanceType('serverless'),
isFromLegacyInstanceProps: true
}),
readers: [
rds.ClusterInstance.serverlessV2('Reader', {
scaleWithWriter: true,
isFromLegacyInstanceProps: true
})
],
今度こそ、と思いながら実行しましたが、isFromLegacyInstanceProps
が存在しないという警告が出てハマります。
Object literal may only specify known properties, and 'isFromLegacyInstanceProps' does not exist in type 'ServerlessV2ClusterInstanceProps'.
なぜだ。。。このために実装されたプロパティではなかったのか。。。
(ここでハマってアップデートできず)
***
実はこの時点ではisFromLegacyInstanceProps
は ProvisionedClusterInstanceProps
に実装されたプロパティであって、ServerlessV2ClusterInstanceProps
には実装されていなかったのです。よく確認できていませんでした。。というか紛らわしい。
要望を出そうにもなんと説明するかとあれこれ悩んでいるうちに、これを解決するPRが立てられ、2.89.0でServerlessV2ClusterInstanceProps
にもisFromLegacyInstanceProps
が実装されました。
rds: isFromLegacyInstanceProps migration flag with ClusterInstance.serverlessV2
これによりめでたくCDKを最新にすることができました。感謝ですね。[※]
$ cdk --version
2.89.0
$ cdk diff DatabaseStack
There were no differences
[※]: ちなみに、一度アップデートに成功したからといって isFromLegacyInstanceProps
を消すことはできないようです(再びdestroy表示になる)。いずれ外せるのかもしれませんが。
まとめ
CDK2.82.0未満で作られたAuroraServerlessV2があるときは以下のようにしましょう
- CDKを2.82.0以上にアップデートする
-
ServerlessV2ClusterInstanceProps
を使用している場合は2.89.0以上
-
- インスタンスのIdentifier(名前)を一致させる
-
instance
,instanceProps
をやめ、writer
,readers
に書き換える -
isFromLegacyInstanceProps
をtrue
に設定する
AWS CDKは次々と機能追加や仕様変更が入っています(現時点では2.114.1まで進んでいます)。基本的には新しいバージョンを使っていく方がよいですが、バージョンアップ時に予期せぬ変更が入ったり、インスタンスの置換や廃棄が行われてしまうことがあります。溜まっていくと多方面でdiffが発生して大変になってくるので、定期的にバージョンを上げるようにしたほうがいいですね。逆に対応したからといってすぐに書き換えるのではなく、変更点をよく読んで修正をあてていきましょう。