Terraformの「Instance cannot be destroyed」エラーを解決する方法

intermediate🏗️ Terraform2026-06-25| Terraform CLI(全バージョン)、AWS/Azure/GCPプロバイダー、Linux/macOS/Windows

Error Message

Error: Instance cannot be destroyed Resource aws_s3_bucket.example has lifecycle.prevent_destroy set, but the plan calls for this resource to be destroyed. To avoid this error and continue, you must remove the lifecycle.prevent_destroy configuration from this resource.
#terraform#devops#aws#infrastructure-as-code#トラブルシューティング

問題の発生デプロイの途中で、ターミナルが突然動かなくなることがあります。通常の進捗バーの代わりに、「Instance cannot be destroyed」という赤いエラーメッセージが表示されます。これはTerraformのバグではありません。指示通りに動作している安全機能です。通常、開発者が本番環境のRDSデータベースやコアVPCのような重要なリソースに対して、誤ったコマンドで誤って削除してしまわないよう、ガードレール(保護策)を追加した際に発生します。

エラーメッセージ```

Error: Instance cannot be destroyed

Resource aws_s3_bucket.example has lifecycle.prevent_destroy set, but the plan calls for this resource to be destroyed. To avoid this error and continue, you must remove the lifecycle.prevent_destroy configuration from this resource.


## なぜこのエラーが発生したのか?`prevent_destroy`メタ引数は、究極の安全装置です。これが`true`に設定されていると、Terraformはそのリソースの削除を伴ういかなるプランも拒否します。この保護機能は通常、以下の2つの特定のシナリオでトリガーされます。
- **意図的な削除:** `terraform destroy`を実行したか、`.tf`ファイルからリソースブロックを削除した場合。- **偶発的な置換:** 「Force New(新規作成を強制)」アクションを必要とする設定を変更した場合。例えば、`aws_s3_bucket`の`name`や`aws_instance`の`availability_zone`を変更すると、Terraformは古いリソースを削除して新しいリソースを作成しようとします。## クイックフィックス:一時的に保護を無効化する実際にリソースを置換または削除する必要がある場合は、コードを修正する必要があります。Terraformには、この安全チェックをバイパスするためのコマンドラインフラグ(`--force`など)は用意されていません。手動で保護をオフに切り替える必要があります。
- リソースが含まれている設定ファイルを開きます。- `lifecycle`ブロックを探します。- `prevent_destroy = false`に設定するか、ブロック全体をコメントアウトします。```
resource "aws_s3_bucket" "example" {
  bucket = "my-production-data-12345"

  # lifecycle {
  #   prevent_destroy = true
  # }
}

ファイルを保存したら、再度terraform planを実行してください。エラーは消え、Terraformは要求通りに削除または置換を続行します。

恒久的な対策:リソースの置換への対処何も削除したくなかった場合はどうすればよいでしょうか?多くの場合、このエラーはわずかな設定変更によって、通常のterraform apply中に発生します。予期せず置換が強制されている場合は、その原因を調査する必要があります。

ステップ1:プランを分析するterraform planを実行し、# aws_s3_bucket.example must be replacedというフレーズを探します。Terraformは、競合の原因となっている特定の属性に# forces replacementというマークを付けます。単純なタグや説明の変更で置換が強制されている場合、それはプロバイダー固有の挙動である可能性があります。

ステップ2:元に戻すか移行する置換が間違いであった場合は、.tfファイルを以前の状態に戻してください。変更が必須であるものの、リソースを失うわけにはいかない場合は、movedブロック(Terraform 1.1以降で使用可能)の利用を検討してください。これにより、実際のインフラを再作成することなく、ステートファイル内のリソース名を変更できます。

ステップ3:ステートから削除する(上級者向け)リソースを実環境(AWSコンソールなど)には残しつつ、Terraformによる管理を停止したい場合があります。その場合は、state rmコマンドを使用します。

terraform state rm aws_s3_bucket.example

このコマンドは、terraform.tfstateファイルからリソースを削除します。これにより、Terraformが実際のS3バケットを操作することなく、安全にコードブロックを削除できるようになります。

本番環境におけるベストプラクティスデータベースやストレージのようなステートフルなリソースにprevent_destroyを使用するのは賢明な判断です。しかし、すべてのリソースに適用すると、CI/CDパイプラインが脆弱になり、管理が煩わしくなる可能性があります。これはインフラの「最重要資産」のために取っておきましょう。

設定エラーは、外部ファイルの不正なデータから発生することがよくあります。Terraformの変数が複雑なJSONやYAMLソースから提供されている場合、インデントのミス一つで意図しないリソースの置換がトリガーされることがあります。私は、設定構造を検証するためにToolCraftのYAML ↔ JSON Converterを使用しています。これにより、Terraform CLIに到達する前に構文エラーをキャッチできます。

検証手順修正が確実であることを確認するには、以下のワークフローに従ってください。

  • terraform plan -out=tfplanを実行します。- 「Instance cannot be destroyed」エラーが出ずにプランが完了することを確認します。- 出力を注意深く確認し、意図した5つまたは10程度のリソースのみが変更対象になっていることを確認します。- terraform apply tfplanを実行して変更をコミットします。更新が完了したら、prevent_destroy = trueを忘れずにtrueに戻してください。タイポ(打ち間違い)で本番環境のデータベースを失うよりも、保護機能があって手間がかかる方がはるかにマシです。

Related Error Notes