Terraformの「Invalid template interpolation value」エラーの解決方法

beginner🏗️ Terraform2026-06-07| Terraform CLI (v0.12以降), Linux, macOS, または Windows

Error Message

Error: Invalid template interpolation value: the template interpolation at line X requires a string value, not object.
#terraform#devops#hcl#トラブルシューティング

問題点

Terraformは通常、型に対して柔軟ですが、文字列の補間(interpolation)に関しては厳格な制限があります。単純な文字列が必要な場所に複雑なデータ構造を入れようとすると、planapplyの実行中にこのエラーが発生します。

Error: Invalid template interpolation value

on main.tf line 42, in resource "aws_instance" "example":
42:   user_data = "echo ${var.config_map}"

|----------------
| var.config_map is object with 2 attributes

Cannot include the given value in a string template: string required.

${...}構文の役割はただ一つ、文字列を挿入することです。リスト、マップ、またはオブジェクトを渡しても、Terraformはそれをどのようにフォーマットすべきか推測しません。Terraformはプレーンな文字列を期待しており、多層のオブジェクトを検出すると処理を停止します。

よくあるシナリオ

これは単なる構文の癖ではなく、型の不一致(type mismatch)です。以下のような場合に頻繁に遭遇します:

  • user_dataのシェルスクリプトに環境変数のマップを渡している。
  • 設定ファイルに5つのプライベートIPアドレスのリストを出力しようとしている。
  • タグやメタデータフィールドにリソースオブジェクト全体を注入している。

3つの解決方法

解決策は、変換後にデータをどのように表示させたいかによって異なります。以下に標準的なアプローチを紹介します。

1. マップとオブジェクトには jsonencode() を使用する

送信先(SSMパラメータや設定ファイルなど)が構造化データを期待している場合は、jsonencode()を使用します。これにより、HCLオブジェクトが自動的に有効なJSON文字列に変換されます。

間違った方法:

resource "aws_ssm_parameter" "config" {
  name  = "app_settings"
  type  = "String"
  value = "settings = ${var.my_map}" # これによりエラーが発生します
}

正しい方法:

resource "aws_ssm_parameter" "config" {
  name  = "app_settings"
  type  = "String"
  value = jsonencode(var.my_map) # "{\"key\":\"value\"}" を返します
}

2. リストには join() を使用する

リストの扱いは少し特殊です。文字列のリストがある場合、通常はカンマやスペースなどの区切り文字で結合したいはずです。

例:

resource "aws_instance" "web" {
  # 3つのCIDRブロックのリストを、カンマ区切りの1つの文字列に結合する
  user_data = <<-EOT
    #!/bin/bash
    echo "許可されたソース: ${join(", ", var.external_ips)}"
  EOT
}

3. 複雑なフォーマットにはHCLディレクティブを使用する

jsonencodeでは出力が煩雑になりすぎる場合があります。templatefile()を使用してカスタム設定(NginxやHaProxyの設定など)を生成する場合は、テンプレート内でforループディレクティブを使用します。

テンプレート (config.tftpl):

%{ for name, ip in servers ~}
server ${name} ${ip}:8080
%{ endfor ~}

Terraformコード:

content = templatefile("config.tftpl", { 
  servers = { "web01" = "10.0.1.5", "web02" = "10.0.1.6" }
})

デプロイせずにテストする

修正が機能するか確認するために、時間のかかるterraform planを待つ必要はありません。組み込みのコンソールを使用して、すぐにフィードバックを得ることができます:

  • ターミナルで terraform console を実行します。
  • ロジックを入力します: join(" | ", ["prod", "staging"])
  • "prod | staging" と出力されれば、補間は安全です。

専門家のアドバイス

  • 厳格な型指定: 変数を明確に定義しましょう。type = map(string) を使用すると、デプロイの途中で失敗するのではなく、入力段階でエラーをキャッチできます。
  • YAMLのサポート: ログに対してJSONが大きすぎる場合は、yamlencode() がJSON版と同じように機能しますが、よりクリーンなYAMLを出力します。
  • セキュリティ: 機密情報を含むオブジェクトに対して jsonencode を使用する場合は注意してください。変数に sensitive = true が設定されている場合、Terraformはパスワードを保護するために、CLI出力内の文字列全体を伏せ字(redact)にします。

Related Error Notes