The Practitioner’s Guide to Scaling Infrastructure as Code

➡️ Download Now

Ansible

How to Use Ansible Become Keyword to Secure Playbooks

ansible become

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

  1. What is become in Ansible?
  2. How to use become in Ansible playbooks
  3. How to use become on the entire Ansible playbook
  4. Using become_user and become_method for advanced purposes
  5. How to use ansible-playbook command with become playbooks
  6. How to use become with ad-hoc Ansible commands
  7. Best practices using Ansible become
  8. Common mistakes using Ansible become and how to avoid them

What is become in Ansible?

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).

How to use become in Ansible playbooks

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.

1. Using become in Ansible Tasks

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

2. Using become to create a directory in a directory that requires escalated privileges

- 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

3. Using become to create a user or group

- 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

4. Using become with the command module

- name: Update the package cache
  command:
    cmd: apt-get update
  become: true

- name: Reload the systemd daemon
  command:
    cmd: systemctl daemon-reload
  become: true

5. Using become with the service module

- name: Restart nginx service
  service:
    name: nginx
    state: restarted
  become: true

- name: Stop Apache service
  service:
    name: httpd
    state: stopped
  become: true

6. Use become in a conditional task

- name: Restart the service if configuration was changed
  service:
    name: myservice
    state: restarted
  become: true
  when: my_config_changed

How to use become on the entire Ansible Playbook

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

Using become_user and become_method for advanced purposes

The become_user and become_method parameters give you finer control over the way you escalate privileges in your playbook. 

Using Ansible become_user parameter

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

Using the Ansible become_method parameter

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

What is the difference between become and become_user in Ansible?

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.

How to use ansible-playbook command with become playbooks

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

How to use become with ad-hoc Ansible commands

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

Best practices using Ansible become

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 add become 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 use become throughout your playbooks is beneficial for spreading awareness. 
  • Minimize the use of become in playbooks: Always try to figure out another option before introducing become 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, use become_method, preventing you from always using root to grant permissions for that task to run

Common mistakes using become and how to avoid them

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. 
  • Perform a playbook run on a non-production environment to find out what tasks require elevated privileges
  • Perform ad-hoc commands with the module against a test environment before running from a playbook
  • If most tasks in the playbook require elevated privileges, you can set the become: true on the play level
  • Utilize a consistent convention or checklist for noting Ansible tasks that require 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.
  • Be mindful of your playbook tasks and review any task that uses become parameter carefully and play out the situation
  • Run playbook against a dev environment that has similar configurations and user accounts set up
  • Perform ad-hoc commands against the particular dev environment with configurations and user accounts set up
  • Group specific tasks that are used by the same become_user into one playbook to avoid inconsistency
Hardcoding sudo password in playbooks This is a security risk and can get flagged under auditing, but it still happens over testing periods.
  • Use the --ask-become-pass flag across your ansible-playbook command run to always prompt for passwords
  • Utilize an encrypted password file and pass in the file through --become-password-file flag in your ansible-playbook run
  • Utilize Ansible Vaults to encrypt passwords and any other sensitive data
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.
  • Review your become_users listed on the Ansible Playbook tasks and ensure all of them are added to the sudoers file
  • Create an automated workflow that adds any new service account or application user to the sudoers file
  • Set NOPASSWD: ALL to allow all users to sudo. Not recommended since it can pose as a security risk
  • Test each Ansible task manually or by ad-hoc commands to ensure there are no roadblocks
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.
  • Properly test out the method on the system you are running your playbook against and ensure the method is configured and being used
  • Create a script to perform a test run against all systems in the inventory file to ensure the method is set up
  • If most systems support one method, set that as your default method in the ansible.cfg file

How can Spacelift help you with Ansible projects?

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:

ansible product video thumbnail

Key points

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.

Learn more

Elevate Your Ansible Automation

Strengthen control, enhance inventory visibility,

and unify your infrastructure pipeline.

Learn more
ansible bottom overlay