Skip to main content
The SSH connector is pyinfra’s default connector for connecting to remote hosts using SSH. It uses Paramiko for SSH communication and supports various authentication methods.

Overview

The SSH connector is used by default for all hosts unless another connector is specified:
# These are identical
pyinfra my-host.net ...
pyinfra @ssh/my-host.net ...

Connection Data

Configure SSH connection using inventory data:
ssh_hostname
str
SSH hostname or IP address to connect to.
ssh_port
int
default:22
SSH port number.
ssh_user
str
SSH username for authentication.
ssh_password
str
SSH password for authentication (not recommended, use keys instead).
ssh_key
str
Path to SSH private key file.
ssh_key_password
str
Password for encrypted SSH private key.
ssh_allow_agent
bool
default:true
Whether to use SSH agent for authentication.
ssh_look_for_keys
bool
default:true
Whether to search for SSH keys in standard locations.
ssh_forward_agent
bool
default:false
Whether to enable SSH agent forwarding.
ssh_config_file
str
Path to SSH config file.
ssh_known_hosts_file
str
Path to SSH known_hosts file.
ssh_strict_host_key_checking
str
default:"accept-new"
Host key checking mode: accept-new, yes, or no.
ssh_paramiko_connect_kwargs
dict
Additional keyword arguments passed to Paramiko’s SSHClient.connect().
ssh_connect_retries
int
default:0
Number of connection retry attempts.
ssh_connect_retry_min_delay
float
Minimum delay between retries (seconds).
ssh_connect_retry_max_delay
float
Maximum delay between retries (seconds).
ssh_file_transfer_protocol
str
default:"sftp"
Protocol for file transfers: sftp or scp.

Inventory Examples

Single Host with SSH Forward Agent

# inventory.py
hosts = [
    ("my-host.net", {"ssh_forward_agent": True}),
]

Multiple Hosts with Shared SSH User

# inventory.py
hosts = (
    ["host1.example.com", "host2.example.com"],
    {"ssh_user": "deploy"},
)

Multiple Hosts with Different Users

# inventory.py
hosts = [
    ("host1.example.com", {"ssh_user": "ubuntu"}),
    ("host2.example.com", {"ssh_user": "admin"}),
    ("host3.example.com", {"ssh_user": "centos"}),
]

Using SSH Config File

# inventory.py
hosts = [
    ("host1", {"ssh_config_file": "~/.ssh/config"}),
]
With ~/.ssh/config:
Host host1
    HostName 192.168.1.100
    User deploy
    Port 2222
    IdentityFile ~/.ssh/deploy_key

Custom SSH Port and Key

# inventory.py
hosts = [
    ("my-host.net", {
        "ssh_port": 2222,
        "ssh_user": "deploy",
        "ssh_key": "~/.ssh/deploy_key",
    }),
]

Connection Retries

# inventory.py
hosts = [
    ("unreliable-host.net", {
        "ssh_connect_retries": 3,
        "ssh_connect_retry_min_delay": 1.0,
        "ssh_connect_retry_max_delay": 5.0,
    }),
]

Using SCP Instead of SFTP

# inventory.py
hosts = [
    ("legacy-host.net", {
        "ssh_file_transfer_protocol": "scp",
    }),
]

Authentication Methods

Use SSH agent for secure key management:
# Start SSH agent and add key
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_rsa

# Run pyinfra (will use agent)
pyinfra inventory.py deploy.py
# inventory.py - agent is used by default
hosts = [
    ("host.example.com", {"ssh_user": "deploy"}),
]

SSH Key File

Specify a private key file:
# inventory.py
hosts = [
    ("host.example.com", {
        "ssh_user": "deploy",
        "ssh_key": "~/.ssh/deploy_key",
    }),
]

Encrypted SSH Key

# inventory.py
hosts = [
    ("host.example.com", {
        "ssh_user": "deploy",
        "ssh_key": "~/.ssh/encrypted_key",
        "ssh_key_password": "key-password",
    }),
]
# inventory.py
hosts = [
    ("host.example.com", {
        "ssh_user": "deploy",
        "ssh_password": "password",
    }),
]
Password authentication is not recommended for production use. Use SSH keys with SSH agent instead.

Host Key Verification

Control how SSH host keys are verified:

Accept New Keys (Default)

# inventory.py
hosts = [
    ("host.example.com", {
        "ssh_strict_host_key_checking": "accept-new",
    }),
]
Accepts new hosts but verifies known hosts.

Strict Checking

# inventory.py
hosts = [
    ("host.example.com", {
        "ssh_strict_host_key_checking": "yes",
    }),
]
Rejects unknown hosts.
# inventory.py
hosts = [
    ("host.example.com", {
        "ssh_strict_host_key_checking": "no",
    }),
]
Disabling host key checking makes you vulnerable to man-in-the-middle attacks. Only use in trusted environments.

Agent Forwarding

Enable SSH agent forwarding to use local SSH keys on remote hosts:
# inventory.py
hosts = [
    ("bastion.example.com", {
        "ssh_forward_agent": True,
    }),
]
Useful for:
  • Accessing Git repositories from remote hosts
  • SSHing from one remote host to another
  • Using local credentials on remote systems

Advanced Configuration

Paramiko Connection Options

Pass additional options to Paramiko:
# inventory.py
hosts = [
    ("host.example.com", {
        "ssh_paramiko_connect_kwargs": {
            "timeout": 30,
            "banner_timeout": 60,
            "auth_timeout": 30,
            "compress": True,
        },
    }),
]

Custom Known Hosts File

# inventory.py
hosts = [
    ("host.example.com", {
        "ssh_known_hosts_file": "/custom/path/known_hosts",
    }),
]

Complete Example

Here’s a comprehensive inventory using SSH connector:
# inventory.py
from pyinfra import Inventory

inventory = Inventory(
    # Production servers
    ([
        ("web1.example.com", {
            "ssh_user": "ubuntu",
            "ssh_forward_agent": True,
        }),
        ("web2.example.com", {
            "ssh_user": "ubuntu",
            "ssh_forward_agent": True,
        }),
        ("db1.example.com", {
            "ssh_user": "postgres",
            "ssh_port": 2222,
            "ssh_key": "~/.ssh/db_key",
        }),
    ], {
        # Global SSH settings
        "ssh_connect_retries": 3,
        "ssh_strict_host_key_checking": "yes",
    }),
    
    # Web servers group
    webservers=([
        "web1.example.com",
        "web2.example.com",
    ], {}),
    
    # Database servers group
    databases=([
        "db1.example.com",
    ], {}),
)

File Transfer Methods

The SSH connector supports two file transfer protocols:

SFTP (Default)

Recommended for most use cases:
  • More reliable
  • Better error handling
  • Works with more SSH server configurations

SCP

Useful for legacy systems:
  • Compatible with older SSH servers
  • Simpler protocol
# inventory.py
hosts = [
    ("legacy-host", {
        "ssh_file_transfer_protocol": "scp",
    }),
]

Troubleshooting

Connection Timeouts

Increase timeout and enable retries:
hosts = [
    ("slow-host.example.com", {
        "ssh_connect_retries": 5,
        "ssh_connect_retry_max_delay": 10.0,
        "ssh_paramiko_connect_kwargs": {
            "timeout": 60,
        },
    }),
]

Authentication Failures

Enable verbose logging:
pyinfra -vv inventory.py deploy.py
Check:
  1. SSH key permissions (chmod 600 ~/.ssh/id_rsa)
  2. SSH agent is running (ssh-add -l)
  3. User has correct permissions on remote host
  4. SSH service is running on remote host

Host Key Verification Failed

Update known_hosts:
ssh-keygen -R hostname
ssh hostname  # Accept new key

Source Reference

Location: src/pyinfra/connectors/ssh.py:119

Key Methods

  • connect() - Establish SSH connection
  • disconnect() - Close SSH connection
  • run_shell_command() - Execute commands via SSH
  • put_file() - Upload files via SFTP/SCP
  • get_file() - Download files via SFTP/SCP

Build docs developers (and LLMs) love