Ansible SSH Configuration Prompt
Configure SSH for Ansible — keys, jump hosts, control persist, agent forwarding, known_hosts, parallel connections.
- Target user
- Ansible engineers managing SSH-based access
- Difficulty
- Intermediate
- Tools
- Claude, ChatGPT
The prompt
You are a senior automation engineer who has configured SSH for Ansible at scale — jump hosts, control persist, parallel connections, key rotation. I will provide: - The SSH topology (direct, bastion, multi-hop) - Current ansible config - Symptom (connection slow, fails through jump, keys expired) Your job: 1. **SSH basics**: - Default `ansible_connection: ssh` - Uses `~/.ssh/config` as base - Override via inventory vars 2. **For SSH keys**: - `ansible_ssh_private_key_file: ~/.ssh/ansible_key` - Or via ssh-agent - Per-host: `host_vars/<host>.yml` 3. **For jump host (bastion)**: - `ansible_ssh_common_args: '-o ProxyJump=bastion@bastion.example.com'` - Or `ProxyCommand` (older) - SSH config-based preferred 4. **For control persist**: - Reuse SSH connection across tasks - `ControlMaster=auto`, `ControlPersist=60s` (default) - Huge speedup 5. **For parallel**: - `forks: 100` in ansible.cfg - Limited by SSH connection capacity 6. **For host key checking**: - `host_key_checking: false` skips — security risk - Better: pre-populate known_hosts - Or use `ssh-keyscan` periodically 7. **For agent forwarding**: - `ssh-agent` runs locally - Forwards to remote - Useful for git clones from remote 8. **For pipelining**: - Faster module execution - Requires `requiretty` off in sudoers Mark DESTRUCTIVE: `host_key_checking: false` opens MITM, agent forwarding to untrusted hosts, weak keys (RSA-1024), SSH config without key restrictions. --- Topology: [DESCRIBE] Current config: [PASTE] Symptom: [DESCRIBE]
Why this prompt works
SSH config affects every Ansible run. This prompt walks setup.
How to use it
- Use SSH config.
- Enable control persist.
- Pre-populate known_hosts.
- Vault SSH keys.
Useful commands
# Test connection
ansible -i inventory all -m ping
ansible -i inventory web-01 -m ping -vvv
# Through jumphost
ssh -o ProxyJump=bastion@bastion.example.com web-01.example.com
# Update known_hosts
ssh-keyscan -H web-01.example.com >> ~/.ssh/known_hosts
# Test SSH config
ssh -F ~/.ssh/config -G web-01.example.com
Patterns
ansible.cfg
[defaults]
host_key_checking = True
forks = 50
timeout = 60
[ssh_connection]
ssh_args = -o ControlMaster=auto -o ControlPersist=60s -o PreferredAuthentications=publickey
pipelining = True
control_path_dir = ~/.ansible/cp
control_path = %(directory)s/%%h-%%r
Inventory with SSH details
all:
hosts:
web-01.internal:
ansible_host: 10.0.1.5
ansible_user: ansible
ansible_ssh_private_key_file: ~/.ssh/ansible_key
children:
behind_bastion:
hosts:
web-01.internal:
vars:
ansible_ssh_common_args: '-o ProxyJump=bastion@bastion.example.com'
SSH config approach (preferred)
# ~/.ssh/config
Host bastion.example.com
User ansible
IdentityFile ~/.ssh/ansible_bastion
ControlMaster auto
ControlPersist 60s
Host 10.0.*
User ansible
IdentityFile ~/.ssh/ansible_internal
ProxyJump bastion.example.com
ControlMaster auto
ControlPersist 60s
Then in inventory:
web-01.internal:
ansible_host: 10.0.1.5
Ansible uses your SSH config.
Multi-hop
Host jumpa
...
Host jumpb
ProxyJump jumpa
Host target
ProxyJump jumpb
Key rotation (Ansible-managed)
- hosts: all
tasks:
- name: Authorize new key
authorized_key:
user: ansible
key: "{{ new_ansible_key }}"
state: present
- name: Verify new key works
# Force run with new key, before removing old
- name: Remove old key
authorized_key:
user: ansible
key: "{{ old_ansible_key }}"
state: absent
Performance tuning
[ssh_connection]
ssh_args = -o ControlMaster=auto -o ControlPersist=600s
pipelining = True
[defaults]
forks = 100
gathering = smart
fact_caching = jsonfile
fact_caching_connection = /tmp/ansible_facts
fact_caching_timeout = 3600
Common findings this catches
- Slow connection → enable control persist.
- Connection fails through jump → SSH config issue.
The authenticity of host... can't be established→ known_hosts setup.- Key not accepted → check authorized_keys on target.
- Parallel runs cap at low N → SSH server MaxSessions.
ssh: Could not resolve hostname→ DNS / inventory.- Pipelining fails → requiretty in sudoers.
When to escalate
- SSH server configuration — networking team.
- Bastion HA design — strategic.
- Key rotation strategy — security.
Related prompts
-
Ansible Become / Privilege Escalation Prompt
Configure Ansible privilege escalation — become, become_user, become_method, restrict sudo, password handling.
-
Ansible Performance Tuning Prompt
Speed up Ansible playbooks — forks, pipelining, async, smart gathering, fact caching, mitogen.
-
SSH Security Audit Prompt
Audit sshd_config, authorized_keys, and SSH client config — flag insecure defaults, weak algorithms, missing controls.