Ansible: how to clone a repository as other user

2019-04-23 13:26发布

问题:

I'm trying to write deployments rules with Ansible. Some of the steps are:

  1. Update and Upgrade Server
  2. Create a user called harry
  3. Add Public and Private keys to harry
  4. Clone a Git Repository from bitbucket.org

I want to clone the repository as harry user in his home directory (that's why I'm copying it's public and private keys). The issue is that it is not possible to specifiy a user the git clone must be executed as. So Ansible try to clone the repository as root and failed because he doesn't have rights to access the repository.

How do you solve this ?

回答1:

As per Ansible's documentation on Privilege Escalation, Ansible has limitations on becoming an unprivileged user as it exposes a security hole to Harry.

Using the Ansible git module, you can specify to use Harry's private key from the privileged Ansible user using the key_file parameter, and using become_user allows the cloned files to be given ownership to Harry. For example:

- name: Clone bitbucket repo
  git:
    repo: git@bitbucket.org:your-repo.git
    dest: /var/www/
    version: master
    accept_hostkey: yes
    key_file: /home/harry/.ssh/id_rsa
  become_user: harry


回答2:

You can specify a user for every task in your playbook:

- name: Clone bitbucket repo
  git: ...
  become: yes
  become_user: harry

For more details see Ansible Privilege Escalation.

A more secure alternative to placing your private key on a remote server is to enable ssh key forwarding in the sshd config on the server and your ssh config locally. The key then never leaves your local box.



回答3:

yes, you can make it work with ssh forwarding

as long as the user that you become in the git clone is part of sudoers, so he doesn't need to use sudo to execute git

So, in addition to all the configs required for key forwarding, there is a trick that even mentioned in Ansible docs. High level process is as follows: enable agent forwarding in controlling machine enable accepting agent key in target machine create a user and add him (or her:) into sudoers group use ansible's git module to clone the repo, become: your-sudoer-user

Also, to avoid any permissions denied on the host, just clone it into ~/something You can always copy or symlink to anywhere you want

here is the link to where the playbook part to add user to sudoers is shown, it is basically a copy-paste: Ansible: create a user with sudo privileges

works like a charm

Also, make sure you add your SSH public key in the general settings of BitBucket, not in the per project. Otherwise your ssh key will only work on one specific repo. But if you add the ssh key in the bitbucket general settings, it will work on all your repos

below is the code that makes it work, the suduer user is "deployer"

# the tasks to CREATE A SUDOER GROUP


- name: Make sure we have a 'wheel' group
    group:
      name: wheel
      state: present
    become: yes

  - name: Allow 'wheel' group to have passwordless sudo
    lineinfile:
      dest: /etc/sudoers
      state: present
      regexp: '^%wheel'
      line: '%wheel ALL=(ALL) NOPASSWD: ALL'
      validate: 'visudo -cf %s'
    become: yes

  - name: Add sudoers users to wheel group
    user: name=deployer groups=wheel append=yes state=present createhome=yes
    become: yes


 # tasks to ADD REPO with Ansible's GIT MODULE
  - name: Add  Git Repo - BitBucket 
    git:
      repo: 'git@bitbucket.org:<your_username>/<your_repo>.git'
      dest: ~/code  # note this destination, you will avoid permissions issues
      accept_hostkey: yes # btw, this is for the ssh key forwarding
      recursive: no
    become: deployer # this guy (or gal) is a sudoer by now

# Extra "hack" to change permissions on files AND folders in one go, it has to do with the Capital X and what it applies to and what not. Also picked up from another stackoverflow

- name: Set perms on new Code repo to deployer:deployer dirs-0755 and files-0644
    file:
      path: ~/code
      state: directory
      owner: deployer 
      group: deployer 
      mode: u=rwX,g=rX,o=rX
      recurse: yes
    become: yes


回答4:

Yes with ssh forwarding it works. If your playbook has “become: yes” turned on globally, make sure you turn that off for the git task. The reason that it doesn’t work when you have “become: yes” is because root privilege escalation destroys ssh forwarding. I don’t think you need to become a sudoer. Because if your Ansible controlling machine is authenticated with Bitbucket using ssh key (you add ssh key into the repo) then this authentication is passed through ssh forwarding. You can test it by ssh into your target and issuing “ssh -T git@bitbucket.org” you will see in the output that the target is accepted by Bitbucket as the user of the Ansible controlling machine. So simply execute the task with explicit “become: no”. I agree about cloning into ~/something on the target. Otherwise it will cause issues of permissions. [Edit: one more thing to make it work - ⁃ Repo URL should be the ssh one not https one, without ssh:// (despite what is written in the Ansible Manual examples)] As far as the security, as mentioned above, ssh forwarding is the best.