「Inconsistent result types」エラーの原因と解決方法

1. 概要

  • 「Inconsistent result types」エラーとは
  • 主な発生パターン(条件式・for式・list/map)
  • 原因と解決方法
  • 型強制(tostring/tolist等)の活用

Inconsistent result typesエラーは、Terraformが1つの式から複数の異なる型の値を返そうとしたときに発生します。最もよく見かけるのは条件式(condition ? true_value : false_value)のtrue_valuefalse_valueの型が異なるケースです。


2. 条件式での型不一致

エラー例

variable "environment" {
  description = "環境名"
  type        = string
  default     = "dev"
}

locals {
  # ❌ エラー: trueはstring、falseはnumber → 型不一致
  value = var.environment == "prd" ? "large" : 100
}
Error: Inconsistent conditional result types
The true and false result expressions must have consistent types.

修正方法

locals {
  # ✅ 両辺を同じ型に揃える
  value = var.environment == "prd" ? "large" : "small"
}

3. 実践例: 条件式でnull vs 文字列

terraform {
  required_version = ">= 1.9"
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
}

provider "aws" {
  region = "ap-northeast-1"
}

variable "enable_alarm" {
  description = "アラームを有効にするか"
  type        = bool
  default     = false
}

variable "alarm_email" {
  description = "アラーム通知先メールアドレス"
  type        = string
  default     = ""
}

# ❌ エラーになるパターン: null と string の混在
# sns_topic_arn = var.enable_alarm ? aws_sns_topic.alerts[0].arn : null
# → 片方がstring(arn)、片方がnullでも実は動く場合とエラーになる場合がある

# ✅ 正しいパターン: countで条件付きリソース作成
resource "aws_sns_topic" "alerts" {
  count = var.enable_alarm ? 1 : 0
  name  = "${var.environment}-alerts"

  tags = {
    Name        = "${var.environment}-alerts"
    Environment = var.environment
    ManagedBy   = "terraform"
  }
}

variable "environment" {
  description = "環境名"
  type        = string
  default     = "dev"
}

resource "aws_cloudwatch_metric_alarm" "high_cpu" {
  count = var.enable_alarm ? 1 : 0

  alarm_name          = "${var.environment}-high-cpu"
  comparison_operator = "GreaterThanThreshold"
  evaluation_periods  = 2
  metric_name         = "CPUUtilization"
  namespace           = "AWS/EC2"
  period              = 300
  statistic           = "Average"
  threshold           = 80

  alarm_actions = [aws_sns_topic.alerts[0].arn]

  tags = {
    Name        = "${var.environment}-high-cpu"
    Environment = var.environment
    ManagedBy   = "terraform"
  }
}

4. for式でのリスト要素の型不一致

variable "items" {
  description = "アイテムリスト"
  type        = list(any)
  default     = ["a", 1, "b"]  # string と number が混在
}

locals {
  # ❌ エラー: stringとnumberが混在したlistを変換しようとする
  # processed = [for item in var.items : upper(item)]

  # ✅ tostring()で型を統一する
  processed = [for item in var.items : upper(tostring(item))]
}

5. map の値の型不一致

locals {
  # ❌ エラー: mapの値にstringとnumberが混在
  # config = {
  #   name    = "dev"
  #   count   = 3
  # }

  # ✅ 型を統一するか、object型で明示的に定義
  config = {
    name  = "dev"
    count = "3"  # stringに統一
  }
}

6. よくある発生パターンと対処法

パターンエラー原因対処法
condition ? "text" : 42true=string, false=number両辺を同じ型に統一
condition ? resource.arn : nullnull との組み合わせcount/for_eachで条件付き作成
[for x in list : func(x)]listの要素型が混在tostring()で型変換
mapリテラルで型混在map値がstring/number混在値をstringに統一

7. 関連記事


8. まとめ

  • Inconsistent result typesは条件式の?:の両辺・for式のリスト要素・mapの値の型が揃っていないときに発生
  • 最も多いのは条件式でtrue側とfalse側の型が異なるケース
  • tostring() / tonumber() / tolist()で明示的に型を揃える
  • nullとの組み合わせエラーはcount/for_eachで条件付きリソース作成に変換する

動作確認バージョン: Terraform >= 1.9 公式ドキュメント: https://developer.hashicorp.com/terraform/language/expressions/conditionals