CDKでDynamoDBの請求モードをProvisionedからOnDemandに変更できない場合の対処方法

# はじめに
CDKで作成したDynamoDBの請求モードをProvisioned→OnDemandに変更しようとしたら思いの外つまづいたのと、あまり情報がヒットしなかったのでまとめてみました。

# 結論
1. CDKでDynamoDBの請求モードをOnDemandに変更するときは、ProvisionedモードでseedCapacityというプロパティを設定してから、OnDemandに切り替える必要がある。　　
このプロセスを踏まないと、OnDemandに変更することができない。


# 作業ログ
ますは以下のコードで請求モードをOnDemandに変更しようとしました。
（これは失敗します。）
```javascript

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が完了している状態
![スクリーンショット 2024-05-28 22.28.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/77473/eb29f8d8-f7cc-b355-4357-95d9e9529ba2.png)
https://city-os-6hp5180.slack.com/archives/C05TV904517/p1716887610291779?thread_ts=1716885642.946889&cid=C05TV904517

ログを見ても解決方法が分からず、AWSサポートに上記コードとエラーログを送信してSeedCapacityという値を設定する必要があると回答がきたので、その通りに対応してみました。



### ProvisionedモードでSeedCapacityを設定してDeploy
```javascript

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

```javascript
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」

https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dynamodb-globaltable-capacityautoscalingsettings.html#cfn-dynamodb-globaltable-capacityautoscalingsettings-seedcapacity 

>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.