1. 概要
Terraformで遭遇しやすいエラーメッセージの原因と解決方法をまとめました。エラーメッセージをそのまま検索してこのページに来た方は、該当セクションを参照してください。
2. 変数・式のエラー
Error: Inconsistent conditional result types
│ Error: Inconsistent conditional result types
│
│ on main.tf line 5, in resource "aws_instance" "web":
│ 5: instance_type = var.environment == "prd" ? "t3.medium" : 0
│
│ The true and false result expressions must have consistent types. The
│ given expressions are string and number, respectively.
原因: 三項演算子の「trueの値」と「falseの値」の型が違う(片方がstring、もう片方がnumberなど)。
解決方法: 両方の値の型を揃える。
# ❌ string と number で型不一致
instance_type = var.environment == "prd" ? "t3.medium" : 0
# ✅ 両方 string に揃える
instance_type = var.environment == "prd" ? "t3.medium" : "t3.micro"
# ✅ nullを返したい場合はtostring()等で型を明示
volume_size = var.enable_extra_disk ? 100 : null
# ↑ nullとnumberは型一致しないため、tostring(null)などで対処するか
# 条件式の代わりにlookup/tryを使う
Error: Variables not allowed
│ Error: Variables not allowed
│
│ on main.tf line 8, in terraform:
│ 8: bucket = var.state_bucket
│
│ Variables may not be used here.
原因: backendブロック内でvar.やlocal.を使おうとした。backendブロックは初期化時に評価されるため、変数を参照できない。
解決方法: -backend-configオプションで外部から渡す。
# -backend-config オプションで値を渡す
terraform init \
-backend-config="bucket=myproject-terraform-state" \
-backend-config="key=prod/terraform.tfstate"
詳細は「backendの設定方法」を参照。
Error: Invalid value for input variable
│ Error: Invalid value for input variable
│
│ on terraform.tfvars line 1:
│ 1: environment = "staging"
│
│ The argument "environment" value "staging" is invalid: environment は
│ dev/stg/prd のいずれかを指定してください。
原因: variableブロックにvalidationが設定されており、渡した値がルールを満たさない。
解決方法: 許可された値を確認して正しい値を渡す。
# variableのvalidationを確認
variable "environment" {
type = string
validation {
condition = contains(["dev", "stg", "prd"], var.environment)
error_message = "environmentはdev/stg/prdのいずれかを指定してください。"
}
}
# → "staging" ではなく "stg" を渡す必要がある
3. count / for_each のエラー
Error: Invalid count argument
│ Error: Invalid count argument
│
│ on main.tf line 3, in resource "aws_instance" "web":
│ 3: count = aws_security_group.main.id
│
│ The "count" value depends on resource attributes that cannot be
│ determined until apply, so Terraform cannot predict how many instances
│ will be created.
原因: countに、apply後にしか決まらないリソース属性(IDなど)を使っている。
解決方法: countにはapply前に値が確定する式(変数・数値など)だけを使う。
# ❌ リソースのIDは apply 後にしか決まらない
count = length(aws_security_group.main.id)
# ✅ 変数や固定値を使う
count = var.enable_web ? 1 : 0
count = length(var.server_names)
Error: The for_each value depends on resource attributes that cannot be determined until apply
│ Error: Invalid for_each argument
│
│ on main.tf line 3, in resource "aws_instance" "web":
│ 3: for_each = aws_subnet.main
│
│ The "for_each" value depends on resource attributes that cannot be
│ determined until apply, so Terraform cannot predict how many instances
│ will be created.
原因: for_eachに、apply後にしか決まらないリソース属性を直接渡している。
解決方法: for式でキーが確定している値だけを使ったmapに変換する。
# ❌ apply後にしか決まるsensitive属性を含む場合にエラー
for_each = aws_subnet.main
# ✅ キーが確定している変数から生成する
for_each = var.subnet_configs # 変数から生成
for_each = local.subnets_map # 変数やdata sourceからlocalsで事前に変換しておく
Error: for_each requires a map or set of strings
│ Error: Invalid for_each argument
│
│ on main.tf line 3, in resource "aws_s3_bucket" "logs":
│ 3: for_each = var.bucket_names
│
│ The given "for_each" argument value is unsuitable: the "for_each" argument
│ must be a map, or set of strings, and you have provided a value of type
│ tuple.
原因: for_eachにlistを直接渡した。for_eachはmapかset(string)のみ受け付ける。
解決方法: toset()でset型に変換するか、for式でmapに変換する。
# ❌ list は直接渡せない
for_each = var.bucket_names # list(string) → エラー
for_each = ["access", "error"] # tuple → エラー
# ✅ toset()でset(string)に変換
for_each = toset(var.bucket_names)
for_each = toset(["access", "error"])
# ✅ for式でmapに変換
for_each = { for name in var.bucket_names : name => name }
詳細は「for_eachの使い方」「toset/tolist/tomapの使い方」を参照。
4. 依存関係・構造のエラー
Error: Cycle detected
│ Error: Cycle: aws_instance.web, aws_security_group.main
│
│ Terraform detected a cycle in the dependency graph between these
│ resources. Please resolve the cycle to continue.
原因: リソースAがリソースBを参照し、リソースBもリソースAを参照している(循環依存)。
解決方法: 循環している参照をどちらか一方から取り除く。参照式ではなくdepends_onを使っている場合は不要なdepends_onを削除する。
# ❌ 循環依存の例
resource "aws_security_group" "app" {
egress {
security_groups = [aws_security_group.db.id] # dbを参照
}
}
resource "aws_security_group" "db" {
ingress {
security_groups = [aws_security_group.app.id] # appを参照(循環!)
}
}
# ✅ 解決: セキュリティグループルールを分離する(aws_security_group_rule を使う)
resource "aws_security_group_rule" "db_from_app" {
type = "ingress"
security_group_id = aws_security_group.db.id
source_security_group_id = aws_security_group.app.id
protocol = "tcp"
from_port = 5432
to_port = 5432
}
Error: Missing required argument
│ Error: Missing required argument
│
│ on main.tf line 10, in resource "aws_instance" "web":
│ 10: resource "aws_instance" "web" {
│
│ The argument "ami" is required, but no definition was found.
原因: リソースに必須の引数が指定されていない。
解決方法: プロバイダーの公式ドキュメントで必須引数を確認する。
# ✅ aws_instance の必須引数を確認して追加
resource "aws_instance" "web" {
ami = data.aws_ami.amazon_linux_2023.id # ← 必須
instance_type = "t3.micro" # ← 必須
tags = {
Name = "web"
ManagedBy = "terraform"
}
}
Error: Unsupported argument
│ Error: Unsupported argument
│
│ on main.tf line 5, in resource "aws_instance" "web":
│ 5: instance_count = 3
│
│ An argument named "instance_count" is not expected here.
原因: 存在しない引数名を書いている(タイポ、または古いバージョンの引数名)。
解決方法: 公式ドキュメントで正しい引数名を確認する。countはリソースのプロパティではなくメタ引数。
# ❌ 存在しない引数
instance_count = 3
# ✅ countはメタ引数(同じインデントレベルに書く)
resource "aws_instance" "web" {
count = 3 # メタ引数
ami = data.aws_ami.amazon_linux_2023.id
instance_type = "t3.micro"
}
5. state・backendのエラー
Error: Error acquiring the state lock
│ Error: Error acquiring the state lock
│
│ Lock Info:
│ ID: a1b2c3d4-e5f6-...
│ Path: myproject-state/prod/terraform.tfstate
│ Operation: OperationTypeApply
│ Who: alice@example.com
│ Created: 2026-01-15 10:30:00 +0000 UTC
原因1(正常): 別の人またはCIがterraform applyを実行中。
対処: 実行完了まで待つ。完了すればロックは自動解除される。
原因2(異常): 前回の実行が異常終了してロックが残留している。
対処: チームに確認してからforce-unlockで解除する。
# Lock Info の ID を使って強制解除(チームへの確認必須)
terraform force-unlock a1b2c3d4-e5f6-...
⚠️ 警告:
force-unlockは他のユーザーのapplyを強制終了させる危険があります。必ずチームに確認してから実行してください。
Error: Backend configuration changed
│ Error: Backend configuration changed
│
│ A change in the backend configuration has been detected, which may
│ require migrating existing state.
原因: backendブロックの設定を変更したのにterraform initを再実行していない。
解決方法:
# Stateは移行せず再設定(バックエンドのURLが変わったが移行不要な場合)
terraform init -reconfigure
# 既存StateをS3等の新しいバックエンドに移行する場合
terraform init -migrate-state
Error: state data in S3 does not have the expected content
│ Error: Error loading state: state data in S3 does not have the expected
│ content. This may be caused by a previous force-unlock.
原因: State Lockの強制解除後にStateファイルが破損している、または複数のapplyが同時に走ってStateが上書きされた。
対処: S3のバージョニングが有効な場合、S3コンソールから以前のバージョンに戻す。バックアップがない場合はterraform importで手動復元が必要。
6. initのエラー
Error: Failed to install provider
│ Error: Failed to install provider
│
│ Error while installing hashicorp/aws v5.50.0: could not query provider
│ registry for registry.terraform.io/hashicorp/aws
原因: ネットワーク接続の問題(プロキシ環境、オフライン環境など)、または.terraform.lock.hclとrequired_providersのバージョン制約が競合している。
解決方法:
# .terraform/ と .terraform.lock.hcl を削除してやり直す
rm -rf .terraform
rm .terraform.lock.hcl
terraform init
# プロキシ経由の場合は環境変数を設定
export HTTPS_PROXY=http://proxy.example.com:8080
terraform init
Error: Provider version requirements conflict
│ Error: Failed to query available provider packages
│
│ Could not retrieve the list of available versions for provider
│ hashicorp/aws: locked provider registry.terraform.io/hashicorp/aws
│ 5.0.0 does not match configured version constraint ~> 5.50.
原因: .terraform.lock.hclに記録されたバージョンと、required_providersの制約が合わない。
解決方法:
# ロックファイルを更新してプロバイダーをアップグレード
terraform init -upgrade
7. planの意図しない挙動
-/+(置換)が意図せず発生する
# aws_instance.web must be replaced
-/+ resource "aws_instance" "web" {
~ id = "i-0abc123" -> (known after apply)
+ ami = "ami-newvalue" # forces replacement
原因: AMI IDを変更した、instance_typeを変更した、など「変更すると再作成が必要」な属性を変更した。
確認: 変更前に必ずterraform planでforces replacementの記載を確認する。
対処(ダウンタイムを避けたい場合):
lifecycle {
create_before_destroy = true # 先に新規インスタンスを作ってから古いものを削除
}
No changesなのにapplyで変更が発生する
原因: Terraform Provider側のバグ(apply後にState値がAPIレスポンスで上書きされる)、またはignore_changesがplan時にのみ有効でapply後に差分が生じるケース。
対処:
lifecycle {
ignore_changes = [tags] # 外部から変更されるタグを無視
}
8. 関連記事
- terraform init / plan / apply / destroyの使い方 — コマンドのオプションと安全な実行方法
- count — 整数でリソースを複数作成するメタ引数 — Invalid count argumentの詳細
- for_each — map/setで動的にリソースを作成するメタ引数 — for_eachエラーの詳細
- 条件式(三項演算子)の使い方 — Inconsistent conditional result typesの詳細
- backendの設定方法 — backendエラーの詳細
- state管理とは — state lockエラーの詳細
- lifecycleブロックの使い方 — -/+置換の制御
エラー個別詳解(Phase 3)
- 「Inconsistent result types」エラー — 条件式・for式の型不一致
- 「count/for_each depends on resource attributes」エラー — plan確定できないcount/for_each
- 「for_each map includes keys derived from resource attributes」エラー — for_eachキー未知エラー
- 「Cycle」循環参照エラー — セキュリティグループ相互参照など
- 「Backend configuration changed」エラー — stateバックエンド変更時の移行手順
- 意図しない置換(-/+)の原因と対処法 — forces replacementの特定と防止
- terraform planが遅い原因と高速化 — parallelism・refresh=false・state分割
- プロバイダーバージョンエラー — lock.hcl不一致・terraform init -upgrade
- 「Output refers to sensitive values」エラー — sensitive値のoutput設定
- ignore_changesの正しい使い方と落とし穴 — ignore_changes=allの危険性
9. まとめ
このページでカバーしているエラーの早見表:
| エラー | 主な原因 |
|---|---|
| Inconsistent conditional result types | 三項演算子の型不一致 |
| Variables not allowed | backendブロック内でvar.を使用 |
| Invalid value for input variable | validationルール違反 |
| Invalid count argument | applyまで不明な値をcountに使用 |
| for_each set以外 | listをfor_eachに直接渡した |
| Cycle detected | 循環依存 |
| Missing required argument | 必須引数の未設定 |
| Error acquiring the state lock | State Lockの競合または残留 |
| Backend configuration changed | backend変更後のinit未実施 |
| Failed to install provider | ネットワーク・バージョン制約の問題 |
動作確認バージョン: Terraform >= 1.9 / AWS Provider ~> 5.0 公式ドキュメント: https://developer.hashicorp.com/terraform/language/expressions