Open-Source Wikis

/

Ansible

/

Plugins

/

Become plugins

ansible/ansible

Become plugins

Privilege escalation. ansible-core ships three become plugins: sudo, su, runas. Other escalation tools (pbrun, doas, dzdo, pmrun, etc.) live in collections — community.general has the bulk of them.

Files

lib/ansible/plugins/become/
├── __init__.py     # BecomeBase
├── runas.py        # Windows: invoke as a different user via psrp/winrm
├── su.py           # POSIX: su -
└── sudo.py         # POSIX: sudo

BecomeBase

lib/ansible/plugins/become/__init__.py:BecomeBase defines the protocol:

Attribute / method Purpose
name Plugin name (e.g., 'sudo')
prompt Regex (or list) the connection plugin should match for password input
fail Tuple of strings indicating failed escalation
missing Tuple of strings indicating the become tool isn't installed
build_become_command(cmd, shell) Produce the wrapped command line
check_password_prompt(b_output) Did this output line ask for a password?
check_success(b_output) Did escalation succeed?
check_incorrect_password(b_output) Was the password wrong?
check_missing_password(b_output) Did the prompt time out?

The connection plugin (ssh, winrm, etc.) calls become.build_become_command() to produce the prefix and inspects stdout/stderr against the four check_* predicates to decide whether to feed the become password.

sudo — the default

lib/ansible/plugins/become/sudo.py produces:

sudo -H -S -n  -u target_user /bin/sh -c '<the wrapped command>'

Or with a password:

sudo -H -S -p '[sudo via ansible, key=<random>] password:' -u target_user /bin/sh -c '<the wrapped command>'

The randomized prompt key lets the connection plugin recognize this exact prompt amid other output and feed the password.

Configuration knobs (declared in the plugin's DOCUMENTATION):

  • become_user — target username (default root).
  • become_pass — password.
  • become_exesudo binary (or alternate path).
  • become_flags — extra flags (default -H -S -n).

su

lib/ansible/plugins/become/su.py produces:

su  -l target_user -c "/bin/sh -c '<the wrapped command>'"

su is finickier than sudo because it always allocates a new shell environment. The plugin handles password-prompt scraping via configurable patterns (SU_PROMPT_LOCALIZATIONS).

runas

lib/ansible/plugins/become/runas.py is for Windows. Most Windows automation goes through psrp or winrm, which let you specify a target user directly. runas is the equivalent become for the case where the connection runs as one user but the task needs to run as another.

How escalation flows through the executor

sequenceDiagram
    participant TE as TaskExecutor
    participant CONN as Connection (ssh)
    participant BEC as Become (sudo)
    participant REMOTE as Remote target
    TE->>CONN: exec_command(cmd, sudoable=True)
    CONN->>BEC: build_become_command(cmd, shell)
    BEC-->>CONN: 'sudo -p ... -u user /bin/sh -c "..."'
    CONN->>REMOTE: ssh + the wrapped cmd
    REMOTE-->>CONN: '[sudo via ansible, key=abc] password:'
    CONN->>BEC: check_password_prompt(line)
    BEC-->>CONN: True
    CONN->>REMOTE: stdin: <password>
    REMOTE-->>CONN: stdout from the actual command
    CONN-->>TE: (rc, stdout, stderr)

The randomized prompt key is set up at TaskExecutor time and shared between the become plugin (which embeds it in the prompt argument) and the connection plugin (which scrapes for it). This avoids accidentally feeding the password to a sudo prompt the user typed inside the wrapped command.

Integration points

  • Imported by: lib/ansible/plugins/connection/__init__.py:ConnectionBase (via the configured become_loader.get).
  • Loaded eagerly at TQM init: become_loader.all(class_only=True).
  • Configured by: per-task become:/become_method:/become_user:/become_password: keywords; per-play and per-host vars; CLI flags --become, --become-user, --ask-become-pass.

Entry points for modification

  • Adding a become method — write a plugin in a collection extending BecomeBase. Implement build_become_command and the four check_* predicates. Declare options in DOCUMENTATION.
  • Sudo prompt regression — typically the prompt-detection regex needs updating. The regex lives in the plugin's prompt attribute.
  • Pipelining + become — make sure your new method doesn't require a TTY. Pipelining and requiretty are incompatible.

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Become plugins – Ansible wiki | Factory