Introduction

When Ansible runs tasks with become: true, it needs to escalate privileges via sudo. If the remote user requires a password for sudo and Ansible doesn't have it, you get "Missing sudo password" or "Incorrect sudo password" errors. This guide covers all methods to provide the sudo password — or eliminate the need for one.

The Error

fatal: [webserver01]: FAILED! => {"msg": "Missing sudo password"}
fatal: [webserver01]: FAILED! => {"msg": "Incorrect sudo password"}

Quick Fix Options

# Option 1: Prompt for sudo password at runtime
ansible-playbook site.yml --ask-become-pass
# or short form:
ansible-playbook site.yml -K

# Option 2: Set in inventory
# inventory/hosts
[webservers:vars]
ansible_become_pass=MySudoPassword

# Option 3: Use vault (recommended)
ansible-playbook site.yml --become --vault-password-file .vault_pass

Method 1: Command-Line Prompt

# Interactive prompt — simplest for manual runs
ansible-playbook -i inventory site.yml -K
# BECOME password: ********

# Combine with SSH password prompt
ansible-playbook -i inventory site.yml -k -K
# SSH password: ********
# BECOME password: ********

Method 2: Inventory Variables

# inventory/hosts
[webservers]
web01 ansible_host=10.0.1.10
web02 ansible_host=10.0.1.11

[webservers:vars]
ansible_user=deploy
ansible_become=true
ansible_become_pass=MySudoP@ss  # ⚠️ Plaintext — not recommended
# Create encrypted vars file
ansible-vault create group_vars/all/vault.yml
# group_vars/all/vault.yml (encrypted)
ansible_become_pass: "SecureP@ssw0rd!"
# group_vars/all/main.yml (reference vault var)
ansible_become_pass: "{{ vault_become_pass }}"
# Run with vault
ansible-playbook site.yml --vault-password-file .vault_pass

Per-Host Vault Passwords

# host_vars/web01.yml
ansible_become_pass: "{{ vault_web01_become_pass }}"

# host_vars/db01.yml
ansible_become_pass: "{{ vault_db01_become_pass }}"

Method 4: Passwordless Sudo (Best Practice)

# On the remote host, add to /etc/sudoers.d/ansible:
deploy ALL=(ALL) NOPASSWD: ALL
# Automate it with Ansible (requires initial password):
- name: Configure passwordless sudo for deploy user
  ansible.builtin.lineinfile:
    path: /etc/sudoers.d/ansible
    line: "deploy ALL=(ALL) NOPASSWD: ALL"
    create: true
    mode: '0440'
    validate: "visudo -cf %s"
  become: true

Limited Passwordless Sudo

# Only specific commands (more secure):
deploy ALL=(ALL) NOPASSWD: /usr/bin/systemctl, /usr/bin/apt-get, /usr/bin/cp

Method 5: ansible.cfg Configuration

# ansible.cfg
[privilege_escalation]
become = true
become_method = sudo
become_user = root
become_ask_pass = false  # Set true to always prompt

[defaults]
# Timeout for privilege escalation prompt
timeout = 30

Playbook-Level Configuration

---
- name: Deploy application
  hosts: webservers
  become: true
  become_method: sudo
  become_user: root
  vars:
    ansible_become_pass: "{{ vault_sudo_pass }}"
  tasks:
    - name: Install packages
      ansible.builtin.apt:
        name: nginx
        state: present

Per-Task Become

- name: Read file as normal user
  ansible.builtin.command: cat /home/deploy/.profile
  become: false

- name: Install package as root
  ansible.builtin.apt:
    name: nginx
    state: present
  become: true
  become_user: root

CI/CD Integration

GitHub Actions

- name: Run playbook
  env:
    ANSIBLE_BECOME_PASS: ${{ secrets.SUDO_PASSWORD }}
  run: |
    ansible-playbook -i inventory site.yml \
      -e "ansible_become_pass=$ANSIBLE_BECOME_PASS"

Using Environment Variable

# ansible.cfg
[defaults]
# Read become password from environment
# (requires custom plugin or extra_vars)
export ANSIBLE_BECOME_PASS="mysecretpass"
ansible-playbook site.yml -e "ansible_become_pass=${ANSIBLE_BECOME_PASS}"

Alternative Become Methods

# su instead of sudo
become_method: su

# pbrun (PowerBroker)
become_method: pbrun

# doas (OpenBSD)
become_method: doas

# pfexec (Solaris)
become_method: pfexec

# runas (Windows)
become_method: runas
become_user: Administrator

Troubleshooting

ErrorCauseFix
Missing sudo passwordNo password provided, sudo requires oneUse -K, set ansible_become_pass, or configure NOPASSWD
Incorrect sudo passwordWrong passwordVerify password, check user exists on remote
sudo: a password is requiredNOPASSWD not set for this userAdd sudoers entry or provide password
sudo: user not in sudoersUser lacks sudo accessAdd to sudo group or create sudoers entry
Timeout waiting for privilege escalationsudo prompt hangingCheck requiretty in sudoers, increase timeout
sudo: sorry, you must have a ttyrequiretty set in sudoersAdd Defaults:deploy !requiretty or use become_flags: '-H -S'

Fix requiretty

# If sudoers has "Defaults requiretty":
- name: Disable requiretty for ansible user
  ansible.builtin.lineinfile:
    path: /etc/sudoers.d/ansible
    line: "Defaults:deploy !requiretty"
    create: true
    mode: '0440'
    validate: "visudo -cf %s"

Security Best Practices

  1. Use passwordless NOPASSWD — most secure for automation (no passwords stored anywhere)
  2. If passwords needed, use Vault — never plaintext in inventory
  3. Limit NOPASSWD scope — allow only needed commands if possible
  4. Use dedicated automation user — don't use personal accounts
  5. Audit sudoers regularly — review what the automation user can do
  6. Rotate passwords — if using become_pass, rotate via Vault rekey

Conclusion

The best fix is passwordless sudo (NOPASSWD: ALL in sudoers) — no passwords to manage or leak. If that's not possible, store the sudo password in Ansible Vault and reference it via ansible_become_pass. Use -K for one-off manual runs. Never store sudo passwords in plaintext inventory files.