Ansible「Failed to create temporary directory」エラーをリモートホストで修正する

intermediate🔧 Ansible2026-05-07| Ansible 2.9+、Linuxリモートホスト(Ubuntu、CentOS、RHEL、Debian)、SSHベース接続

Error Message

Failed to create temporary directory. In some cases, you may have been able to authenticate and did not have permissions on the target directory. Please make sure your login shell is set correctly for your user and the environment is configured properly.
#ansible#tmp#パーミッション#リモート#ssh

エラーの内容

fatal: [web01]: FAILED! => {
    "msg": "Failed to create temporary directory. In some cases, you may have been able to authenticate and did not have permissions on the target directory. Please make sure your login shell is set correctly for your user and the environment is configured properly."
}

このエラーはSSH接続が正常に完了した直後に発生します — Ansibleの認証は成功したにもかかわらず、実際のタスクを実行する前にテンポラリディレクトリの作成に失敗しています。SSH接続自体は動作しているため、問題はもう一段深いところにあります。

原因

Ansibleはモジュールを実行する前に、リモートホストのテンポラリディレクトリに小さなPythonスクリプトをアップロードします。そこへの書き込みができない場合、タスクが一つも実行されないまま処理が止まります。原因はいくつかのパターンに分類されます:

  • /tmpnoexecフラグ付きでマウントされている — Ansibleはスクリプトをアップロードできても実行できない
  • リモートユーザーにテンポラリディレクトリへの書き込み権限がない
  • ログインシェルが壊れているか、/sbin/nologinまたは/bin/falseに設定されている
  • $HOMEまたは$TMPDIRが書き込み不可か存在しない
  • SELinuxまたはAppArmorがファイルシステムへのアクセスをブロックしている
  • ansible.cfg内のカスタムremote_tmpが存在しないパスを指定している

手順ごとの解決方法

手順1 — SSHと基本的な書き込みアクセスを手動で確認する

Ansibleが使用するユーザーと同じユーザーでSSH接続し、テンポラリディレクトリを確認します:

ssh deploy@web01

# ユーザーは /tmp に書き込めるか?
touch /tmp/ansible_test && echo "OK" && rm /tmp/ansible_test

# /tmp のマウントフラグを確認
mount | grep /tmp

マウント出力にnoexecが見つかった場合、それが原因です — 手順2に進んでください。

手順2 — /tmp の noexec を修正する

/tmpnoexecでマウントされている場合、Ansibleのテンポラリディレクトリを実行可能な場所にリダイレクトします。ansible.cfgに以下を追加してください:

[defaults]
remote_tmp = ~/.ansible/tmp

グローバル設定を変更したくない場合は、プレイごとに上書きすることもできます:

- hosts: webservers
  vars:
    ansible_remote_tmp: /var/tmp/.ansible
  tasks:
    - name: your task here
      ...

/var/tmpは通常noexecでマウントされていないため、信頼できる代替先です。使用する前に書き込み可能かどうか確認してください。

手順3 — リモートユーザーのログインシェルを確認する

無効なシェルが設定されていると環境が一切構成されず、Ansibleは認証できても以降の処理が何もできなくなります:

# リモートホスト上で
grep deploy /etc/passwd
# 正常: deploy:x:1001:1001::/home/deploy:/bin/bash
# 異常: deploy:x:1001:1001::/home/deploy:/sbin/nologin

壊れたシェルを修正するには:

sudo usermod -s /bin/bash deploy

手順4 — $HOME が存在し書き込み可能かを確認する

ssh deploy@web01
ls -la ~
echo $HOME

ホームディレクトリが存在しない場合は作成します:

sudo mkhomedir_helper deploy
# または手動で作成する
sudo mkdir -p /home/deploy && sudo chown deploy:deploy /home/deploy

手順5 — TMPDIR 環境変数を確認する

存在しないパスを指す古いTMPDIRが設定されていると、/tmp自体が正常でもAnsibleが失敗します:

ssh deploy@web01 'echo $TMPDIR'

存在しないパスを指している場合は、変数を削除するかパスを作成してください。あわせてパイプラインの有効化も検討してください:

[ssh_connection]
pipelining = True

パイプラインを使うとモジュールコードをtemp fileに書き込む代わりにstdin経由で送信します。この種のエラーを根本的に回避できる上、SSHのラウンドトリップが減るのでプレイブックの実行速度も向上します。

手順6 — SELinux または AppArmor を確認する

SELinuxが強制モードのRHEL/CentOS環境では、テンポラリパスを対象としたAVC拒否のログを確認します:

sudo ausearch -m avc -ts recent | grep ansible
# または
sudo journalctl -xe | grep denied

簡単な動作確認として、一時的にパーミッシブモードに切り替えてみてください(そのままにしないこと):

sudo setenforce 0
# プレイブックを再実行してSELinuxがブロックしていたか確認する
sudo setenforce 1

エラーが解消された場合は、適切なSELinuxポリシールールを作成してください。強制モードの無効化はあくまでテスト目的であり、恒久的な解決策ではありません。

手順7 — 最大詳細度で実行する

それでも解決しない場合は、詳細度を4まで上げてテンポラリパス関連のログを絞り込み、Ansibleが何を試みているか確認します:

ansible-playbook site.yml -i inventory -vvvv 2>&1 | grep -i tmp

出力にはAnsibleが書き込もうとした正確なディレクトリが表示され、根本原因がほぼ明らかになります。

修正の確認

# ホストにpingを実行 — テンポラリディレクトリのセットアップ全体を検証できる
ansible web01 -m ping -i inventory

# 期待される出力:
web01 | SUCCESS => {
    "changed": false,
    "ping": "pong"
}

ここでSUCCESSが返れば、Ansibleがtemp fileを正常に作成してモジュールを実行できたことを意味します。問題は解決しています。

補足Tips

/tmpのマウントフラグを制御できないCI/CDパイプラインでは、remote_tmp$HOME配下のサブディレクトリに固定してください。常に書き込み可能で実行可能であり、運用チームのマウント設定に依存しません:

[defaults]
remote_tmp = ~/.ansible/tmp
local_tmp  = ~/.ansible/tmp

これにパイプラインを組み合わせることで、ほとんどの環境でtemp file関連の問題を完全に解消できます:

[ssh_connection]
pipelining = True

注意点として、becomeを使用する場合、パイプラインを有効にするには/etc/sudoersrequirettyを無効にする必要があります。Defaults !requirettyをsudoersに追加してください。そうしないとsudoがTTYなしでの実行を拒否し、別のエラーに悩まされることになります。

remote_tmpのパーミッションを手動で設定する際に適切な8進数の値がわからない場合は、ToolCraftのUnix Permissions Calculatorを使えば計算の手間を省けます。

Related Error Notes