エラーの状況
プレイブックに become: true が設定されています。SSH 接続は問題なく完了します。そして、ターミナルにこのメッセージが表示されます:
fatal: [host]: FAILED! => {"msg": "Missing sudo password"}
プレイが停止します。Ansible はホストに到達し、SSH で認証に成功しましたが、その後に壁にぶつかりました — sudo がパスワードを要求したのに、Ansible には渡すパスワードがなかったのです。
注目すべき点は、これは接続の失敗ではありません。SSH は正常に動作しています。リモートユーザーも存在します。問題は、そのアカウントが root への権限昇格にパスワードを必要とするのに、Ansible がそのパスワードを知らないことです。
このエラーが発生する理由
タスクが become: true で実行されると、Ansible はリモートホスト上で sudo(または設定した become_method)を呼び出します。そのユーザーが NOPASSWD の sudoers グループに属していない場合、sudo はパスワードを要求します。
Ansible はパスワードを提供できますが、それはパスワードを教えた場合に限ります。ansible_become_pass が設定されていない場合、Ansible は空の文字列を渡します。sudo はそれを拒否し、エラーが発生します。
このエラーは通常、次のいずれかの状況で発生します:
- 通常の sudo(パスワードレスではない)を持つリモートユーザーで新しいホストが追加された
- セキュリティ強化により、既存ホストの sudoers から
NOPASSWDが削除された - プレイブックはローカルで正常に動作するが、CI では失敗する — パイプラインでパスワードが渡されない
- sudo パスワードが必要なサービスアカウントでデプロイしている
クイックフィックス:実行時にパスワードを渡す
すぐに解決したい場合は、Ansible に become パスワードのプロンプトを表示するよう指示します:
ansible-playbook site.yml -i inventory --ask-become-pass
プロンプトは一度だけ表示され、そのパスワードが実行中のすべてのホストに適用されます。一度限りの実行やインタラクティブなテストに適しています。短縮形は -K です:
ansible-playbook site.yml -i inventory -K
動作確認: インベントリに対して簡単なスモークテストを実行します:
ansible all -i inventory -m command -a "whoami" --become -K
期待される出力:各ホストで root が表示されます。これが確認できれば、権限昇格は正常に機能しています。
恒久的な修正 1:インベントリに become_pass を設定する
ローカルの検証環境や非本番環境では、become パスワードをインベントリに直接記述できます。inventory/hosts.ini にホストごとに設定する場合:
[webservers]
192.168.1.10 ansible_user=deploy ansible_become_pass=yourpassword
192.168.1.11 ansible_user=deploy ansible_become_pass=yourpassword
または inventory/group_vars/webservers.yml にグループ変数として設定する場合:
ansible_user: deploy
ansible_become_pass: yourpassword
重要なルール:Git に平文パスワードをコミットしてはいけません。 このアプローチは、ローカル開発環境の使い捨て資格情報にのみ許容されます。実際のサーバーに触れるものはすべて Vault が必要です — 以下の修正 2 を参照してください。
恒久的な修正 2:Ansible Vault で暗号化する
本番環境では、これが正しいアプローチです。become パスワードを Ansible Vault で暗号化することで、シークレットを公開せずにバージョン管理に保存できます。
ステップ 1:暗号化された変数ファイルを作成する
ansible-vault create group_vars/webservers/vault.yml
ファイル内にパスワードを追加します:
vault_become_pass: "yourSudoPassword"
ステップ 2:通常の変数ファイルから参照する
group_vars/webservers/vars.yml に記述します:
ansible_become_pass: "{{ vault_become_pass }}"
ステップ 3:vault パスワードを使用して実行する
# 実行時にプロンプト(インタラクティブな使用)
ansible-playbook site.yml -i inventory --ask-vault-pass
# パスワードファイルを使用(CI/CD パイプライン)
ansible-playbook site.yml -i inventory --vault-password-file ~/.vault_pass
設定の確認:
ansible-vault view group_vars/webservers/vault.yml
プロンプトが表示されたら vault パスワードを入力します。復号化されたコンテンツが表示されるはずです。表示されれば、すべてが正しく設定されています。
恒久的な修正 3:パスワードレス sudo(ポリシーで許可されている場合)
一部のチームは、管理対象ホストで Ansible サービスアカウントにパスワードレス sudo を付与しています。これによりパスワードの問題が完全になくなります — 保存する資格情報も、プロンプトも、Vault エントリも不要です。
リモートホストで、visudo を使用して sudoers を安全に編集します:
sudo visudo -f /etc/sudoers.d/ansible
deploy ユーザーへのフルアクセス:
deploy ALL=(ALL) NOPASSWD: ALL
セキュリティポリシーで必要な場合は、特定のコマンドに制限します:
deploy ALL=(ALL) NOPASSWD: /usr/bin/apt, /usr/bin/systemctl
設定が完了したら、変数から ansible_become_pass を完全に削除して確認します:
ansible all -i inventory -m command -a "whoami" --become
root が表示されるはずです — パスワードのプロンプトもエラーもありません。
become 設定の確認
プレイブックのどこに become が設定されているかわからない場合は、ここから始めます:
# become の参照をすべて検索
grep -r "become" site.yml roles/
# 有効な become_method を確認
ansible-config dump | grep BECOME
become を使用した最小限の動作するプレイブック:
---
- hosts: webservers
become: true
become_method: sudo # デフォルト — 省略しても安全
tasks:
- name: nginx をインストール
apt:
name: nginx
state: present
ヒント
Ansible サービスアカウントのパスワードには、覚えやすいものは避けてください。手で入力することのない、ランダムな 32 文字のパスワードを生成しましょう。ToolCraft のパスワードジェネレーターはブラウザ上で完全に動作し、サーバーには何も送信されないため、サービス資格情報の生成に安全です。結果を Ansible Vault に保存すれば完了です。
become を使用するプレイブックでファイルのパーミッションも管理していますか?同サイトの Unix パーミッション計算機を使えば、試行錯誤なしに適切な chmod の値を素早く調べられます。
まとめ
- 一度限りの実行:
-Kまたは--ask-become-passを使用する - チーム・本番環境:
ansible_become_passを Ansible Vault で暗号化する - サービスアカウント: Ansible ユーザーの sudoers に
NOPASSWDを設定する - バージョン管理に平文パスワードをコミットしない

