通过ssh密钥转发进行身份验证时克隆git存储库的最佳方法

时间:2016-01-12 09:50:16

标签: git ansible ansible-playbook git-clone

先决条件:

  • 主持人& git身份验证通过ssh key发生
  • 启用了ssh密钥转发
  • 我们团队的每位用户都使用专用的用户帐户 - 无法通过无头用户帐户登录

现在我们要从git存储库部署应用程序。这应该很简单,但事实并非如此。

- name: Clone app repo
  git:
    repo: githost:org/repo.git
    dest: /some/location
    version: HEAD
    force: yes
    ssh_opts: -o StrictHostKeyChecking=no
  notify:
    - Restart app

githost 是我们的.ssh / config

中的一个条目

以上任务有效。但是(当然)存储库被克隆为执行该剧本的用户。我们需要的是:

  • 所有文件都应由无头用户拥有,让我们称呼他为zaphod
  • 只允许zaphod 读取文件。我们谈论的是0600/0700权限。

以下任务无效,因为使用become我们将丢失转发的ssh密钥,因此git身份验证将失败:

- name: Clone app repo
  git:
    repo: githost:org/repo.git
    dest: /some/location
    version: HEAD
    force: yes
    ssh_opts: -o StrictHostKeyChecking=no
  notify:
    - Restart app
  become: yes
  become_user: zaphod

以下变体首先会调用一个处理程序,该处理程序会在(重新)启动应用程序之前更改结帐的所有权:

- name: Clone app repo
  git:
    repo: githost:org/repo.git
    dest: /some/location
    version: HEAD
    force: yes
    ssh_opts: -o StrictHostKeyChecking=no
  notify:
    - Fix ownership
    - Restart app

这个工作一次。但是如果第二次运行playbook git任务失败,因为运行该游戏的用户没有权限修改克隆。

我们有一个非常难看的解决方案:

  • 克隆到/ tmp / foo
  • 修复/ tmp / foo的所有权
  • rm -rf /some/location
  • mv /tmp/foo /some/location
  • 最后(重新)开始申请

这样做的问题是:

  • 每次执行剧本时触发重启
  • Ansible摘要显示了5个已更改的任务,即使没有发生任何事情 - 除了首先不需要的重启

我在这里有点挑剔,但我只想改变状态,如果真的发生了变化,那么在一个完美的世界中,甚至git任务都不会改变状态。为此,我没有看到解决方案。因为我们要求克隆文件只能由zaphod访问 - 但zaphod他自己无法克隆回购。所以必须有一些操作是某种形式导致变化。

有什么建议如何以干净的方式改进?我不想再添加20个临时副本,临时更改权限,手动比较文件等任务......

当然,自定义编写的模块将能够处理所有这些 - 但我对开发和战斗测试不需要2天的事情更感兴趣。 ; - )

2 个答案:

答案 0 :(得分:5)

看起来您正在尝试通过简单地克隆包含您需要的内容的repo来部署应用程序/网页,而不是需要能够将任何更改从该服务器推回到repo。

如果是这样的话那么你就可以将本地任务转移到git archive将repo变成tarball或其他东西,然后使用unarchive将生成的存档复制到目标机器并打开它。 unarchive将允许您设置权限和所有权。

所以你的游戏看起来像是:

- name: locally clone repo
  git:
    repo: githost:org/repo.git
    dest: /some/tmp/location
    version: HEAD
    force: yes
  delegate_to: localhost
  changed_when: false #

- name: archive app repo
  command: git archive --format zip --output /path/to/archive master
    chdir: /some/tmp/location
  delegate_to: localhost
  changed_when: false

- name: unarchive app repo
  unarchive:
    src: /path/to/archive
    dest: /some/location
    owner: zaphod
    mode: 0700
    creates: /some/location
  notify:
    - Restart app

答案 1 :(得分:0)

建立在@ydaetskcoR的答案之后,以下版本也适用:

- name: locally clone repo
  git:
    repo: githost:org/repo.git
    dest: /some/tmp/location
    version: HEAD
    force: yes
  delegate_to: localhost

- name: archive app repo
  archive: 
    path: /some/tmp/location
    dest: /some/tmp/archive.tgz
  delegate_to: localhost

- name: unarchive app repo
  unarchive:
    src: /some/tmp/archive.tgz
    dest: /some/remote/location
    owner: zaphod
    mode: 0700
  notify:
    - Restart app