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 割は原因が見えます。