Terraformの「Resource provisioning timed out」エラーを修正する

intermediate🏗️ Terraform2026-03-21| Terraform 0.12+、AWS/GCP/Azure、Linux/macOS/Windows

Error Message

Error: A resource could not be created during the last apply. The resource provisioning timed out.
#terraform#タイムアウト#リソース#apply#プロビジョニング

TL;DR

Terraformがリソースのプロビジョニング完了を待ちきれずにタイムアウトしました。該当リソースに timeouts ブロックを追加して terraform apply を再実行してください — ほとんどの場合、これで解決します。

resource "aws_eks_cluster" "main" {
  name     = "my-cluster"
  role_arn = aws_iam_role.eks.arn

  timeouts {
    create = "30m"
    delete = "20m"
  }
}

このエラーが発生する原因

内部的には、terraform apply は各リソースが準備完了状態を報告するまでポーリングを続けます。リソースタイプごとに組み込みの制限時間があり、対象によって通常10〜40分程度です。aws_eks_cluster を作成すると30分、aws_db_instance はデフォルトで40分が割り当てられます。リージョンの遅延、大きなインスタンスサイズ、不安定なAPIなどでその時間を超えると、Terraformは処理を中断します:

Error: A resource could not be created during the last apply. The resource provisioning timed out.

このエラーが発生しやすいリソース:

  • EKS / GKE / AKS クラスター
  • RDS インスタンス(特にマルチAZ構成)
  • ElastiCache クラスター
  • ユーザーデータスクリプトを使用する大型EC2インスタンス
  • VPNゲートウェイおよびTransit Gateway
  • kubernetes プロバイダー経由のKubernetesリソース

注意点として、リソースはすでにクラウド上に存在している可能性があります。Terraformが待機中に根気が切れただけです。何も作成されていないと思い込む前に、クラウドコンソールで確認してください。

ステップ1 — 実際に作成されたものを確認する

Terraformで何かを変更する前に、クラウド上にリソースが存在するかどうかを確認してください — 単に処理が遅いだけかもしれません。

# AWS例 — RDSインスタンスが存在するか確認
aws rds describe-db-instances --db-instance-identifier my-db --query 'DBInstances[*].DBInstanceStatus'

# またはEKSクラスターのステータスを確認
aws eks describe-cluster --name my-cluster --query 'cluster.status'

ステータスが creating または available であれば、リソース自体は問題ありません — Terraformが待ちきれなかっただけです。まず状態を同期してからapplyしてください:

terraform refresh
terraform apply

ステップ2 — タイムアウトを延長する

ほとんどのTerraformリソースタイプは timeouts ブロックを受け付けます。リソース定義の内側に追加してください。使用できるキー(createupdatedelete)はリソースタイプによって異なるため、不明な場合はドキュメントを確認してください。

RDSの例

resource "aws_db_instance" "postgres" {
  identifier        = "my-db"
  engine            = "postgres"
  instance_class    = "db.r5.2xlarge"
  multi_az          = true
  allocated_storage = 100

  timeouts {
    create = "60m"
    update = "80m"
    delete = "40m"
  }
}

EKSクラスターの例

resource "aws_eks_cluster" "main" {
  name     = "production"
  role_arn = aws_iam_role.eks.arn

  vpc_config {
    subnet_ids = var.subnet_ids
  }

  timeouts {
    create = "30m"
    delete = "15m"
  }
}

Google Cloud SQLの例

resource "google_sql_database_instance" "main" {
  name             = "my-instance"
  database_version = "POSTGRES_14"
  region           = "us-central1"

  timeouts {
    create = "30m"
    update = "30m"
    delete = "30m"
  }

  settings {
    tier = "db-custom-4-16384"
  }
}

ファイルを保存してapplyします:

terraform apply

ステップ3 — スタックした状態を処理する

プロビジョニングが完了しなかったリソースに対して、Terraformが不完全な状態エントリを残す場合があります。再試行する前にそれをクリーンアップしてください。

現在の状態を確認する

terraform state list
terraform state show aws_db_instance.postgres

孤立した状態を削除する(クラウド上にリソースが存在しない場合)

# 壊れたリソースを状態から削除して、Terraformが再作成を試みるようにする
terraform state rm aws_db_instance.postgres

既存リソースをインポートする(作成済みだがTerraformが追跡を失った場合)

# 既存のRDSインスタンスを状態にインポート
terraform import aws_db_instance.postgres my-db

# 確認する
terraform plan

ステップ4 — プロビジョニングが遅い原因を調査する

タイムアウトの上限を引き上げるのは症状への対処であり、根本的な原因の解決ではありません。以前は15分で起動していたEKSクラスターが45分かかるようになった場合、何かが変わっています — 何が変わったのか調べる価値があります。

EC2ユーザーデータスクリプト

10分以上実行されるスタートアップスクリプトがあると、インスタンスはその間ずっと pending 状態のままになります。コンソール出力を取得して、どこで詰まっているか確認してください:

aws ec2 get-console-output --instance-id i-0abc123 --output text

重い初期化処理はユーザーデータから切り離してください — AnsibleやChefのような構成管理ツールを使用するか、必要なソフトウェアをあらかじめインストールしたカスタムAMIを作成してください。

大容量EBSボリューム

2TBの gp2 ボリュームはゼロから初期化するのに20分以上かかることがあります。代わりに gp3 に切り替えてください — サイズに関係なくベースラインで3,000 IOPSを提供し、初期化が大幅に速く完了します。重要なワークロードには、ソーススナップショットでファストスナップショットリストアを有効にしてください。

resource "aws_ebs_volume" "data" {
  availability_zone = "us-east-1a"
  size              = 2000
  type              = "gp3"  # 大容量ボリュームではgp2より高速
  throughput        = 500
}

Kubernetesリソース

kubernetes および helm プロバイダーはデプロイメントが準備完了状態になるまで待機します。Podがクラッシュし続けている場合、タイムアウトをいくら延ばしても意味がありません — Terraformは失敗するまでより長く待つだけです。Podを直接確認してください:

kubectl get pods -n my-namespace
kubectl describe pod my-app-xxx -n my-namespace
kubectl logs my-app-xxx -n my-namespace

まず根本的なPodの問題を修正してください。コンテナ自体が正常になるまで、Terraformのタイムアウトは無関係です。

ステップ5 — 修正を確認する

terraform apply が完了したら、両面から簡単なサニティチェックを行ってください:

# Terraformが作成済みとして認識しているか確認
terraform state show aws_db_instance.postgres

# 保留中の変更が残っていないか確認
terraform plan
# 期待される出力:
# No changes. Your infrastructure matches the configuration.

次にAWS側からも確認します:

aws rds describe-db-instances \
  --db-instance-identifier my-db \
  --query 'DBInstances[*].{ID:DBInstanceIdentifier,Status:DBInstanceStatus}'

クイックリファレンス — リソース別デフォルトタイムアウト

  • aws_db_instance — create: 40m、update: 80m、delete: 60m
  • aws_eks_cluster — create: 30m、delete: 15m
  • aws_elasticache_cluster — create: 40m、delete: 40m
  • aws_instance — create: 10m、update: 10m、delete: 20m
  • google_container_cluster — create: 40m、update: 60m、delete: 40m
  • azurerm_kubernetes_cluster — create: 90m、update: 90m、delete: 90m

すべてのリソースが3つのキーすべてを公開しているわけではありません — 対象リソースで updatedelete が利用可能かどうかは、Terraform Registryのドキュメントで事前に確認してください。

参考リンク

  • Terraformドキュメント: Operation Timeouts
  • Terraform RegistryのAWS RDSリソースドキュメント
  • TF_LOG=DEBUG terraform apply を実行すると、プロビジョニング中にどこで時間がかかっているかを詳細にトレースできます

Related Error Notes