★★ 中級

11. デバッグとトラブルシュート

plan が通らない、apply で謎エラー、state が壊れた…そんな時の確認順序と便利コマンド集。

terraform console

対話型 REPL。式の評価、変数の確認、関数の挙動チェックに最強。

$ terraform console
> var.environment
"dev"
> local.common_tags
{
  "Env" = "dev"
  "ManagedBy" = "Terraform"
}
> aws_vpc.main.cidr_block
"10.0.0.0/16"
> cidrsubnet("10.0.0.0/16", 8, 5)
"10.0.5.0/24"
> [for s in aws_subnet.public : s.id]
[
  "subnet-abc",
  "subnet-def",
]
> exit

「この式が何を返すか」を apply 前に 確認できる。コードに書いて plan する前に必ず console で試すと事故が減ります。

TF_LOG でログを出す

# 環境変数 TF_LOG を設定すると詳細ログが出る
export TF_LOG=DEBUG
terraform plan

# Windows PowerShell
$env:TF_LOG = "DEBUG"
terraform plan

# レベル: TRACE / DEBUG / INFO / WARN / ERROR
# ログをファイルに
export TF_LOG_PATH=./terraform.log
terraform plan

API 呼び出しの中身、provider の挙動、認証フローまで全部出ます。使い終わったら unset TF_LOG しないと、以降全実行が遅くなる。

terraform refresh / -refresh-only

「コードは変えていないのに plan で差分が出る」 → AWS 側で誰かが手で変えた可能性。

# 現状を state に取り込みたいだけ(apply はしない)
terraform plan -refresh-only
terraform apply -refresh-only   # 差分を state に取り込む

# 単一リソースだけ refresh
terraform apply -refresh-only -target=aws_s3_bucket.logs

terraform graph で依存関係

terraform graph | dot -Tpng > graph.png   # Graphviz が必要
# または terraform graph > graph.dot で .dot を保存し、各種ビューワで開く

「なぜこの順で作られるのか」「循環依存がないか」を可視化。チームレビューでも便利。

よく出るエラーと対処

1. Error: Cycle(循環依存)

resource A が B を参照、B が A を参照している。depends_on を外すか、構造を分割。

2. Error: Inconsistent dependency lock file

lock ファイルと required_providers の version 制約が矛盾。terraform init -upgrade

3. Error: Provider produced inconsistent result

provider 側のバグか、API レスポンスが想定外。provider のバージョンを 1 つ上げる/下げる。

4. Error: Resource already exists

AWS 側に同名のリソースが既存。terraform import で取り込むか、名前を変える。

5. Error: AccessDenied

IAM 権限不足。エラーメッセージに必要な action(s3:PutBucketPolicy 等)が出るので、ロールに追加。

6. Error: Saved plan is stale

terraform plan -out=tfplan 後、別の操作(変更)が入ってから apply tfplan した。再度 plan し直す。

7. Error: Failed to load state: state lock

誰かが apply 中、または前回の apply が異常終了。状況確認後、terraform force-unlock LOCK_ID(最終手段)。

state の不整合

症状確認・対処
state にあるのに AWS には無いterraform state rm LIST で state から外す
AWS にあるのに state に無いimport { to=..., id=... } で取り込む
plan で「destroy / create」が大量に出るmoved ブロックで address 変更、または ignore_changes の漏れを確認
state ファイルが破損S3 versioning から前のバージョンを取り戻す
困った時の合言葉 terraform state list」「terraform state show ADDR」「terraform plan -refresh-only。この 3 つで 8 割は原因が見えます。