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/SSHConnectionBase
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
sshpassutility, or via a controller-side_ssh_askpass.pyhelper triggered bySSH_ASKPASS. - Host key checking with the host_key_checking config and the
~/.ansible/cpcontrol-path directory. - SSH retries with backoff via
ANSIBLE_SSH_RETRIES. - Pipelining. When
ANSIBLE_PIPELINING=true, the AnsiBallZ wrapper is piped topython3over the same SSH session that runsexec_command— avoiding a separateput_file. - Multiple file-transfer methods.
sftp,scp,piped, orsmart(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_CHECKINGANSIBLE_SSH_RETRIESANSIBLE_SSH_CONTROL_PATH,ANSIBLE_SSH_CONTROL_PATH_DIRANSIBLE_SSH_ARGS,ANSIBLE_SSH_COMMON_ARGS,ANSIBLE_SSH_EXTRA_ARGSANSIBLE_SSH_TRANSFER_METHODANSIBLE_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: stdoutPipelining 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.pyviaconnection_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
ConnectionBaseunder<collection>/plugins/connection/<name>.py. Implement the five abstract methods. Declare options inDOCUMENTATION. - SSH bug fix — typically
lib/ansible/plugins/connection/ssh.py. Be ready: this file is dense and historic. Read existing tests intest/units/plugins/connection/test_ssh.pyfirst. - A new transport on Windows — likely a collection-side plugin; ansible-core ships only the two main Windows transports.
Cross-links
- Module execution and AnsiBallZ — what gets transported.
- Become — the wrapping the connection applies.
- Action — what calls
connection.exec_command. - Plugins → Shell and strategy — the shell plugin that does command quoting before connection sees it.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.