Your playbook fails with a permission denied error when trying to become root or another user. Privilege escalation is essential for many Ansible operations—installing packages, managing services, editing system files—but when sudo doesn't work, nothing works.

The Error

bash
fatal: [webserver]: FAILED! => {
    "msg": "Failed to set permissions on the temporary files Ansible needs to create when becoming an unprivileged user (rc: 1, err: chown: changing ownership of '/home/user/.ansible/tmp/ansible-tmp-1640000000.0-12345/': Operation not permitted\n}). As a temporary workaround, you can set 'allow_world_readable_tempfiles' to True in ansible.cfg."
}

Or:

bash
fatal: [webserver]: FAILED! => {
    "msg": "Missing sudo password"
}

Or the classic:

bash
fatal: [webserver]: FAILED! => {
    "msg": "Sorry, user deploy is not allowed to execute '/bin/sh' as root on webserver."
}

Quick Diagnosis

Test sudo access manually:

```bash # SSH to host ssh deploy@webserver

# Test sudo sudo -l

# Test specific command sudo whoami ```

Test from Ansible:

```bash # Test become without password ansible webserver -b -m shell -a "whoami"

# Test become with password ansible webserver -b --ask-become-pass -m shell -a "whoami" ```

Check become configuration:

bash
# Show become settings
ansible-config dump | grep become

Common Causes and Fixes

Missing Sudo Password

The user needs a password to sudo but you haven't provided it.

Ask for password on command line:

bash
ansible-playbook site.yml --ask-become-pass
# or
ansible-playbook site.yml -K

Or configure in playbook:

yaml
- hosts: webservers
  become: yes
  become_method: sudo
  vars:
    ansible_become_password: "{{ vault_become_password }}"

Never hardcode passwords—use Ansible Vault:

bash
# Create encrypted variable
ansible-vault create secrets.yml
yaml
# secrets.yml
vault_become_password: mysecretpassword
bash
# Run with vault
ansible-playbook site.yml --ask-vault-pass

User Not in Sudoers

The SSH user isn't allowed to use sudo.

Add user to sudoers on the target:

```bash # SSH as root ssh root@webserver

# Add user to sudo group (Debian/Ubuntu) usermod -aG sudo deploy

# Add user to wheel group (RHEL/CentOS) usermod -aG wheel deploy

# Or add specific sudoers entry echo "deploy ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/deploy chmod 440 /etc/sudoers.d/deploy ```

Using Ansible to fix (if you have root access):

yaml
- hosts: webserver
  become: yes
  tasks:
    - name: Add user to sudo group
      user:
        name: deploy
        groups: sudo
        append: yes

Passwordless Sudo Not Configured

The user can sudo but needs a password.

Configure passwordless sudo:

bash
# On the target host
sudo visudo

Add:

bash
deploy ALL=(ALL) NOPASSWD: ALL

Or for specific commands only:

bash
deploy ALL=(ALL) NOPASSWD: /usr/bin/apt, /usr/bin/systemctl

Or use a drop-in file:

bash
sudo bash -c 'echo "deploy ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/deploy'
sudo chmod 440 /etc/sudoers.d/deploy

Using Ansible:

yaml
- hosts: all
  become: yes
  tasks:
    - name: Allow passwordless sudo for deploy user
      copy:
        dest: /etc/sudoers.d/deploy
        content: "deploy ALL=(ALL) NOPASSWD: ALL"
        mode: '0440'
        validate: 'visudo -cf %s'

The validate option checks syntax before applying.

Wrong Become User

Trying to become a user that doesn't exist or you can't become.

Problem: ``yaml - hosts: all become: yes become_user: postgres

Check if user exists:

bash
ansible webserver -m shell -a "id postgres"

Fix by ensuring user exists:

yaml
- hosts: all
  become: yes
  tasks:
    - name: Ensure postgres user exists
      user:
        name: postgres
        system: yes
        shell: /bin/bash

Become Method Not Available

Different systems use different privilege escalation methods.

Available methods: - sudo (default) - su - pbrun - pfexec - doas - dzdo - ksu - runas (Windows)

Configure become method:

In ansible.cfg: ``ini [privilege_escalation] become = True become_method = sudo become_user = root become_ask_pass = False

In playbook: ``yaml - hosts: all become: yes become_method: su become_user: root

For BSD systems: ``yaml - hosts: bsdservers become: yes become_method: doas

SELinux Blocking Sudo

On SELinux-enabled systems, policies can block sudo.

Check SELinux status:

bash
ansible webserver -m shell -a "getenforce"

Temporarily disable:

bash
ansible webserver -b -m shell -a "setenforce 0"

Install SELinux bindings:

yaml
- hosts: all
  become: yes
  tasks:
    - name: Install SELinux Python bindings
      package:
        name: libselinux-python3
        state: present

Temporary File Permissions

Ansible creates temp files that need proper permissions.

Problem: `` Failed to set permissions on the temporary files

Quick workaround in ansible.cfg:

ini
[defaults]
allow_world_readable_tempfiles = True

Better fix—use pipelining:

ini
[ssh_connection]
pipelining = True

Pipelining reduces temporary file creation. However, it requires requiretty to be disabled in sudoers.

Disable requiretty:

bash
# On target
sudo visudo

Comment out or remove:

bash
# Defaults requiretty

Or add:

bash
Defaults:deploy !requiretty

Host Key Checking with Become

When using become, host keys might need rechecking.

Disable strict host key checking temporarily:

ini
[defaults]
host_key_checking = False

Better approach—accept keys in known_hosts:

bash
ssh-keyscan webserver >> ~/.ssh/known_hosts

Ansible Configuration for Become

Complete ansible.cfg:

```ini [defaults] inventory = ./inventory remote_user = deploy ask_become_pass = False

[privilege_escalation] become = True become_method = sudo become_user = root become_ask_pass = False

[ssh_connection] pipelining = True ```

Per-host become configuration:

```ini [webservers] web1 ansible_user=deploy ansible_become=yes ansible_become_method=sudo

[dbservers] db1 ansible_user=postgres ansible_become=no ```

Playbook-Level Configuration

Enable become for entire play:

yaml
- hosts: webservers
  become: yes
  tasks:
    - name: Install package
      apt:
        name: nginx
        state: present

Enable per-task:

```yaml - hosts: webservers tasks: - name: Install package (requires root) apt: name: nginx state: present become: yes

  • name: Copy user file (no root needed)
  • copy:
  • src: userfile
  • dest: /home/deploy/userfile
  • become: no
  • `

Become a different user:

yaml
- hosts: webservers
  become: yes
  become_user: postgres
  tasks:
    - name: Run psql command
      command: psql -c "SELECT 1"

Verification

After configuration:

```bash # Test sudo access ansible webserver -b -m shell -a "whoami" # Should return: root

# Test specific user ansible webserver -b -m shell -a "whoami" -e "ansible_become_user=postgres" # Should return: postgres

# Test without password ansible webserver -b -m ping

# Full playbook test ansible-playbook site.yml --check ```

Quick Checklist

  1. 1.User in sudoers? ssh user@host "sudo -l"
  2. 2.Passwordless sudo? Check /etc/sudoers.d/
  3. 3.Become enabled? ansible-config dump | grep become
  4. 4.Right become method? Use sudo for most systems
  5. 5.SELinux? Install libselinux-python3
  6. 6.Temp file issues? Enable pipelining