CloudFormation の ROLLBACK_FAILED の対処をやってみた

CloudFormation の ROLLBACK_FAILED の対処をやってみた

2025.10.15

はじめに

立神です。

学習を進める中で、CloudFormation で ROLLBACK_FAILED が発生すると対処が複雑になることを知りました。そこで今回は、実際に ROLLBACK_FAILED を再現し、その対処方法を確認してみます。

CloudFormation のロールバックとは

CloudFormation では、スタックの作成や更新が失敗した場合、
自動的にロールバック(巻き戻し)が実行されます。

スタック作成時に発生するロールバックの流れ

CREATE_IN_PROGRESS → CREATE_FAILED → ROLLBACK_IN_PROGRESS → ROLLBACK_COMPLETE
※ 今回のケースでは、ロールバック中にリソースの削除に失敗するため、最終的に ROLLBACK_FAILED 状態になります。

再現の仕組み

以下の流れで ROLLBACK_FAILED を発生させます:

  1. S3 バケットを作成(成功)
  2. 手動で S3 バケットにファイルをアップロード
  3. EC2 インスタンスを作成(失敗させる)
  4. ロールバック開始
  5. S3 バケット削除失敗(ファイルがあるため)
  6. ROLLBACK_FAILED 発生

やってみた

事前準備

以下の権限を持つ IAM ユーザー/ロールの用意

  • CloudFormation の操作権限(cloudformation:* など)
  • S3 の操作権限(s3:CreateBuckets3:DeleteBuckets3:PutObjects3:DeleteObject など)
  • EC2 の操作権限(ec2:RunInstancesec2:DescribeInstances など)
    今回は上記の権限を持つ IAM ユーザーで実行します。

CloudFormation テンプレートファイルの準備

今回は下記の JSON ファイルを用意しました。
こちらの公式ドキュメントを参考に AI に改良してもらいました。

https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/conditions-section-structure.html

template-rollback-failed.json
			
			{
  "AWSTemplateFormatVersion": "2010-09-09",
  "Description": "Template to reproduce ROLLBACK_FAILED scenario",
  "Resources": {
    "TestBucket": {
      "Type": "AWS::S3::Bucket",
      "Properties": {
        "BucketName": {
          "Fn::Sub": "rollback-test-${AWS::AccountId}-${AWS::StackName}"
        },
        "Tags": [
          {
            "Key": "Purpose",
            "Value": "RollbackTest"
          }
        ]
      }
    },
    "DummyWaitConditionHandle": {
      "Type": "AWS::CloudFormation::WaitConditionHandle"
    },
    "DummyWaitCondition": {
      "Type": "AWS::CloudFormation::WaitCondition",
      "DependsOn": "TestBucket",
      "Properties": {
        "Handle": {
          "Ref": "DummyWaitConditionHandle"
        },
        "Timeout": "300",
        "Count": 0
      }
    },
    "TestEC2Instance": {
      "Type": "AWS::EC2::Instance",
      "DependsOn": "DummyWaitCondition",
      "Properties": {
        "ImageId": "ami-INVALID-ID-WILL-FAIL",
        "InstanceType": "t3.micro",
        "Tags": [
          {
            "Key": "Name",
            "Value": "rollback-test-instance"
          }
        ]
      }
    }
  },
  "Outputs": {
    "BucketName": {
      "Description": "Name of the S3 bucket",
      "Value": {
        "Ref": "TestBucket"
      }
    }
  }
}

		

このテンプレートでは、以下の工夫により ROLLBACK_FAILED を再現しやすくしています:

  • WaitCondition の活用: S3 バケット作成後、EC2 インスタンス作成前に 300 秒(5 分)の待機時間を設けています。この間に手動でファイルをアップロードする時間を確保しています。
  • DependsOn の設定: リソース間の依存関係を明示的に定義し、作成順序を制御しています。
  • 無効な AMI ID の指定: EC2 インスタンスの作成を意図的に失敗させるため、存在しない AMI ID を指定しています。

スタックの作成

  1. CloudFormation コンソールで「スタックの作成」をクリックし、「新しいリソースを使用」を選択します
  2. 「テンプレートファイルのアップロード」を選択し、作成した JSON ファイルを選択します
    stack-upload
  3. 任意の名前を入力し、その他の設定は全てデフォルトのまま作成します

スタック作成イベントの監視

スタックを作成するとイベントタブに移行するので、更新ボタンを押しながらイベントを監視します。
すぐに S3 バケットの作成が始まるので、CREATE_COMPLETE の状態になるのを待ちます。
create-complete-event

S3 バケットにファイルをアップロード

CREATE_COMPLETE イベントが表示されたら、論理 ID のタブに表示されているバケット名をクリックして、S3 バケットを開きます。
適当なファイルをアップロードします。

アップロードが完了したら、バケット内にファイルが表示されていることを確認します。
bucket-object-mask

ロールバック開始イベントの監視

CloudFormation の画面に戻り、再度イベントタブを表示します。
EC2 インスタンスの作成に失敗(CREATE_FAILED)が表示された後、ロールバックを試行します。
元の状態(S3 バケットも EC2 インスタンスも存在しない最初の状態)に戻そうとしますが、S3 バケットにオブジェクトが存在しているため、S3 バケットの削除に失敗します(DELETE_FAILED)。

ここで ROLLBACK_FAILED が発生します。
rollback-failed-event

スタックの削除を試行

手動でスタックの削除をしてみます。
スタックの一覧画面から、作成したスタックを選択し、「削除」をクリックします。
しかし、同様に DELETE_FAILED になり、削除に失敗します。
delete-failed-event

ROLLBACK_FAILED への対処

最後に、本題である ROLLBACK_FAILED への対処を行います。
CloudFormation のイベントタブで、DELETE_FAILED となっているイベントの状態を見ると、以下のエラーメッセージが表示されています:
The bucket you tried to delete is not empty
このエラーは、S3 バケットが空ではないのに削除しようとした、というエラーです。

S3 バケットを空にする

S3 コンソールを開き、作成したバケットを選択します。
全てのオブジェクトを選択し、「削除」をクリックします。
確認のため、テキストボックスに「完全に削除」と入力し、削除を実行します。
バケットが空になった状態を確認します。
delete-bucket-object-mask

スタックの削除

CloudFormation の画面に戻り、作成したスタックを選択します。
先程と同様に「削除」をクリックします。
今度は正常に削除が完了し、イベントタブで確認すると DELETE_COMPLETE が表示されます。
delete-complete-event

S3 バケットの確認

最後に S3 バケットも削除されているか確認します。
S3 コンソールを開き、作成したバケットを検索します。
一致するものが見つからなければ正常にロールバックが完了しています。
no-bucket2

まとめ

今回は CloudFormation でスタック作成時に ROLLBACK_FAILED が発生した場合の対処をやってみました。
ROLLBACK_FAILED は復旧コマンドがなく、原因を特定し解決してからスタックを削除する必要がありました。
ロールバックが失敗するとスタックが使用不可能な状態で残り続けるのは、実際に体験すると想像以上に厄介でした。
この状況に遭遇した際は、慌てずにイベント履歴を確認し、失敗したリソースを一つずつ対処することが重要です。
本ブログが誰かの参考になれば幸いです。

参考資料

リソースのプロビジョニング時における失敗への対応方法を選択する - AWS CloudFormation
CloudFormation のトラブルシューティング - AWS CloudFormation
CloudFormation テンプレートの Conditions 構文 - AWS CloudFormation

アノテーション株式会社について

アノテーション株式会社は、クラスメソッド社のグループ企業として「オペレーション・エクセレンス」を担える企業を目指してチャレンジを続けています。「らしく働く、らしく生きる」のスローガンを掲げ、様々な背景をもつ多様なメンバーが自由度の高い働き方を通してお客様へサービスを提供し続けてきました。現在当社では一緒に会社を盛り上げていただけるメンバーを募集中です。少しでもご興味あれば、アノテーション株式会社WEBサイトをご覧ください。

この記事をシェアする

FacebookHatena blogX

関連記事