【実務・中級編】CloudFormationスタックのロールバック失敗(Rollback Completeの罠)からの手動復旧とスタック削除の完全手順 – インフラ構成管理(IaC)活用バイブル

【AWS】CloudFormation「ロールバック失敗(Rollback Failed)」の深淵から生還する:実務のための完全復旧・強制削除マニュアル

テックリードの私だ。日々のインフラ自動化、ご苦労様。
君たちは、CloudFormationのスタック更新で赤字のエラーログが出た後、「Rollback Failed(ロールバック失敗)」という絶望のステータスを目の当たりにし、コンソール上で身動きが取れなくなった経験はないだろうか?

「スタックの削除もできない」
「更新も受け付けない」
「`aws cloudformation delete-stack` を叩いても、無限に `DELETE_FAILED` を繰り返す」

この状態に陥ったとき、一般的なドキュメントやネット上の浅い記事は役に立たない。手動でマネジメントコンソールをポチポチしても、エラーのループが加速するだけだ。

今回は、このCloudFormationの最大の罠である「ロールバック失敗」から完全に生還し、IaCの秩序を取り戻すための極限のトラブルシューティングと実務的知見を授けよう。

—

1. なぜ「Rollback Failed」の罠に落ちるのか?(構造的理解)

CloudFormationは、宣言された望ましい状態(Desired State)と現実のリソースの差分を埋めるためにトランザクションを張る。しかし、ロールバック中(エラー発生前の状態に戻す処理)に以下の事象が発生すると、CloudFormationは整合性を担保できなくなり、スタックを「Failed」状態で凍結する。

  • 手動でのリソース変更・削除: CloudFormation管理下のリソースを誰かがこっそりマネジメントコンソールや別ルート(Terraformなど)で削除・変更していた。
  • 依存関係のデッドロック: IAMロールの削除前に、それに依存するリソースの解放が間に合わない、あるいはVPCのENI(Elastic Network Interface)が他サービス(RDSやLambda)に占有されていて削除できない。
  • Service Limit(クォータ)の壁: ロールバック時にリソースを再作成しようとして、リージョンの上限値に引っかかった。

この状態のスタックは、AWS側から見ると「どのリソースが実際に存在し、どれが消滅したかトラッキング不能なゾンビ状態」だ。これを正常化するには、CloudFormationの「強制力」をこちら側から引き出す必要がある。

—

2. 現場で使える!AWS CLIを活用した強制復旧の全手順

コンソールはもう閉じるんだ。ここからはAWS CLIと、AWSの内部状態をハックする実務コマンドの領域だ。

ステップ 1: ゾンビ状態のリソースを特定する

まずは、どのリソースがどのステータスでスタックの足を引っ張っているかを正確に把握する。

aws cloudformation describe-stack-resources \
–stack-name <あなたの壊れたスタック名> \
–query “StackResources[?ResourceStatus==’DELETE_FAILED’ || ResourceStatus==’CREATE_FAILED’]” \
–output table

ここで `DELETE_FAILED` や `UPDATE_FAILED` になっているリソースの物理ID(`PhysicalResourceId`)と論理ID(`LogicalResourceId`)をメモせよ。

ステップ 2: 原因となっている実リソースの「自力解決」

CloudFormationが消せないのなら、人間が手動で(あるいは個別のAPIで)そのリソースを始末するしかない。
例えば、ENIが残ってVPCが消せないなら、EC2コンソールやCLIでそのENIを強制切断・削除する。IAMポリシーの競合なら、該当のロールを強制削除する。

> ⚠️ プロの鉄則:
> 実リソースを手動で削除した場合、CloudFormationは「まだそこにあるはずだ」と思い込んでいる。この乖離を解消するのが次のステップだ。

ステップ 3: `–retain-resources` を使った「切り離し」削除

スタック全体を削除したいが、一部のリソースが邪魔をしている場合、`delete-stack` コマンドに `–retain-resources` オプションを渡し、問題児のリソースをCloudFormationの管理外(捨て駒)に指定して、スタックを強制削除する。

aws cloudformation delete-stack \
–stack-name <あなたの壊れたスタック名> \
–retain-resources LogicalResourceId01 LogicalResourceId02

このコマンドを実行すると、指定したリソースはAWS上に残ったまま(あるいは手動で既に消されていればそのまま)、CloudFormationのスタックメタデータだけが綺麗に消し去られる。
残された不要リソースは、後から個別にクリーンアップすればよい。

—

3. 生産性を極限まで高める:開発環境とツールチェーンのベストプラクティス

このような地獄を二度と踏まないため、また日々のIaC開発スピードを倍化させるための「プロの装備」を紹介しよう。

A. 開発スピードを劇的に高める VSCode キーボードショートカット

CloudFormation(YAML)を書く際、インデントのズレやプロパティ名のタイポは死活問題だ。以下のショートカットを体に叩き込め。

  • `Shift + Alt + F`(Mac: `Shift + Option + F`):ドキュメントのフォーマット(Prettier / YAML拡張機能による構文整形)
  • `Ctrl + Space`(Mac: `Ctrl + Space`):プロパティのIntelliSense(補完)を強制呼び出し
  • `F1` -> `AWS: Validate Template`:テンプレートの静的解析(後述のプラグイン必須)

B. 絶対入れるべき神プラグイン(VSCode)

1. AWS Toolkit for Visual Studio Code

  • 理由: IDE上でCloudFormationスタックのステータスをリアルタイム監視でき、テンプレートのバリデーションやS3へのアップロード、デプロイまでが完結する。

2. YAML (Red Hat)

  • 理由: JSON Schemaと連携し、CloudFormationのLinter(cfn-lint)と連動して記述ミスをビルド前に100%検知する。

3. CloudFormation Snippets

  • 理由: 冗長なボイラープレート(Resources, Outputs等の構造)を一瞬で展開する。

C. チーム開発における設定共有化ルール

チームメンバー全員のローカル環境で同じ品質を保つため、プロジェクトルートに `.vscode/settings.json` と `cfnlintrc` を必ず配置せよ。

`.vscode/settings.json` のベストプラクティス構成例:

{
“editor.formatOnSave”: true,
“editor.tabSize”: 2,
“yaml.schemas”: {
“https://raw.githubusercontent.com/awslabs/goformation/master/schema/cloudformation.schema.json”: “.yaml”
},
“yaml.validate”: true,
“files.associations”: {
“template.yaml”: “yaml”,
“.cfn.yml”: “yaml”
}
}

—

4. 失敗を許容する:耐障害性の高いCloudFormation設定パターン

最後に、ロールバック失敗すら起きにくい「堅牢なIaC設計」のコード断片を共有する。

実用的な設定ファイル:ベストプラクティス構成例(YAML)

リソースの削除ポリシー(`DeletionPolicy`)と更新ポリシー(`UpdateReplacePolicy`)を適切に制御し、万が一のスタック削除時にもデータや基幹ネットワークが消えない、あるいはデッドロックしない設計にするのがプロだ。

AWSTemplateFormatVersion: ‘2010-09-09’
Description: ‘Resilient Production Infrastructure Pattern’

Parameters:
EnvironmentType:
Type: String
Default: ‘prod’
AllowedValues: [‘dev’, ‘stg’, ‘prod’]
Description: ‘Target environment for deployment’

Resources:
# 1. デッドロックを防ぐための依存関係の明示 (DependsOn)
ApplicationLogGroup:
Type: AWS::Logs::LogGroup
Properties:
LogGroupName: !Sub ‘/aws/application/${EnvironmentType}’
RetentionInDays: 30
# 削除時の挙動を制御(本番環境ではRetainを推奨)
DeletionPolicy: Retain
UpdateReplacePolicy: Retain

# 2. セキュアかつ依存関係を考慮したVPC
CoreVPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: ‘10.100.0.0/16’
EnableDnsHostnames: true
EnableDnsSupport: true
Tags:

  • Key: Name

Value: !Sub ‘${EnvironmentType}-core-vpc’

# 3. ネットワークとログの順序制御例
CoreSubnet:
Type: AWS::EC2::Subnet
DependsOn: CoreVPC
Properties:
VpcId: !Ref CoreVPC
CidrBlock: ‘10.100.1.0/24’
MapPublicIpOnLaunch: false
Tags:

  • Key: Name

Value: !Sub ‘${EnvironmentType}-core-subnet’

Outputs:
VpcId:
Description: ‘The ID of the primary VPC’
Value: !Ref CoreVPC
Export:
Name: !Sub ‘${AWS::StackName}-VpcId’

—

テックリードからの最後のメッセージ

「Rollback Failed」に出くわした時、素人はパニックになってAWSサポートへチケットを切る。しかし、真のSRE・インフラエンジニアは、CloudFormationが裏側で何をやっているのか(CloudWatch Logsのイベントログ、リソースの依存関係グラフ)を冷静に逆算し、CLIとAPIでスマートにシステムを外科手術する。

障害は構造を深く理解する最高のチャンスだ。恐れず、しかし慎重に、インフラの主導権を常に自分たちの手に握り続けろ。

タイトルとURLをコピーしました