Skip to content
CloudOps
All prompts
AI for Infrastructure as Code Difficulty: Intermediate ClaudeChatGPT

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

  1. Use SSH config.
  2. Enable control persist.
  3. Pre-populate known_hosts.
  4. 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

Newsletter

Get weekly AI workflows for DevOps engineers

Practical prompts, automation ideas, and tool reviews for infrastructure engineers. One email per week. No spam.