使用Ansible通过Deploy Key克隆GitHub私有仓库失败求助
问题排查:Ansible git模块未插值仓库URL且密钥加载失败
我正尝试用Ansible Playbook及内置git模块部署应用,遇到两个核心问题:Ansible未将git仓库URL正确插值到命令中,同时出现密钥加载报错。库存变量已存在且值正确,远程服务器上.ssh目录权限为0700,公钥权限644,私钥权限0600,用户及组均为ec2-user。以下是相关配置与报错信息:
Inventory配置
--- servers: hosts: "<ip_address>": ansible_user: "ec2-user" ansible_group: "ec2-user" ... web: git: public_key: "./.certs/github.web.id_rsa.pub" private_key: "./.certs/github.web.id_rsa" repo: "git@github.com:<organisation>/web-repo-name.git" ... data: git: public_key: "./.certs/github.data.id_rsa.pub" private_key: "./.certs/github.data.id_rsa" repo: "git@github.com:<organisation>/data-repo-name.git" ...
Playbook代码
- name: 确保.ssh目录存在 ansible.builtin.file: path: "/home/{{ansible_user}}/.ssh" state: directory mode: 0700 owner: '{{ansible_user}}' group: '{{ansible_user}}' register: command_output - ansible.builtin.debug: msg: "{{command_output}}" - name: 确保GitHub部署私钥已上传到服务器 ansible.builtin.copy: content: "{{ item }}" dest: "/home/{{ansible_user}}/.ssh/{{ item | basename }}" with_items: - "{{ web.git.private_key }}" - "{{ web.git.public_key }}" - "{{ data.git.private_key }}" - "{{ data.git.public_key }}" register: command_output - debug: msg: "{{ command_output }}" - name: 设置私钥权限 ansible.builtin.file: path: "/home/{{ansible_user}}/.ssh/{{ item | basename }}" state: file mode: 0600 owner: '{{ansible_user}}' group: '{{ansible_user}}' with_items: - "{{ web.git.private_key }}" - "{{ data.git.private_key }}" register: command_output - ansible.builtin.debug: msg: "{{command_output}}" - name: 设置公钥权限 ansible.builtin.file: path: "/home/{{ansible_user}}/.ssh/{{ item | basename }}" state: file mode: 0644 owner: '{{ansible_user}}' group: '{{ansible_user}}' with_items: - "{{ web.git.public_key }}" - "{{ data.git.public_key }}" register: command_output - ansible.builtin.debug: msg: "{{command_output}}" - name: 确保.ssh目录存在(重复步骤) ansible.builtin.file: path: "/home/{{ansible_user}}/.ssh" state: directory mode: 0700 owner: '{{ansible_user}}' group: '{{ansible_user}}' register: command_output - ansible.builtin.debug: msg: "{{command_output}}" - name: 确保GitHub部署私钥已上传到服务器(重复步骤) ansible.builtin.copy: content: "{{ item }}" dest: "/home/{{ansible_user}}/.ssh/{{ item | basename }}" with_items: - "{{ web.git.private_key }}" - "{{ web.git.public_key }}" - "{{ data.git.private_key }}" - "{{ data.git.public_key }}" register: command_output - debug: msg: "{{ command_output }}" - name: 设置私钥权限(重复步骤) ansible.builtin.file: path: "/home/{{ansible_user}}/.ssh/{{ item | basename }}" state: file mode: 0600 owner: '{{ansible_user}}' group: '{{ansible_user}}' with_items: - "{{ web.git.private_key }}" - "{{ data.git.private_key }}" register: command_output - ansible.builtin.debug: msg: "{{command_output}}" - name: 设置公钥权限(重复步骤) ansible.builtin.file: path: "/home/{{ansible_user}}/.ssh/{{ item | basename }}" state: file mode: 0644 owner: '{{ansible_user}}' group: '{{ansible_user}}' with_items: - "{{ web.git.public_key }}" - "{{ data.git.public_key }}" register: command_output - ansible.builtin.debug: msg: "{{command_output}}" ... - name: 克隆仓库到工作目录 hosts: servers remote_user: '{{ansible_user}}' tasks: - name: 克隆data仓库 ansible.builtin.git: accept_hostkey: true key_file: "/home/{{ansible_user}}/.ssh/{{ data.git.private_key | basename }}" repo: "{{ data.git.repo }}" version: master dest: /opt/app/data clone: yes update: yes register: command_output - ansible.builtin.debug: msg: "{{command_output}}" - name: 克隆web仓库 ansible.builtin.git: accept_hostkey: true key_file: "/home/{{ansible_user}}/.ssh/{{ web.git.private_key | basename }}" repo: "{{ web.git.repo }}" version: master dest: /opt/app/web clone: yes update: yes register: command_output - ansible.builtin.debug: msg: "{{command_output}}"
报错信息
TASK [Gathering Facts] ************************************************************************************************************************************************* ok: [18.170.237.197] TASK [Clone a data github repository] ********************************************************************************************************************************** fatal: [18.170.237.197]: FAILED! => {"changed": false, "cmd": "/usr/bin/git clone --origin origin '' /opt/app/data", "msg": "Cloning into '/opt/app/data'...\nLoad key \"/home/ec2-user/.ssh/github.data.codenv.top.id_rsa\":********@github.com: Permission denied (publickey).\r\nfatal: Could not read from remote repository.\n\nPlease make sure you have the correct access rights\nand the repository exists.", "rc": 128, "stderr": "Cloning into '/opt/app/data'...\nLoad key \"/home/ec2-user/.ssh/github.data.codenv.top.id_rsa\": error in libcrypto\r\ngit@github.com: Permission denied (publickey).\r\nfatal: Could not read from remote repository.\n\nPlease make sure you have the correct access rights\nand the repository exists.\n", "stderr_lines": ["Cloning into '/opt/app/data'...", "Load key \"/home/ec2-user/.ssh/github.data.codenv.top.id_rsa\": error in libcrypto", "git@github.com: Permission denied (publickey).", "fatal: Could not read from remote repository.", "", "Please make sure you have the correct access rights", "and the repository exists."], "stdout": "", "stdout_lines": []} PLAY RECAP *************************************************************************************************************************************************************
排查与修复方案
1. 仓库URL未插值(空字符串)
从报错的cmd字段可见,repo参数被解析为空字符串,说明data.git.repo变量未被正确读取:
- 核心原因:YAML缩进错误或变量作用域问题。检查inventory文件中
data.git.repo的缩进是否与同级变量一致;确认git任务所在play的hosts与inventory中定义的主机匹配,无变量覆盖情况。 - 验证方法:在git任务前添加debug步骤,打印变量值:
若输出为空,需修正inventory的YAML格式或调整变量作用域。- name: 打印data仓库URL ansible.builtin.debug: var: data.git.repo
2. 密钥加载报错(error in libcrypto)
报错显示密钥文件加载失败,核心问题出在密钥复制步骤:
- 原因1:复制逻辑错误
原copy任务使用content: "{{ item }}",但item存储的是本地密钥文件路径,而非密钥内容,导致远程服务器上的密钥文件仅写入路径字符串,而非实际密钥。
修复:将content改为src,直接复制本地文件到远程:- name: 上传GitHub部署密钥 ansible.builtin.copy: src: "{{ item }}" dest: "/home/{{ansible_user}}/.ssh/{{ item | basename }}" with_items: - "{{ web.git.private_key }}" - "{{ web.git.public_key }}" - "{{ data.git.private_key }}" - "{{ data.git.public_key }}" - 原因2:重复执行冗余步骤
Playbook中重复执行了2次创建.ssh目录、复制密钥、设置权限的步骤,可能导致密钥被覆盖或权限异常,需删除重复步骤,仅保留一套。 - 原因3:密钥本身损坏
在本地执行ssh-keygen -y -f ./certs/github.data.id_rsa验证私钥有效性,若报错则需重新生成密钥。
额外优化建议
- 用
ansible-vault加密敏感密钥文件,避免明文存储。 - 可通过环境变量指定密钥,替代
key_file参数(兼容性更好):- name: 克隆data仓库 ansible.builtin.git: accept_hostkey: true repo: "{{ data.git.repo }}" version: master dest: /opt/app/data clone: yes update: yes environment: GIT_SSH_COMMAND: "ssh -i /home/{{ansible_user}}/.ssh/{{ data.git.private_key | basename }} -o StrictHostKeyChecking=no" - 确认远程服务器git版本支持
key_file参数,旧版本git建议升级或改用环境变量方式。
内容的提问来源于stack exchange,提问作者Sergey Bezugliy
相关产品推荐
相关产品推荐

