You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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步骤,打印变量值:
    - name: 打印data仓库URL
      ansible.builtin.debug:
        var: data.git.repo
    
    若输出为空,需修正inventory的YAML格式或调整变量作用域。

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验证私钥有效性,若报错则需重新生成密钥。

额外优化建议

  1. 用ansible-vault加密敏感密钥文件,避免明文存储。
  2. 可通过环境变量指定密钥,替代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"
    
  3. 确认远程服务器git版本支持key_file参数,旧版本git建议升级或改用环境变量方式。

内容的提问来源于stack exchange,提问作者Sergey Bezugliy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 07:17:01