The Error Scenario
Your playbook has become: true set. SSH connects without a hitch. Then this lands in your terminal:
fatal: [host]: FAILED! => {"msg": "Missing sudo password"}
The play stops dead. Ansible reached the host, authenticated over SSH, and then hit a wall โ sudo demanded a password, and Ansible had nothing to give it.
Worth noting: this isn't a connection failure. SSH is working. The remote user exists. The problem is specifically that the account requires a password to escalate to root, and Ansible doesn't know what it is.
Why This Happens
When a task runs with become: true, Ansible calls sudo (or whatever become_method you've configured) on the remote host. If that user isn't in the NOPASSWD sudoers group, sudo asks for a password.
Ansible can supply it โ but only if you tell it what the password is. Without ansible_become_pass set, Ansible passes an empty string. Sudo rejects it. Error fires.
You'll typically hit this in one of these situations:
- A new host was added where the remote user has normal sudo, not passwordless
- Security hardening removed
NOPASSWDfrom sudoers on existing hosts - Playbook runs fine locally but fails in CI โ no password gets passed in the pipeline
- You're deploying with a service account that requires a sudo password
Quick Fix: Pass the Password at Runtime
Need to get moving right now? Tell Ansible to prompt for the become password before it runs:
ansible-playbook site.yml -i inventory --ask-become-pass
You'll be prompted once, and that password applies to every host in the run. Good for one-off executions or interactive testing. The short form is -K:
ansible-playbook site.yml -i inventory -K
Verify it worked: Run a quick smoke test against your inventory:
ansible all -i inventory -m command -a "whoami" --become -K
Expected output: root for each host. See that, and privilege escalation is working correctly.
Permanent Fix 1: Set become_pass in Inventory
For local labs or non-production setups, you can drop the become password directly into your inventory. Per-host in 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
Or as a group variable in inventory/group_vars/webservers.yml:
ansible_user: deploy
ansible_become_pass: yourpassword
Hard rule: don't commit plaintext passwords to Git. This approach is only acceptable for throwaway credentials in a local dev environment. Anything touching a real server needs Vault โ see Fix 2 below.
Permanent Fix 2: Encrypt with Ansible Vault
For production, this is the right approach. Encrypt the become password with Ansible Vault so it can live in version control without exposing secrets.
Step 1: Create an encrypted vars file
ansible-vault create group_vars/webservers/vault.yml
Add the password inside the file:
vault_become_pass: "yourSudoPassword"
Step 2: Reference it in your regular vars file
In group_vars/webservers/vars.yml:
ansible_become_pass: "{{ vault_become_pass }}"
Step 3: Run with the vault password
# Prompt at runtime (interactive use)
ansible-playbook site.yml -i inventory --ask-vault-pass
# Use a password file (CI/CD pipelines)
ansible-playbook site.yml -i inventory --vault-password-file ~/.vault_pass
Verify the setup:
ansible-vault view group_vars/webservers/vault.yml
Enter your vault password when prompted. You should see the decrypted content. If you do, everything is wired up correctly.
Permanent Fix 3: Passwordless sudo (When Your Policy Allows It)
Some teams grant the Ansible service account passwordless sudo on managed hosts. It removes the password problem entirely โ no credential to store, no prompt, no Vault entry required.
On the remote host, edit sudoers safely with visudo:
sudo visudo -f /etc/sudoers.d/ansible
Full access for the deploy user:
deploy ALL=(ALL) NOPASSWD: ALL
Or lock it down to specific commands if your security policy requires it:
deploy ALL=(ALL) NOPASSWD: /usr/bin/apt, /usr/bin/systemctl
Once that's in place, drop ansible_become_pass from your vars entirely and verify:
ansible all -i inventory -m command -a "whoami" --become
You should see root โ no password prompt, no error.
Checking Your become Configuration
Not sure where become is set in your playbook stack? Start here:
# Find all become references
grep -r "become" site.yml roles/
# Check the active become_method
ansible-config dump | grep BECOME
A minimal working playbook with become:
---
- hosts: webservers
become: true
become_method: sudo # default โ safe to omit
tasks:
- name: Install nginx
apt:
name: nginx
state: present
Tips
For Ansible service account passwords, skip anything memorable. Generate a random 32-character password โ something you'd never type by hand. The Password Generator at ToolCraft runs entirely in your browser with nothing sent to any server, so it's safe for generating service credentials. Store the result in Ansible Vault and you're done.
Managing file permissions in the same playbooks that use become? The Unix Permissions Calculator on the same site saves time figuring out the right chmod values without trial and error.
Summary
- One-time run: use
-Kor--ask-become-pass - Team/production: encrypt
ansible_become_passwith Ansible Vault - Service account: configure
NOPASSWDin sudoers for the Ansible user - Never commit plaintext passwords to version control

