Question:
I’ve set up a box with a user david
who has sudo privileges. I can ssh into the box and perform sudo operations like apt-get install
. When I try to do the same thing using Ansible’s “become privilege escalation”, I get a permission denied
error. So a simple playbook might look like this:
simple_playbook.yml:
1 2 3 4 5 6 7 8 9 10 11 |
--- - name: Testing... hosts: all become: true become_user: david become_method: sudo tasks: - name: Just want to install sqlite3 for example... apt: name=sqlite3 state=present |
I run this playbook with the following command:
1 2 |
ansible-playbook -i inventory simple_playbook.yml --ask-become-pass |
This gives me a prompt for a password, which I give, and I get the following error (abbreviated):
1 2 3 4 5 |
fatal: [123.45.67.89]: FAILED! => {... failed: E: Could not open lock file /var/lib/dpkg/lock - open (13: Permission denied)\nE: Unable to lock the administration directory (/var/lib/dpkg/), are you root?\n", ...} |
Why am I getting permission denied?
Additional information
I’m running Ansible 2.1.1.0 and am targeting a Ubuntu 16.04 box. If I use remote_user
and sudo
options as per Ansible < v1.9, it works fine, like this:
remote_user: david
sudo: yes
Update
The local and remote usernames are the same. To get this working, I just needed to specify become: yes
(see @techraf’s answer):
Answer:
Why am I getting permission denied?
Because APT requires root permissions (see the error: are you root?
) and you are running the tasks as david
.
Per these settings:
1 2 3 4 |
become: true become_user: david become_method: sudo |
Ansible becomes david
using sudo
method. It basically runs its Python script with sudo david
in front.
the user ‘david’ on the remote box has sudo privileges.
It means david
can execute commands (some or all) using sudo
-executable to change the effective user for the child process (the command). If no username is given, this process runs as the root
account.
Compare the results of these two commands:
1 2 3 4 5 |
$ sudo whoami root $ sudo david whoami david |
Back to the APT problem, you (from CLI) as well as Ansible (connecting with SSH using your account) need to run:
1 2 |
sudo apt-get install sqlite3 |
not:
1 2 |
sudo david apt-get install sqlite3 |
which will fail with the very exact message Ansible displayed.
The following playbook will escalate by default to the root user:
1 2 3 4 5 6 7 8 9 |
--- - name: Testing... hosts: all become: true tasks: - name: Just want to install sqlite3 for example... apt: name=sqlite3 state=present |