はじめに
CDKで作成したDynamoDBの請求モードをProvisioned→OnDemandに変更しようとしたら思いの外つまづいたのと、あまり情報がヒットしなかったのでまとめてみました。
結論
- CDKでDynamoDBの請求モードをOnDemandに変更するときは、ProvisionedモードでseedCapacityというプロパティを設定してから、OnDemandに切り替える必要がある。
このプロセスを踏まないと、OnDemandに変更することができない。
作業ログ
ますは以下のコードで請求モードをOnDemandに変更しようとしました。
(これは失敗します。)
const testTable = new TableV2(this, 'testTable', {
tableName: 'testTable',
partitionKey: { name: 'ID', type: AttributeType.STRING },
billing: Billing.onDemand()
// 以下、元々Provisionedで設定した箇所
// billing: Billing.provisioned({
// readCapacity: Capacity.autoscaled({
// minCapacity: 1,
// maxCapacity: 10,
// targetUtilizationPercent: 70
// }),
// writeCapacity: Capacity.autoscaled({
// minCapacity: 1,
// maxCapacity: 10,
// targetUtilizationPercent: 70
// }),
// })
})
cdk deployを行うと、下記エラーが発生
21:59:08 | UPDATE_FAILED | AWS::DynamoDB::GlobalTable | testTableFD9E8557
Resource handler returned message: "Invalid request provided: When switching billing mode to OnDemand, the previous templ
ate must specify a value for all autoscaled resources, so that Cloudformation can rollback if needed." (RequestToken: f18
ef8b3-5422-e3b7-c9fe-50bbb75aac21, HandlerErrorCode: InvalidRequest)
Cfnを確認すると、Rollbackが完了している状態
https://city-os-6hp5180.slack.com/archives/C05TV904517/p1716887610291779?thread_ts=1716885642.946889&cid=C05TV904517
ログを見ても解決方法が分からず、AWSサポートに上記コードとエラーログを送信してSeedCapacityという値を設定する必要があると回答がきたので、その通りに対応してみました。
ProvisionedモードでSeedCapacityを設定してDeploy
const testTable = new TableV2(this, 'testTable', {
tableName: 'testTable',
partitionKey: { name: 'ID', type: AttributeType.STRING },
// billing: Billing.onDemand()
billing: Billing.provisioned({
readCapacity: Capacity.autoscaled({
minCapacity: 1,
maxCapacity: 10,
targetUtilizationPercent: 70,
seedCapacity: 10 //このプロパティを追加
}),
writeCapacity: Capacity.autoscaled({
minCapacity: 1,
maxCapacity: 10,
targetUtilizationPercent: 70,
seedCapacity: 10 //このプロパティを追加
}),
})
Deployに成功したので、OnDemandでDeploy
const testTable = new TableV2(this, 'testTable', {
tableName: 'testTable',
partitionKey: { name: 'ID', type: AttributeType.STRING },
billing: Billing.onDemand()
// billing: Billing.provisioned({
// readCapacity: Capacity.autoscaled({
// minCapacity: 1,
// maxCapacity: 10,
// targetUtilizationPercent: 70,
// seedCapacity: 10
// }),
// writeCapacity: Capacity.autoscaled({
// minCapacity: 1,
// maxCapacity: 10,
// targetUtilizationPercent: 70,
// seedCapacity: 10
// }),
// })
})
しばらくするとDynamoDBのTableがOnDemandになっていることが確認できますが、CloudFormationスタックが終了するまでにはしばらく時間がかかります。
最後にCloudFormationスタックが完了になることを確認したら、終了です。
誰かの参考になれば幸いです。
※ソースコードは差分がわかりやすいようにコメントアウトしてますが、実際は不要なコードになるので削除しておきましょう。
参考文献
「AWS::DynamoDB::GlobalTable CapacityAutoScalingSettings - AWS CloudFormation」
SeedCapacity
You must also specify a value for SeedCapacity when you plan to switch a table's billing mode from PROVISIONED to PAY_PER_REQUEST, because CloudFormation might need to roll back the operation (reverting the billing mode to PROVISIONED) and this cannot succeed without specifying a value for SeedCapacity.