Updated April 14, 2023
Introduction to Ansible Sudo
The following article provides an outline for Ansible Sudo. In Ansible, we work on remote target machines by using playbooks which have plays and tasks. The playbook will run on remote target machines as same user as on Ansible controller machine, unless specified otherwise. But there are times when the requirement is to run a task as some other user on remote target nodes. In such cases, we need become plugins like sudo, which stands for substitute user do. This enables the remote user to execute commands as another user or privileged user. There are few other options in this plugin which make it more flexible to use.
What is Ansible Sudo?
In Ansible, we can use become to make use to Linux system’s sudo feature. This makes one user to execute commands on system as another user for the moment of command execution. There are various ways to tell Ansible about the privileged user, password and other related options. These ways include defining variables, making entries in inventory file or in imported file.
Ansible uses parameters like become_exe, become_flag, become_pass, become_user to achieve same.
Given below is the detail of such parameters:
1. become_exe: To set the sudo.
Possible ini entries:
- [privilege_escalation] executable = sudo
- [sudo_become_plugin] become_exe = sudo
- env:ANSIBLE_SUDO_EXE
- env:ANSIBLE_BECOME_EXE
- var:ansible_sudo_exe
- var:ansible_become_exe
2. become_flag: To set options to pass in sudo.
ini entries:
- [privilege_escalation] become_flags = -H -S -n
- [sudo_become_plugin] flags = -H -S -n
- env:ANSIBLE_BECOME_FLAGS
- env:ANSIBLE_SUDO_FLAGS
- var:ansible_become_flags
- var:ansible_sudo_flags
3. become_pass: To set the Password to pass to sudo for sudo user.
ini entries:
- [sudo_become_plugin] password = value
- env:ANSIBLE_BECOME_PASS
- env:ANSIBLE_SUDO_PASS
- var:ansible_become_pass
- var:ansible_become_password
- var:ansible_sudo_pass
4. become_user: To set the sudo user.
ini entries:
- [privilege_escalation] become_user=root
- user=root
- env:ANSIBLE_SUDO_USER
- env:ANSIBLE_BECOME_USER
- var: ansible_sudo_user
- var: ansible_become_user
How does Ansible Sudo work?
To use become methods, we can mention the specific parameters in playbook, in static inventory files or in imported files.
Syntax:
The syntax will be like below when we use it is playbook:
---
-tasks:
....
....
-name: Run a command as nobody command: somecommand become: yes
become_method: su become_user: nobody become_flags: '-s /bin/sh'
....
....
Similarly, the become variables can be mentioned in inventory files to defined sudo user. This can be done against a group of hosts or a special host. That way it becomes easy to work on a special host or host group.
Examples of Ansible Sudo
Given below are the examples mentioned:
Here we have an Ansible control server named ansible-controller and two remotes hosts named host-one and host-two. We will create playbooks and run Ansible commands on ansible-controller node and see the results on remote hosts.
Example #1
In this example, we have a playbook with content like below, here we are running this playbook with root user, but as we mentioned become parameters in the playbook. We are trying to run command as ec2-user. In the output we will see that command ran as ec2-user.
Please note, this user must exist on target machine, else playbook will fail.
Code:
---
-hosts: all
become:
yes
become_user: ec2-user
become_method:
sudo tasks:
-name: here we are chekcing the user id by which command is shell: id
register: id_var
-debug
var: id_var['stdout_lines']
Running this playbook like below:
ansible-playbook ansible_sudo.yaml
Output:
Here we can see in the output that id of ec2-user was shown though we ran this playbook as root user. As we switched from root to non-root user it did not ask for password.
Example #2
In this example, we have a playbook with content like below, here we are restarting a service using Ansible service module with user ec2-user but this user have entries in sudoer file of target machines, so we will not be required to enter password for root user.
Code:
---
-hosts:
all
tasks:
-name: Here we are starting the httpd
service.service:
name: httpd
state: restarted
Running this playbook like below with non-root user named ec2-user:
ansible-playbook ansible_sudo_root.yaml
We get the output like below, where it failed, as the user do not have permission to do the task.
Output:
Now if we update the playbook like below and mention become: yes in it. We are giving this user, the sudo power.
Code:
---
-hosts:
all
tasks:
-name: Here we are starting the httpd
service.service:
name: httpd
state: restarted
become: yes
Now running this playbook like below, we can see that it ran successfully.
ansible-playbook ansible_sudo_root.yaml
Output:
Example #3
In this example, we have a playbook with content like below, when we are running this playbook as ec2-user with become parameters, then actually we are running simple command on remote target machines as another non-root user named testuser after switching to it. Also this user ec2-user have entries in sudoer file of target machines, so we will not be required to enter password for testuser user to switch to it.
Code:
---
-hosts: all
gather_facts:
no tasks:
-name: Here we are switching to another user named testuser to run a command shell: whoami
become: yes
become_user:
testuser register:
var_output
-debug:
var: var_output.stdout_lines
Running this playbook like below:
ansible-playbook ansible_sudo_non-root.yaml
We get the output like below where we can see that user identified is the testuser, as we used become parameter to run the command as testuser.
Output:
Example #4
In this example, we have a playbook with content like below. Here we are running a simple command from a user named testuser, who do not have any sudo entry in sudoer. We will run the playbook with passing option to ask for password of become user which is ec2-user.
Code:
---
-hosts: all
gather_facts:
no tasks:
-name: Here we are switching to another non-root user to run a command shell: whoami
become: yes
become_user: ec2-user register:
var_output
become_method:
su
-debug:
var: var_output.stdout_lines
Running this playbook like below, note the –ask-become-pass option used in command.
ansible-playbook ansible_sudo_nonroot_to_nonroot.yaml --ask-become-pass
Output:
Here we can see that the command ran as ec2-user, because we used become parameter to switch to it and passed password on asking by –ask-become-pass option.
Conclusion
As we saw in this article, using become is very important aspect of using Ansible in your environment, as on target remote servers, we always have some restrictions on non-root users. To overcome this, we need escalated privileges for time being, that is only possible by sudo methods.
Recommended Articles
This is a guide to Ansible Sudo. Here we discuss what is ansible sudo, how does ansible sudo work, and examples respectively. You may also have a look at the following articles to learn more –