I'm trying to write deployments rules with Ansible. Some of the steps are:
- Update and Upgrade Server
- Create a user called harry
- Add Public and Private keys to harry
- 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 ?
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
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.
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
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.