Ansibleの「Could not find or access 'templates/nginx.conf.j2'」エラーの修正方法

beginner🔧 Ansible2026-03-18| Ansible 2.9以降、Linux/macOSコントローラー、任意の管理対象ホスト

Error Message

fatal: [host]: FAILED! => {"changed": false, "msg": "Could not find or access 'templates/nginx.conf.j2' on the Ansible Controller."}
#テンプレート#jinja2#j2#ロール#templatefile

エラーの内容

Ansible Playbookを実行すると、直ちに次のエラーで失敗します:

fatal: [host]: FAILED! => {"changed": false, "msg": "Could not find or access 'templates/nginx.conf.j2' on the Ansible Controller."}

ほとんどの場合、ansible.builtin.template(または短縮形のtemplate)を使用しているタスクが原因です。エラーメッセージをよく見ると、Ansibleが検索したのはリモートホストではなく、ansible-playbookを実行したコントローラーマシンであることがわかります。つまり、Ansibleが期待する場所にファイルが存在しなかったということです。

原因

Ansibleは、PlaybookやロールからみてrelativeにあるNodeのtemplates/サブディレクトリを自動的に検索します。これはルックアップロジックに組み込まれています。そのため、srcにはファイル名だけを指定します。templates/nginx.conf.j2ではなく、nginx.conf.j2と書きます。

このエラーが発生する原因はほぼ次の2つです:

  • src: templates/nginx.conf.j2と書いた場合、Ansibleはtemplates/templates/nginx.conf.j2を探しますが、そのパスは存在しません。
  • .j2ファイルが間違ったディレクトリに置かれており、Ansibleが実際に検索する場所にありません。

修正手順

ステップ1 — templateモジュールの呼び出し方を確認する

タスク内のsrcフィールドを確認します:

# 誤り — "templates/" プレフィックスを含めてはいけない
- name: nginx設定をデプロイ
  ansible.builtin.template:
    src: templates/nginx.conf.j2
    dest: /etc/nginx/nginx.conf

# 正しい — ファイル名のみを指定する
- name: nginx設定をデプロイ
  ansible.builtin.template:
    src: nginx.conf.j2
    dest: /etc/nginx/nginx.conf

AnsibleはPlaybookの隣、またはロール内のtemplates/を自動的に検索します。プレフィックスを追加すると、パスがtemplates/templates/nginx.conf.j2のように二重になり、そのパスは存在しません。

ステップ2 — ファイルが正しい場所にあるか確認する

シナリオA:Playbookレベルのテンプレート(ロールなし)

テンプレートはPlaybookのすぐ隣にあるtemplates/ディレクトリに配置する必要があります:

site.yml
templates/
  nginx.conf.j2    ← ここに配置する必要がある

確認コマンド:

ls -la templates/nginx.conf.j2

シナリオB:ロール内のテンプレート

ロール内のタスクは、プロジェクトルートではなく、そのロール自身のtemplates/フォルダを参照します:

roles/
  nginx/
    tasks/
      main.yml
    templates/
      nginx.conf.j2    ← ここに配置する必要がある

確認コマンド:

ls -la roles/nginx/templates/nginx.conf.j2

よくあるミス:テンプレートをプロジェクトルートのtemplates/に置いたまま、ロール内のタスクから実行してしまうケースです。Ansibleはロールのディレクトリを優先して検索するため、プロジェクトルートのファイルは見つかりません。

ステップ3 — ディレクトリ構造を修正する

ディレクトリが存在しない、または場所が間違っている場合は、ディレクトリを作成してファイルを移動します:

# "nginx" という名前のロールの場合
mkdir -p roles/nginx/templates
mv nginx.conf.j2 roles/nginx/templates/

# Playbookレベルのテンプレートの場合
mkdir -p templates
mv nginx.conf.j2 templates/

ステップ4 — タイポと大文字・小文字の区別を確認する

Linuxのファイルシステムは大文字・小文字を区別します。Nginx.conf.j2nginx.conf.j2は全く別のファイルです。ディスク上の正確なファイル名を確認してください:

ls templates/
# 表示されるべきファイル名: nginx.conf.j2 (Nginx.conf.j2 ではない)

ステップ5 — 絶対パスを使用する(最終手段)

標準外の場所にテンプレートが保存されている場合は、フルパスを直接指定します:

- name: nginx設定をデプロイ
  ansible.builtin.template:
    src: /opt/configs/nginx.conf.j2
    dest: /etc/nginx/nginx.conf

この方法は動作しますが、Playbookが特定のマシンに依存してしまいます。共有や再利用を予定しているPlaybookでは避けてください。

修正の確認

詳細なログを出力して、Ansibleが解決するパスを確認します:

ansible-playbook site.yml -vvv 2>&1 | grep -i "template\|j2"

正常に動作した場合、次のような出力が表示されます:

TASK [nginx設定をデプロイ] ****
ok: [host] => changed=true

ファイルを変更せずにテストしたい場合は、--checkオプションを追加します:

ansible-playbook site.yml --check

クイックリファレンス:Ansibleがテンプレートを検索する場所

# Playbookレベル(プロジェクトルートにsite.ymlがある場合)
./templates/
./

# ロールレベル(roles/nginx/tasks/main.yml内のタスク)
roles/nginx/templates/
roles/nginx/
./templates/      ← ここも確認されるが、ロールのテンプレートが優先される
./

Ansibleはこのリストを上から順に検索し、最初に見つかったものを使用します。templates/ディレクトリはすでに検索パスに含まれているため、srcにこのプレフィックスを追加すると、パスが二重になって検索が失敗する原因になります。

ヒント

  • srctemplates/プレフィックスを絶対に付けない — これがこのエラーの最大の原因であり、パッと見では気づきにくいポイントです。
  • フラットなPlaybookからロールにタスクを移行する際は、テンプレートも同時にロールのtemplates/ディレクトリに移動してください。そうしないとAnsibleの検索パス外になります。
  • templates/内のサブディレクトリはsrcで問題なく使用できます。例:src: nginx/nginx.conf.j2templates/nginx/nginx.conf.j2に解決されます。
  • テンプレートパスを調べる前に、ansible-playbook --list-tasksを実行して、どのロールがそのタスクを所有しているか確認しましょう。

Related Error Notes