nwinkler
nwinkler

Reputation: 54437

Can Ansible use "sudo su -" if the sudo user is not allowed to run arbitrary scripts?

I am trying to use Ansible to automate software installation and setup on several remote machines. My personal user account on the machine is locked down, but I can use sudo su - to become the root user when I log in manually. Once I'm the root user, I can run things like yum install git and similar commands.

When I tried to do that through Ansible, I tried the following to use Ansible's yum module:

- name: install Git
  yum:
    name: git
    state: present
  become: yes
  become_method: sudo
  become_user: root
  become_exe: "sudo su -"

When I ran this, it failed with an error saying that my user was not allowed to run the command

sudo su - root /tmp/foobarbazblablabla

What happens is that Ansible puts all of the Yum commands into a temporary script file and then tries to run that using the become method/exe.

It turns out that my user has the permission to run sudo su -, but not run arbitrary scripts using sudo or sudo su -, and hence Ansible fails to run the above.

I ended up using an ugly workaround like this:

- name: install Git
  shell:
    cmd: |
      sudo su - <<EOF
      yum install -y git
      EOF

This works, but is ugly and does not use Ansible's idempotent check mechanism.

Is there a better way to do this in Ansible, where Ansible executes the sudo su - first, and then executes its set of commands in the opened sub shell? Or am I out of luck with this? I doubt that the security team will grant my user permissions to run arbitrary scripts using sudo. (On the other hand, it might not hurt to ask.)

This is a description of a similar problem, but the suggested solutions are the same ugly hacks I used above: https://gist.github.com/nanobeep/3b3d614a709086ff832a

One more instance of this error with a very similar error that I get: https://www.reddit.com/r/devops/comments/53hukf/ansible_centrify_become_root/

fatal: [hostname]: FAILED! => {"changed": false, "failed": true, "module_stderr": "", 
"module_stdout": "Sorry, user username is not allowed to execute 
'/bin/sh -c echo BECOME-SUCCESS-msylkobbkasuuxlawgqppdpjxmeqirgd; LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8 LC_MESSAGES=en_US.UTF-8 
/usr/bin/python /home/username/.ansible/tmp/ansible-tmp-1474243234.94-154392424015843/lineinfile; rm -rf \"/home/username/.ansible/tmp/ansible-tmp-1474243234.94-154392424015843/\" > /dev/null 2>&1' 
as root on hostname.\r\n", "msg": "MODULE FAILURE", "parsed": false}

Update If I run sudo -l, this is displayed:

User foo may run the following commands on this host:
    (root) /bin/kill
    (root) /bin/su - bar
    (root) su -

Upvotes: 5

Views: 22908

Answers (3)

Deepend-Dev
Deepend-Dev

Reputation: 151

Just add this to playbook:

become: yes
become_method: su

and before running playbook export below env variable on host server:

ANSIBLE_BECOME_EXE=’sudo su -‘

Here is the reference link.

Upvotes: 5

MadMike
MadMike

Reputation: 1439

I had similar issues with teamviewer passwd, which wouldn't allow me to run with become: true either. This my task definition to setup a teamviewer password with ansible:

  - name: set teamviewer login to password only
    become: true
    become_method: sudo
    become_flags: 'su - root /bin/bash -c'
    command: 'teamviewer passwd {{ teamviewer_password }}'

This will run:

sudo su - root /bin/bash -c 'teamviewer passwd Th3Passw0r8'

As a sidenote: You can skip the become_*-stuff if you go with shell-task instead of command. But with that come ansible-warnings and far worse: escape-hell with your password. Don't go there.

Upvotes: 5

MillerGeek
MillerGeek

Reputation: 3137

I think this will work with

- name: install Git
  yum:
    name: git
    state: present
  become: yes
  become_method: sudo
  become_exe: "sudo su - /bin/bash -c"

Upvotes: 1

Related Questions