エラーの内容
│ Error: Invalid value for input variable
│
│ on terraform.tfvars line 3:
│ 3: instance_count = "2"
│
│ The given value is not suitable for var.instance_count: a number is required.
このエラーは terraform plan または terraform apply の実行中に発生します。Terraform が .tfvars ファイルを読み込み、変数を見つけたものの、型が変数の宣言と一致しないため値を拒否しました。プランは開始されません。
根本原因
Terraform の型システムは暗黙的な型変換を行いません。変数を type = number と宣言しておきながら、"2" のようにクォートで囲んだ文字列を渡した場合は拒否されます。自動変換は行われず、Terraform は厳密に指定された型を要求します。これは bool、list、map、object 型にも同様に適用されます。
型の不一致は、主に以下のような状況で発生します:
.tfvarsファイル内で数値や bool 値がクォートで囲まれているlist型の変数がカンマ区切りの文字列として渡されているobject型の変数で必須属性が1つ以上欠けているvariables.tfで変数の型が変更されたが、.tfvarsファイルが更新されていない
修正1:数値・bool 値からクォートを削除する
ほとんどの場合、これが原因です。HCL には明確なルールがあります:文字列にはクォートが必要ですが、それ以外の型には不要です。
誤り:
# terraform.tfvars
instance_count = "2" # 文字列であり、数値ではない
enable_logging = "true" # 文字列であり、bool ではない
正しい書き方:
# terraform.tfvars
instance_count = 2 # 数値 — クォート不要
enable_logging = true # bool — クォート不要
数値、bool、list、map はすべてクォートなしで記述します。クォートが必要なのは文字列値だけです。
修正2:list・set 型変数を修正する
list(string) 型の変数にカンマ区切りの文字列を渡すのもよくある間違いです。Terraform が自動的に分割してくれることはありません。
変数の宣言:
# variables.tf
variable "availability_zones" {
type = list(string)
}
誤り:
# terraform.tfvars
availability_zones = "us-east-1a,us-east-1b"
正しい書き方:
# terraform.tfvars
availability_zones = ["us-east-1a", "us-east-1b"]
修正3:map・object 型変数を修正する
HCL の map は { key = value } の構文を使用します。JSON スタイルのコロンは使えません。JSON 設定からコピー&ペーストすると、コロンが原因でエラーになります。
変数の宣言:
# variables.tf
variable "tags" {
type = map(string)
}
variable "db_config" {
type = object({
engine = string
version = string
port = number
})
}
tfvars の正しい構文:
# terraform.tfvars
tags = {
Environment = "production"
Team = "platform"
}
db_config = {
engine = "postgres"
version = "14.5"
port = 5432
}
port に注意してください。number 型として宣言されているため、5432 にクォートは不要です。"5432" と書くと、まさに今修正しようとしているエラーが再発します。
修正4:CLI フラグで変数を渡す場合
コマンドラインで -var を使用している場合、型の扱いが異なります。Terraform は値を文字列として受け取り、宣言された型に基づいて変換しますが、これは単純なスカラー値には機能するものの、list、map、object では問題が生じます。
基本的な数値や bool 以外の型を渡す場合は、.tfvars ファイルを使用してください:
# 複雑な型には不安定:
terraform plan -var='instance_count=2'
# より確実な方法:
terraform plan -var-file="production.tfvars"
単純な number や bool 変数であれば -var でも概ね問題ありません。list、map、object になると厄介になります。
修正5:モジュール間の型のずれを確認する
最近モジュールを更新して変数の型を変更しましたか?ルートモジュールの .tfvars が古い形式のままになっている可能性があります。これは気づきにくいケースで、エラーメッセージは型が実際に変更されたモジュールではなく tfvars ファイルを指しています。
# Terraform が実際に期待する型を確認する:
terraform console
> var.instance_count
またはソースを直接確認します:
grep -A5 'variable "instance_count"' variables.tf
簡単な診断:apply なしで検証する
plan を実行する前に terraform validate を実行してください:
terraform validate
このコマンドは tfvars を読み込まないため、値レベルの不一致は検出できません。しかし、宣言エラーは素早く捉えられます。tfvars を含めた完全な検証を行うには、plan を実行して出力をパイプで確認してください:
terraform plan -var-file="your.tfvars" 2>&1 | head -30
修正の確認
tfvars ファイルの型を修正したら、再度 plan を実行してください:
terraform plan
Invalid value for input variable の行が表示されなければ、型の不一致は解消されています。正常な plan の出力は次のようになります:
Terraform will perform the following actions:
# aws_instance.web will be created
+ resource "aws_instance" "web" {
...
}
Plan: 1 to add, 0 to change, 0 to destroy.
ここまで来れば、型エラーではなくインフラのロジックに集中できます。
予防策
このクラスのエラーを減らすための3つの習慣:
variables.tfで型を明示的に宣言する。型制約がなければ Terraform は何でも受け入れますが、問題は plan 時ではなく実行時に発覚し、原因の特定が難しくなります。validationブロックを追加することで、より厳格なチェックが可能になります。生の型エラーではなく、人間が読みやすいメッセージが出力されます。- 正しい型の記述例を示した
terraform.tfvars.exampleを git で管理する。変数を更新する人が、どの形式を使えばよいか参照できます。 - CI で実際の tfvars ファイルに対して
terraform planを実行する。型のずれが本番環境に到達する前に検出できます。
# variables.tf — 明示的な型 + バリデーション
variable "instance_count" {
type = number
description = "Number of EC2 instances to create"
default = 1
validation {
condition = var.instance_count >= 1 && var.instance_count <= 20
error_message = "instance_count must be between 1 and 20."
}
}
この validation ブロックを設定しておけば、不正な値が渡されたとき「instance_count must be between 1 and 20」というメッセージが表示されます。深夜2時に10分かけて検索する羽目になる、あの不可解な型エラーとはおさらばです。

