Ansible Playbook配置带密码SSH密钥及ssh-agent复用问题求助
问题分析
你的Playbook核心错误是:将本地主机ssh-agent的环境变量(SSH_AUTH_SOCK/SSH_AGENT_PID)传递给了远程主机的任务环境,但这个套接字是本地主机的文件路径,远程主机根本无法访问。而Ansible的SSH连接是在本地Ansible进程中发起的,需要让本地的Ansible进程使用这个已加载密钥的ssh-agent,而非远程主机。
同时,原代码中env_vars是字符串格式的JSON,直接传给environment会无法解析,需要先转为字典格式。
修复后的Playbook
--- - name: Setup ssh-agent locally hosts: localhost gather_facts: false vars_files: - ../vars.yml vars: ssh_key_path: "{{ lookup('env', 'HOME') }}/.ssh/{{ sshkeyname }}" ssh_passphrase: "{{ sshpassphrs }}" tasks: - name: Start ssh-agent and capture environment variables shell: | eval $(ssh-agent -s) > /dev/null echo '{"SSH_AUTH_SOCK":"'$SSH_AUTH_SOCK'","SSH_AGENT_PID":"'$SSH_AGENT_PID'"}' register: agent_env_raw - name: Parse agent environment into dictionary set_fact: agent_env: "{{ agent_env_raw.stdout | from_json }}" - name: Add SSH key to ssh-agent environment: "{{ agent_env }}" expect: command: ssh-add "{{ ssh_key_path }}" responses: passphrase: "{{ ssh_passphrase }}" - name: Execute tasks on remote hosts hosts: all gather_facts: false vars_files: - ../vars.yml vars: ansible_user: "{{ username }}" # 让Ansible的SSH连接使用本地的ssh-agent环境 ansible_ssh_common_args: "-o IdentityAgent={{ hostvars['localhost'].agent_env.SSH_AUTH_SOCK }}" tasks: - name: Run ping test shell: ping -c 20 -w 50 fb.me
关键修复说明
- 解析JSON环境变量:用
from_json将shell输出的字符串转为字典,确保environment参数能正确识别。 - 指定SSH代理路径:在远程连接的
ansible_ssh_common_args中添加IdentityAgent参数,强制Ansible使用本地已加载密钥的ssh-agent发起连接,而非尝试在远程主机查找套接字。 - 变量命名优化:调整变量名使其更清晰,避免与Ansible内置变量冲突(比如原
ansible_ssh_pass是Ansible内置的SSH密码变量,用来存密钥口令容易混淆)。
额外验证步骤
执行Playbook前,可以在本地先验证ssh-agent是否正常加载密钥:
# 在Playbook执行的同一个终端环境中 ssh-add -l
如果能看到你的密钥指纹,说明ssh-agent配置生效。
内容的提问来源于stack exchange,提问作者Dr.PB
相关产品推荐
相关产品推荐

