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
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:
fatal: [webserver]: FAILED! => {
"msg": "Missing sudo password"
}Or the classic:
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:
# Show become settings
ansible-config dump | grep becomeCommon 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:
ansible-playbook site.yml --ask-become-pass
# or
ansible-playbook site.yml -KOr configure in playbook:
- hosts: webservers
become: yes
become_method: sudo
vars:
ansible_become_password: "{{ vault_become_password }}"Never hardcode passwords—use Ansible Vault:
# Create encrypted variable
ansible-vault create secrets.yml# secrets.yml
vault_become_password: mysecretpassword# Run with vault
ansible-playbook site.yml --ask-vault-passUser 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):
- hosts: webserver
become: yes
tasks:
- name: Add user to sudo group
user:
name: deploy
groups: sudo
append: yesPasswordless Sudo Not Configured
The user can sudo but needs a password.
Configure passwordless sudo:
# On the target host
sudo visudoAdd:
deploy ALL=(ALL) NOPASSWD: ALLOr for specific commands only:
deploy ALL=(ALL) NOPASSWD: /usr/bin/apt, /usr/bin/systemctlOr use a drop-in file:
sudo bash -c 'echo "deploy ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/deploy'
sudo chmod 440 /etc/sudoers.d/deployUsing Ansible:
- 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:
ansible webserver -m shell -a "id postgres"Fix by ensuring user exists:
- hosts: all
become: yes
tasks:
- name: Ensure postgres user exists
user:
name: postgres
system: yes
shell: /bin/bashBecome 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:
ansible webserver -m shell -a "getenforce"Temporarily disable:
ansible webserver -b -m shell -a "setenforce 0"Install SELinux bindings:
- hosts: all
become: yes
tasks:
- name: Install SELinux Python bindings
package:
name: libselinux-python3
state: presentTemporary File Permissions
Ansible creates temp files that need proper permissions.
Problem:
``
Failed to set permissions on the temporary files
Quick workaround in ansible.cfg:
[defaults]
allow_world_readable_tempfiles = TrueBetter fix—use pipelining:
[ssh_connection]
pipelining = TruePipelining reduces temporary file creation. However, it requires requiretty to be disabled in sudoers.
Disable requiretty:
# On target
sudo visudoComment out or remove:
# Defaults requirettyOr add:
Defaults:deploy !requirettyHost Key Checking with Become
When using become, host keys might need rechecking.
Disable strict host key checking temporarily:
[defaults]
host_key_checking = FalseBetter approach—accept keys in known_hosts:
ssh-keyscan webserver >> ~/.ssh/known_hostsAnsible 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:
- hosts: webservers
become: yes
tasks:
- name: Install package
apt:
name: nginx
state: presentEnable 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:
- 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.User in sudoers?
ssh user@host "sudo -l" - 2.Passwordless sudo? Check
/etc/sudoers.d/ - 3.Become enabled?
ansible-config dump | grep become - 4.Right become method? Use
sudofor most systems - 5.SELinux? Install
libselinux-python3 - 6.Temp file issues? Enable pipelining