Ansible is a popular open-source tool for managing infrastructure, handling tasks like deployment, orchestration, cloud provisioning, and ensuring security across remote hosts. It uses an agentless, push-based model for seamless communication and consistent management.
Tasks are written in YAML and stored in playbooks, which can use built-in or custom modules to execute commands or manage resources. When elevated privileges are needed, Ansible uses the become
keyword to securely activate privilege escalation on remote hosts.
In this article, we will cover different ways of using the Ansible become
keyword, the flags we need to pass into the ansible-playbook command line to run playbooks that use the become
keyword, and review a few advanced cases by using the become_user
and become_method
.
- What is
become
in Ansible? - How to use
become
in Ansible playbooks - How to use become on the entire Ansible playbook
- Using
become_user
andbecome_method
for advanced purposes - How to use
ansible-playbook
command withbecome
playbooks - How to use
become
with ad-hoc Ansible commands - Best practices using Ansible
become
- Common mistakes using Ansible
become
and how to avoid them
In Linux, you typically use sudo
to elevate your privileges to the root user when installing applications, performing administrative tasks like modifying critical files, or interacting with system components that your regular account lacks permission to access.
In Ansible, the become
method allows you to elevate privileges for specific tasks or an entire playbook, enabling the use of sudo
without hardcoding credentials. By leveraging become
, you reduce the need to use sudo
in the Ansible command module, increase flexibility by automating privilege escalation, and ensure consistency across your playbooks.
Tasks requiring elevated permissions are clearly defined, which improves security and maintainability. Additionally, become supports switching to the root user and transitioning to other administrator accounts using the become_user
parameter. We’ll explore this feature in more detail later.
Overall, become
provides a structured and secure way to manage privilege escalation in Ansible. It streamlines administrative tasks while adhering to the principle of least privilege, thereby enhancing your system’s security posture.
In Windows, privilege escalation typically involves using runas
. If you’re working across environments that use different escalation methods — such as pfexec
, doas
, pbrun
, dzdo
, ksu
, or machinectl
— you may need to update the ansible.cfg
file to specify the default privileged user and escalation method.
For mixed environments (e.g., primarily Linux with some Windows tasks), you can use the become_user
and become_method
parameters to define the user and method for specific tasks without altering the global default settings. We’ll cover this approach in more detail later.
For our examples, we’ll focus on Linux systems and use the default user (root
) and method (sudo
).
There are two ways to use Ansible become
in your playbooks: You can either use it in your individual Ansible tasks or at the top level of the playbook and apply it across all of your tasks in that specific playbook.
However, it’s very important to know what those individual tasks will do to avoid any unnecessary changes across your systems. It’s best practice to apply the least privileges across all of your tasks to ensure high security unless sudo
is a must and needed to run that specific task.
Let’s see some examples of applying become
to our individual tasks and the different Ansible modules, we can use the become
parameter with.
When using become
with a task, you must note that the become
parameter is not part of the Ansible module you intend to use; instead, it is an Ansible-wide parameter that allows you to use it with different Ansible modules.
Using become
to install an application
---
- hosts: web
tasks:
- name: Install nginx
apt:
name: nginx
state: present
become: true
- name: Install httpd
yum:
name: httpd
state: present
become: true
Using become
to copy files over to directories that require escalated privileges
---
- hosts: all
tasks:
- name: Deploy web app to Tomcat
copy:
src: /path/myapp.war
dest: /opt/tomcat/webapps/myapp.war
mode: '0755'
become: true
- name: Copy systemd service file for your app
copy:
src: yourapp.service
dest: /etc/systemd/system/yourapp.service
mode: '0755'
become: true
- name: Update PostgreSQL configuration
copy:
src: postgresql.conf
dest: /etc/postgresql/14/main/postgresql.conf
mode: '0755'
become: true
- name: Create a directory in /opt/myapp with elevated privileges
file:
path: /opt/myapp
state: directory
mode: '0755'
become: true
- name: Create a directory for Tomcat logs
file:
path: /var/log/tomcat
state: directory
mode: '0755'
owner: tomcat
group: tomcat
become: true
- name: Create a new user
user:
name: johndoe
state: present
groups: sudo
become: true
- name: Create a developers group
group:
name: developers
state: present
become: true
- name: Update the package cache
command:
cmd: apt-get update
become: true
- name: Reload the systemd daemon
command:
cmd: systemctl daemon-reload
become: true
- name: Restart nginx service
service:
name: nginx
state: restarted
become: true
- name: Stop Apache service
service:
name: httpd
state: stopped
become: true
- name: Restart the service if configuration was changed
service:
name: myservice
state: restarted
become: true
when: my_config_changed
If all the tasks in your playbook require elevated privileges, you can apply become
on the top level of the playbook. This will trigger become
to run on every task, which can be useful in many situations where you don’t have to specify become
on each individual task.
The following playbook covers some basic tasks you would perform when installing and configuring a Tomcat application that requires elevated permissions:
---
- name: Tomcat Install
hosts: all
become: true
tasks:
- name: Update the package repository
command:
cmd: apt-get update
- name: Install Java
apt:
name: openjdk-11-jdk
state: present
- name: Create Tomcat group
group:
name: tomcat
state: present
- name: Create Tomcat user
user:
name: tomcat
group: tomcat
home: /opt/tomcat
shell: /bin/false
state: present
- name: Download Tomcat archive
get_url:
url: https://downloads.apache.org/tomcat/tomcat-11/v11.0.0/bin/apache-tomcat-11.0.0.tar.gz
dest: /tmp/apache-tomcat-11.0.0.tar.gz
- name: Create Tomcat installation directory
file:
path: /opt/tomcat
state: directory
mode: '0755'
- name: Extract Tomcat archive
unarchive:
src: /tmp/apache-tomcat-11.0.0.tar.gz
dest: /opt/tomcat
remote_src: yes
creates: /opt/tomcat/apache-tomcat-11.0.0
The become_user
and become_method
parameters give you finer control over the way you escalate privileges in your playbook.
By default, the become
parameter uses the root
user during its privilege escalation process. However, the become_user
parameter lets you specify a different user to switch to when using become
. This is similar to running su - useraccount
in Linux to execute a command as another user.
This feature is particularly useful when you need to run a task under a service account or application user with specific permissions for a service or application. By switching to that user, you ensure the task or set of tasks is executed with the appropriate permissions.
To use the become_user
parameter, you must also set the become
parameter to true
. If become
is not enabled, attempting to use become_user
will result in an error.
Here are some examples and scenarios of using the become_user
parameter in Ansible Playbook tasks:
This is a simple example of using a service user account to restart a task:
- name: Manage NGINX as www-data user
service:
name: nginx
state: restarted
become: true
become_user: web_user
In Tomcat, the application is run under a specific Tomcat user account that gets assigned across all directories and files under /opt/tomcat
, in this situation, it is best to switch to the tomcat user
to avoid permission issues:
- name: Deploy application files as the tomcat user
copy:
src: /path/to/app.war
dest: /opt/tomcat/webapps/app.war
become: true
become_user: tomcat
Postgres SQL commands are meant to be run under the user account that has specific database privileges, this would allow you to switch to the Postgres user account and run the psql
command under it:
- name: Create a PostgreSQL database as the postgres user
command:
cmd: psql -c "CREATE DATABASE mydb1;"
become: true
become_user: postgres
Usually with GIT, you use a specific user account when cloning into a specific directory. In this case, you would ensure proper permissions are distributed under that account for all files:
- name: Clone a Git repository as the deploy user
git:
repo: 'https://github.com/myappfolder/myapp.git'
dest: ~/myapp
become: true
become_user: myuseraccount
Running tasks that involve Kubernetes will require you to have administrator privileges on the cluster, therefore, you can use a kubernetes-admin account as your become-user
when triggering kubectl
tasks.
- name: Apply Kubernetes configuration as the kubernetes-admin user
command:
cmd: kubectl apply -f ~/k8s/deployment.yaml
become: true
become_user: kubernetes-admin
Read more: How to Manage Kubernetes with Ansible
The become_method
parameter overrides the default privilege escalation method specified in ansible.cfg
(typically sudo
) and allows you to select one of the available become plugins, such as sudo
, su
, doas
, runas
, etc. This parameter works in conjunction with become
and become_user
.
First, you need to enable privilege escalation by setting become
, and second, become_method
requires a specific user to be defined using become_user
, as it determines the user context for the specified escalation method. By default, the user in ansible.cfg
is root
, unless you explicitly configure a different user or use sudo
as the escalation method.
Here are some examples of how to use the become_method parameter and how it differs from the become and become_user parameters:
If you have hosts in your environment running Windows, you can combine the become_user
and become_method
parameters to execute a PowerShell command as an administrator:
- name: Run a command as a different user using runas on Windows
ansible.windows.win_command:
command: "powershell.exe -Command 'Restart-Service -Name W32Time'"
become: true
become_user: Administrator
become_method: runas
If ansible.cfg has been modified to include become_user
and become_method
as another privileged user and escalation method, we can specify root
and sudo
on the task itself:
- name: Install a NGINX as root using sudo
apt:
name: nginx
state: present
become: true
become_user: root
become_method: sudo
BeyondTrust offers a Privileged Access Management (PAM) solution that enables users to execute commands with elevated privileges according to a defined policy. This solution is particularly valuable for organizations with stringent security requirements.
BeyondTrust leverages pbrun
to centrally manage and control privileged access. In the example below, we use pbrun
as our become_method
and specify a pre-configured user account, which has the necessary permissions to execute commands on your systems, as our become_user
:
- name: Run a privileged command using pbrun
command:
cmd: /path/to/script.sh
become: true
become_user: pbrun_security_user
become_method: pbrun
The Ansible become
parameter enables privilege escalation, allowing tasks to run with elevated permissions (defaulting to the root
user), whereas become_user
specifies the user account Ansible should switch to after privilege escalation, overriding the default (root
). They are often used together to enable and customize privilege escalation for specific tasks.
Now that we’ve covered how to apply become
, become_user
, and become_method
in your playbooks, let’s move on to running an ansible-playbook
command with these parameters in place.
The ansible-playbook
command executes Ansible playbooks. If we attempt to run a playbook that uses the become
parameter without including the necessary flags in the command line, the playbook execution will fail.
Playbooks that use any of the become
parameters must include the --become
flag. If your environment is set up for passwordless sudo, you can simply use the --become
flag on its own.
However, if passwordless sudo is not configured, you’ll need to include either the --ask-become-password
flag or specify a become-password-file
when running the ansible-playbook
command. This adds an extra layer of security and ensures the proper credentials are provided to execute the administrative tasks in your playbooks.
In an ideal scenario where passwordless sudo is configured across your environment, running a playbook that uses the become
parameter is straightforward. You only need to include the --become
flag with your ansible-playbook
command:
ansible-playbook playbook.yml --become
If you do not have a passwordless setup, you have two options. You can either get prompted to enter your sudo/become_user password by using the —ask-become-pass
flag as the following example:
ansible-playbook playbook.yml --become --ask-become-pass
You can also pass in a file that contains your sudo/become_user password by using the --become-password-file
flag, which can be useful if you have an automated workflow in your CI/CD pipeline.
There are many ways to lock down this file in Linux and utilize a bash script along with Ansible Vault to encrypt/decrypt it during the playbook run, but we will not cover that for the purpose of this article.
Here is a simple way of passing in a file that contains your sudo/become_user password:
ansible-playbook my_playbook.yml --become --become-password-file=/path/to/become_password.txt
Ad-hoc commands in Ansible allow for quick, one-off tasks without the need to create a full playbook. The become keyword can be included in these ad-hoc commands in the same way they elevated privileges in the playbooks.
In a passwordless setup, you can quickly run the following to restart Apache service on web servers with the root user under the sudo method:
ansible myservers -m service -a "name=httpd state=restarted" --become
If you have a non-passwordless setup, you can run the following command to get prompted for a sudo/become_user password:
ansible myservers -m service -a "name=nginx state=restarted" --become --ask-become-pass
To pass in a file with your sudo/become_user password, you can run the following:
ansible myservers -m service -a "name=nginx state=restarted" --become --become-password-file=/path/to/the/become_password.txt
If we want to specify a become_user
, such as a nginx_service_account
to kick off a service restart command, we can run the following:
ansible myservers -m command -a "systemctl restart nginx" --become --become-user=nginx_service_account
Now we can use both become_user
and become_method
to specify a privileged user and escalation method with an ad-hoc command:
ansible myserversl -m shell -a "whoami" --become --become-method=su --become-user=root
Some of the best practices we should follow when using Ansible become
across our playbooks and tasks to ensure you maintain high security and efficiency include:
- Avoid applying
become
to the entire playbook: This is only necessary when most tasks in your playbook require elevated privileges; it helps avoid repetition across your code. - Do not blindly use
become
in your playbook tasks: Test the specific task in a non-production environment and validate that it requires elevated permissions to run. Do not blindly addbecome
to the task. - Apply conditionals to
become
tasks: This can prevent these elevated privileged tasks from always running. - Document the use of
become
tasks: Documenting and ensuring the entire team knows each time you usebecome
throughout your playbooks is beneficial for spreading awareness. - Minimize the use of
become
in playbooks: Always try to figure out another option before introducingbecome
in your playbooks and tasks. - Group together using Roles for tasks that require elevated privileges: To avoid losing track of them, set up a Role with all the tasks that require elevated privileges.
- Store secure credentials for
become_user
in an Ansible Vault. - Use
become_method
: Anytime a task requires a different escalation method, usebecome_method
, preventing you from always using root to grant permissions for that task to run
Here are some common mistakes users make when using Ansible and how to remediate and prevent them:
Mistake | Description | How to avoid |
Forgetting to add become parameter for Tasks: |
This is very common when installing applications, managing services, or modifying system files. It is possible to forget to add it or not know if a specific task requires elevated privileges. |
|
Not specifying the correct become_user |
Certain tasks are only configured to run under a specific non-root user, this is when become_user is very important to specify, and the playbook run will fail if not specified. |
|
Hardcoding sudo password in playbooks |
This is a security risk and can get flagged under auditing, but it still happens over testing periods. |
|
Misconfiguration passwordless configuration | There are many scenarios you might have forgotten to include the become_user into the sudoers file and that can fail your playbook run. |
|
Using incorrect become_method |
This can happen if you specified a become_user the system was not configured to support, such as pbrun or runas . |
|
Spacelift’s vibrant ecosystem and excellent GitOps flow can greatly assist you in managing and orchestrating Ansible. By introducing Spacelift on top of Ansible, you can then easily create custom workflows based on pull requests and apply any necessary compliance checks for your organization.
Another great advantage of using Spacelift is that you can manage different infrastructure tools like Ansible, Terraform, Pulumi, AWS CloudFormation, and even Kubernetes from the same place and combine their Stacks with building workflows across tools.
Our latest Ansible enhancements solve three of the biggest challenges engineers face when they are using Ansible:
- Having a centralized place in which you can run your playbooks
- Combining IaC with configuration management to create a single workflow
- Getting insights into what ran and where
Provisioning, configuring, governing, and even orchestrating your containers can be performed with a single workflow, separating the elements into smaller chunks to identify issues more easily.
If you want to learn more about using Spacelift with Ansible, check our documentation, read our Ansible guide, or book a demo with one of our engineers.
Would you like to see this in action – or just want a tl;dr? Check out this video I put together showing you Spacelift’s new Ansible functionality:
The become
keyword in Ansible playbooks is crucial for managing privilege escalation securely. It allows you to elevate permissions for tasks or entire plays, maintain security, and avoid issues like hardcoding credentials or overusing sudo
. Parameters like become_user
and become_method
let you customize privilege management for different systems, such as Linux or Windows.
Best practices include minimizing become
usage, documenting its implementation, and testing in non-production environments. Grouping privileged tasks into roles and using Ansible Vault for credentials can enhance security and maintainability. When used thoughtfully, become
bridges security and operations, enabling confident and secure automation.
Manage Ansible Better with Spacelift
Managing large-scale playbook execution is hard. Spacelift enables you to automate Ansible playbook execution with visibility and control over resources, and seamlessly link provisioning and configuration workflows.