🛠️

SAMのデプロイでつまずきたくない!【初回と二回目以降のデプロイ失敗時のステータスコード】と【SAM CLIで不可能な操作がある】を理解する

2024/03/27に公開

まず答え

  • 初回デプロイに失敗・ロールバック後は スタックを削除→再デプロイする
  • 二回目以降のデプロイ(更新)に失敗・ロールバック後は 再デプロイ可能
  • 更新失敗時にロールバックしないオプションがあるが、SAM CLIでは失敗したリソースのみの更新やロールバック操作ができない
    • 基本的にはロールバックする方がよさそう

何が分からなかったのか

SAM CLIでデプロイ失敗時に再デプロイができたり、できなかったり…その状況を整理できていなかった

最初に知っておくべきこと

SAM CLIはSAMアプリケーションをCloudFormationを通してデプロイする

  • CloudFormationのスタックステータスコードを参照する
    今どんな状態?ということを正しく知る。
    ↓ドキュメント!

https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/using-cfn-describing-stacks.html#cli-stack-status-codes

  • SAMはCloudFormationを拡張したものだが、SAM CLIでCloudFormationの全ての機能を直接的に操作できるわけではない

【試してみる①】初回デプロイ失敗パターン:ROLLBACK_COMPLETE

※前提:sam deploy --guidedでデプロイする際にdisable rollbackはfalseにして失敗時はロールバックするように設定。
初めてスタックを作成する時に、なんらかの理由で失敗した場合、CloudFormationのステータスはROLLBACK_COMPLETEになる。
↓以下のような状態

このステータスについて、ドキュメントの説明はこのようになっています。

このステータスが存在するのは、スタックの作成が失敗した後のみです。部分的に作成されたスタックからすべてのオペレーションが適切にクリーンアップされたことを示します。この状態では、削除オペレーションのみを実行できます。

削除オペレーションのみを実行できます ということなので、テンプレートを修正して再デプロイすることはできません。
デプロイしようとすると以下のようになります。

$ sam deploy --stack-name deploy-test --region ap-northeast-1
~略~
Error: Failed to create changeset for the stack: deploy-test, An error occurred (ValidationError) when calling the CreateChangeSet operation: Stack:arn:aws:cloudformation:ap-northeast-1:XXXXXXXXXX:stack/deploy-test/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx is in ROLLBACK_COMPLETE state and can not be updated.

なのでsam deleteでスタックを削除してから再度デプロイすることで対処します。初回デプロイ時の話なのでスタック削除で問題ありません。

【試してみる②】二回目以降デプロイ失敗パターン:UPDATE_ROLLBACK_COMPLETE

※前提:sam deploy --guidedでデプロイする際にdisable rollbackはfalseにして失敗時はロールバックするように設定。
二回目以降、スタック更新時に、なんらかの理由で失敗した場合、CloudFormationのステータスはUPDATE_ROLLBACK_COMPLETEになる。
↓以下のような状態

このステータスについて、ドキュメントの説明は、

スタックの更新の失敗後、1 つ以上のスタックを前の動作状態に正常に戻しました。
となっています。
この場合は、テンプレートを修正して再デプロイ(sam buildsam deploy)が可能です。

【試してみる③】ロールバックしない設定でデプロイ失敗パターン:UPDATE_FAILED

上記二つと異なる前提sam deploy --guidedでデプロイする際にdisable rollbackはtrue(yes)にして失敗時にロールバックしないようにする
この設定の詳細はこちらです。
https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/stack-failure-options.html#stack-failure-options-overview
この設定でデプロイに失敗するとステータスはUPDATE_FAILEDになります。
↓以下のような状態

この状態で、テンプレートを修正して再デプロイしようとするとエラーが発生します。

$ sam deploy --stack-name deploy-test --region ap-northeast-1
~略~
Error: Failed to create/update the stack: deploy-test, An error occurred (ValidationError) when calling the ExecuteChangeSet operation: This stack is currently in a non-terminal [UPDATE_FAILED] state. To update the stack from this state, please use the disable-rollback parameter with update-stack API. To rollback to the last known good state, use the rollback-stack API

現在のSAM CLIではUPDATE_FAILEDステータスから再試行または失敗リソースのみ更新、ロールバックはできないようです。
対処法としてはコンソール上で操作することになります。

まとめ(所感)

  • 初回デプロイは失敗したらスタック削除して再度デプロイする
  • 二回目以降のデプロイ(更新)に失敗したら再デプロイ可能
  • SAM CLIではCloudFormationの機能全てを扱えるわけではないので注意。基本的にロールバックはした方が良さそう。

そもそもSAMとは、を考える

AWS SAMとはサーバーレスアプリケーションの構築と実行において開発体験を向上させるツールキットです。(参考:AWS Serverless Application Model (AWS SAM) とは
SAM CLIを使用することで開発サイクルを管理することができます。例えばローカルでの実行やテスト、コードの即時反映などの機能はSAMが開発者のためのツールであることの表れだと思います。(だからロールバックしない選択がSAMにはないのでは?と考察レベルで考えました。またsam deployも頻繁に実行するものではないと思います。)

不要な混乱を避けることができるよう、SAMおよびSAM CLIを利用した開発サイクルを設計することが(難しいですが)大切なのではと思いました。
実際に使いながら、ベストな開発サイクルをその都度探していきたいです。

GitHubで編集を提案
Fusic 技術ブログ

Discussion