Terraformの「templatefile」エラー:No Such File or Directoryの解決方法

beginner🏗️ Terraform2026-06-28| Terraform (全バージョン), Linux, macOS, Windows, CI/CDパイプライン (GitHub Actions, GitLab CI)

Error Message

Error: Error in function call Call to function "templatefile" failed: open ./templates/user_data.tpl: no such file or directory.
#terraform#devops#iac#トラブルシューティング

問題:すべて正しく見えるのに、エラーが発生する

3つのEC2インスタンスを展開するための複雑なTerraformモジュールを作成し終えたところだとしましょう。シェルスクリプトに動的な環境変数を注入するためにtemplatefile()関数を使用しています。IDE上ではすべてが完璧に見えます。user_data.tplファイルも、あるべき場所であるtemplatesフォルダに保存されています。

しかし、terraform planを実行すると、次のようなエラーに突き当たります:

Error: Error in function call

Call to function "templatefile" failed: open ./templates/user_data.tpl: no such file or directory.

ターミナルからls ./templates/user_data.tplを実行すれば、ファイルが存在することを確認できるかもしれません。では、なぜTerraformはそれを認識しないのでしょうか?問題はファイルが存在しないことではなく、Terraformが間違った場所を探していることにあります。

なぜパスが壊れるのか

Terraformは、./templates/user_data.tplのような相対パスを**現在の作業ディレクトリ(カレントワーキングディレクトリ)**に基づいて解決します。これはterraformコマンドを実行したフォルダのことであり、.tfコードが実際に置かれているフォルダではありません。

プロジェクトの構造が以下のようになっていると仮定します:

.
├── main.tf (ルート設定ファイル)
└── modules/
    └── web_server/
        ├── main.tf (モジュールコード)
        └── templates/
            └── user_data.tpl

もしmodules/web_server/main.tfの中でtemplatefile("./templates/user_data.tpl", {})を呼び出すと、Terraformはルートディレクトリを起点としてそのファイルを検索します。ファイルはモジュールフォルダの中に深く階層化されているため、検索は失敗します。この実行コンテキストのズレは、GitHub ActionsやJenkinsなどのCI/CDパイプラインにおけるパスエラーの最大の原因です。

まず確認すべきこと

コードを変更する前に、ベテランのエンジニアでも陥りやすい単純なミスを確認しましょう:

  • 大文字と小文字の区別: LinuxベースのCIランナーでは、Templates/templates/は別のフォルダとして扱われます。
  • 隠れた拡張子: ファイル名が実際にはuser_data.tpl.txtになっていないか確認してください。
  • 実行コンテキスト: -chdirフラグを使用してサブフォルダからTerraformを実行していませんか?これにより、Terraformが相対パスを探す場所が変わります。

確実な解決策:path.moduleを使用する

コードのポータビリティ(移植性)を高めるには、モジュール自体を基準としてファイルを探すようTerraformに指示する必要があります。Terraformには、まさにこの目的のためにpath.moduleという組み込み変数が用意されています。この変数は、その.tfファイルが存在するディレクトリのファイルシステムパスを常に指し示します。

リソースブロックを以下のように更新してください:

# 確実なアプローチ
resource "aws_instance" "web" {
  count = 3
  # ...
  user_data = templatefile("${path.module}/templates/user_data.tpl", {
    admin_email = var.admin_email
    server_id   = count.index
  })
}

${path.module}を使用すると、Terraformは絶対パスを生成します。ルートディレクトリ、サブフォルダ、あるいはリモートのビルドエージェントのどこから実行しても関係ありません。パスは常に正しく解決されます。

その他の便利なパス変数

  • path.root: Terraformの実行を開始したディレクトリを指します。
  • path.cwd: 現在のターミナルの作業ディレクトリを指します。

モジュール内でのtemplatefileの呼び出しには、ほとんどの場合path.moduleが最適なツールです。

Terraform Consoleで素早くデバッグする

パスのテストのためだけに、terraform planの完了を60秒も待つ必要はありません。terraform consoleを使えば、ロジックを即座に検証できます。これは、何もデプロイせずにパスの問題をデバッグする最短の方法です。

  • プロジェクトのルートでターミナルを開きます。
  • terraform consoleを実行します。
  • 次のコマンドを入力して絶対パスをテストします: abspath("${path.module}/modules/web_server/templates/user_data.tpl")
  • ファイルの内容を直接読み取ってみます: file("${path.module}/modules/web_server/templates/user_data.tpl")

file()関数がエラーを出さずにスクリプトの内容を返せば、パスの問題は解決です。Ctrl+Cを押して終了し、デプロイを進めましょう。

まとめ

「no such file or directory」エラーは、実際にファイルがないことは稀で、ほとんどの場合はTerraformが実行コンテキストをどのように処理するかについての誤解が原因です。ハードコードされた相対パスをやめ、${path.module}を活用することで、インフラ構成コードの耐障害性とポータビリティが高まり、デバッグも格段に容易になります。

Related Error Notes