Open-Source Wikis

/

Ansible

/

Plugins

/

Connection plugins

ansible/ansible

Connection plugins

The transport layer. A connection plugin's job is to put files onto a remote target, run commands, and read their output. ansible-core ships four: local, ssh, winrm, and psrp. Network-device connections (network_cli, httpapi, netconf) live in collections.

Files

lib/ansible/plugins/connection/
├── __init__.py        # ConnectionBase — abstract base class
├── local.py           # Run on the controller itself (no transport)
├── ssh.py             # OpenSSH-based — the default
├── winrm.py           # Microsoft Windows Remote Management
└── psrp.py            # PowerShell Remoting Protocol over WinRM/SSH

ConnectionBase

lib/ansible/plugins/connection/__init__.py:ConnectionBase defines the contract every connection plugin must implement:

Method Purpose
_connect() Establish the connection (lazy — first call only)
exec_command(cmd, in_data=None, sudoable=True) Run a command, return (rc, stdout, stderr)
put_file(in_path, out_path) Push a file from the controller to the target
fetch_file(in_path, out_path) Pull a file from the target to the controller
close() Tear down the connection
reset() Force a fresh connection on next operation

Plus transport, become_methods, has_pipelining, connection_type, and option declarations through the standard plugin DOCUMENTATION block.

The base also supplies _make_tmp_path(), password-prompt handling, and the become integration point (a connection runs the command via the appropriate BecomeBase plugin to wrap with sudo/su/runas).

ssh — the workhorse

lib/ansible/plugins/connection/ssh.py is 1,625 lines, the second-longest connection in the tree. It wraps OpenSSH (/usr/bin/ssh, /usr/bin/sftp, /usr/bin/scp) with extensive logic for:

  • ControlMaster / ControlPersist. Multiplexed connections so subsequent ops to the same host reuse the existing session.
  • sshpass / askpass. Password authentication via the sshpass utility, or via a controller-side _ssh_askpass.py helper triggered by SSH_ASKPASS.
  • Host key checking with the host_key_checking config and the ~/.ansible/cp control-path directory.
  • SSH retries with backoff via ANSIBLE_SSH_RETRIES.
  • Pipelining. When ANSIBLE_PIPELINING=true, the AnsiBallZ wrapper is piped to python3 over the same SSH session that runs exec_command — avoiding a separate put_file.
  • Multiple file-transfer methods. sftp, scp, piped, or smart (auto-detect based on what works).
  • Become wrapping. The connection wraps the command with the configured become plugin's prefix (sudo -H -S -p ... -u user /bin/sh -c '...' for sudo).

Configuration knobs (the partial list):

  • ANSIBLE_HOST_KEY_CHECKING
  • ANSIBLE_SSH_RETRIES
  • ANSIBLE_SSH_CONTROL_PATH, ANSIBLE_SSH_CONTROL_PATH_DIR
  • ANSIBLE_SSH_ARGS, ANSIBLE_SSH_COMMON_ARGS, ANSIBLE_SSH_EXTRA_ARGS
  • ANSIBLE_SSH_TRANSFER_METHOD
  • ANSIBLE_SSH_PIPELINING

There are dozens of edge cases handled in this file — the project has been wrapping ssh since 2012, and SSH supports a lot of authentication and transport variants.

local

lib/ansible/plugins/connection/local.py is the simplest. exec_command shells out via subprocess.Popen with the controller's environment. put_file and fetch_file are file copies. Used for delegate_to: localhost, connection: local, and most of ansible-pull (which clones a repo and runs locally).

The local connection still goes through the become plugin if the user requested escalation — sudo -u target_user ansible-test-suite is a real, frequent use case.

winrm

lib/ansible/plugins/connection/winrm.py uses pywinrm (an optional dependency) to talk WinRM HTTP/HTTPS to Windows targets. Authentication options: NTLM, Kerberos, CredSSP, certificate. Fed through the configured Windows-side PowerShell wrapper from lib/ansible/executor/powershell/ to run modules.

Recent maintenance activity (4 commits in 90 days) indicates this is still actively supported.

psrp

lib/ansible/plugins/connection/psrp.py is the modern replacement for winrm. It uses the PowerShell Remoting Protocol directly via pypsrp, supporting both WinRM and SSH transports underneath. PSRP has better support for streaming output, large file transfers, and named pipes; new Windows automation usually targets psrp rather than winrm.

Become wrapping

When a task says become: true, the connection plugin wraps exec_command with the configured become plugin's prefix:

# Inside ConnectionBase.exec_command
if sudoable and self.become:
    cmd = self.become.build_become_command(cmd, shell)

BecomeBase.build_become_command for sudo produces something like:

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

with a known-pattern prompt ([sudo via ansible, key=...] password:) so the connection knows to scrape stdin for password input. See Become for details on the three become plugins.

Pipelining

sequenceDiagram
    participant Action
    participant Connection
    participant Remote
    Note over Action,Remote: Without pipelining
    Action->>Connection: put_file(wrapper)
    Connection->>Remote: SFTP wrapper
    Action->>Connection: exec_command(python3 wrapper)
    Connection->>Remote: SSH exec
    Remote->>Connection: stdout
    Note over Action,Remote: With pipelining
    Action->>Connection: exec_command(python3 -, in_data=wrapper)
    Connection->>Remote: SSH exec, stdin=wrapper
    Remote->>Connection: stdout

Pipelining is only safe if the become method doesn't require a TTY (sudo with requiretty breaks it). Disabled by default; set ANSIBLE_PIPELINING=true to enable.

Connection plugin lifecycle

A connection is created lazily by TaskExecutor when needed and shared across tasks via ControlPersist (for ssh) or kept open in-process (for local). On meta: reset_connection, the connection's reset() method is called and a fresh connection is established for the next task.

Connection options can be set per-host via inventory (ansible_host, ansible_user, ansible_port, ansible_ssh_private_key_file, ...) and per-play via vars and connection:/port:/remote_user: keywords.

Integration points

  • Imported by: lib/ansible/executor/task_executor.py via connection_loader.get.
  • Loaded eagerly at TQM init for caching: connection_loader.all(class_only=True).
  • Imports: lib/ansible/plugins/become/ (via the wrapping mechanism), the optional Windows libs (pywinrm, pypsrp).

Entry points for modification

  • Add a connection in a collection. Subclass ConnectionBase under <collection>/plugins/connection/<name>.py. Implement the five abstract methods. Declare options in DOCUMENTATION.
  • SSH bug fix — typically lib/ansible/plugins/connection/ssh.py. Be ready: this file is dense and historic. Read existing tests in test/units/plugins/connection/test_ssh.py first.
  • A new transport on Windows — likely a collection-side plugin; ansible-core ships only the two main Windows transports.

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

Connection plugins – Ansible wiki | Factory