lambda + Dynamo DBのサーバーレスなWeb APIを開発しています。インフラ構築は勉強を兼ねてAWS SAMを利用。
テンプレート上でDynamoの定義変更を行いデプロイしたところ、以下のエラーが発生。
CloudFormation cannot update a stack when a custom-named resource requires replacing. Rename FugaDynamoDBTable and update the stack again.
一度テンプレート上で削除してからデプロイ、さらに再び構築するとうまくいきました。以下その過程です。
やりたかったこと & エラー
開発中、DynamoのGSIを貼り直したくなった。テンプレートで定義し直しデプロイするとまるっとリプレイスされるが、該当テーブルには手動で入れたテストデータしかなかったので問題無し。
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Resources:
HogeFunction:
Type: AWS::Serverless::Function
Properties: #中略
FugaDynamoDBTable:
Type: AWS::DynamoDB::Table
Properties:
TableName: FugaTable
GlobalSecondaryIndexes: # ←ここに変更を加えた
# 以下略
sam build
→ sam deploy
と打ち、出力を観察。
CloudFormation stack changeset (抜粋)
---------------------------------------------------------------------------------------------
Operation LogicalResourceId ResourceType Replacement
---------------------------------------------------------------------------------------------
* Modify FugaDynamoDBTable AWS::DynamoDB::Table True
: : : :
ReplacementがTrueで問題ないので、そのままデプロイしたところ、該当のDynamoのアップデートに以下のエラーが発生しロールバックが実行された。
CloudFormation cannot update a stack when a custom-named resource requires replacing. Rename FugaDynamoDBTable and update the stack again.
対応
エラーメッセージはテーブル名 (FugaTable
)を変更するように言っている。しかしテーブル名は変えたくない。
AWS CloudFormation > ユーザーガイド > スタックのリソースの更新動作によると、リプレイスは置換リソースを作ってから古いリソースを削除するらしい。そこで「名前が被っているのが悪いのかな」と考え、Dynamo DBのwebコンソールから手動で削除し、再デプロイ。しかし結果は変わらず。
リソース名(FugaDynamoDBTable
)を変えれば新設リソースと見做されそうな気もするが、なんか気持ち悪い。
同じくユーザーガイドのName タイプに
スタックリソースの変更を AWS CloudFormation 以外で行うことも避けてください。たとえば、スタックに属しているリソースの名前を AWS CloudFormation を使用せずに変更した場合、そのスタックを更新または削除しようとしたときにエラーが発生します。
との記述を発見(ごめんなさい)。
ではテンプレート上でも無かったことにして実態に合わせようと、FugaDynamoDBTable
の定義を丸々コメントアウトし再度デプロイ。
CloudFormation stack changeset
------------------------------------------------------------------------------
Operation LogicalResourceId ResourceType Replacement
------------------------------------------------------------------------------
- Delete FugaDynamoDBTable AWS::DynamoDB::Table N/A
と確認され実行。特にエラーなく削除されたことになった。
再び該当部分をコメントインしデプロイ。
CloudFormation stack changeset
-----------------------------------------------------------------------------------
Operation LogicalResourceId ResourceType Replacement
-----------------------------------------------------------------------------------
+ Add FugaDynamoDBTable AWS::DynamoDB::Table N/A
意図通りのchangesetになったのでそのまま実行。無事にデプロイ。コンソール上でも意図した設定になっていることを確認できた。
追記
約1年前に全く同じ問題で全く同じ過程を辿った方がいた。SAMでハマったらCloudFormationの情報もちゃんと探すべきか。
CloudFormation内のDynamoDBリソース更新でハマった話