SSH, Private Repos, Ansible and Vagrant

Lets say you want to setup a server using Vagrant and Ansible and you want to put your code onto the server by checking it out from a private repo from some place like BitBucket. Further, you want to make it possible for the server to checkout new updates. Here is one way to do it.

First create a RSA keypair. There are lots of examples of how to do it. This is a good one. When you complete this, you will have the keypair on your local machine, which will be useful if you want to check code from the repo.

Next, put a copy of your public key (*.pub) on the repo site (e.g. Bitbucket). The repo site will have instructions for how to do this.

After that, create an Ansible YMAL file and put both the private and public keys in it. Something like this:

---
git_repo: ssh://git@bitbucket.org/me/my_repo.git

- name: Create the Bitbucket SSH public key file
  copy: src="/path/to/your/local/public/key"
        dest=/home/vagrant/.ssh/id_rsa_bitbucket.pub
        mode=0644
        owner=vagrant
        group=vagrant

- name: Create the Bitbucket SSH private key file
  copy: src="/path/to/your/local/private/key"
        dest=/home/vagrant/.ssh/id_rsa_bitbucket
        mode=0600
        owner=vagrant
        group=vagrant

- name: Setup the Git repo git: repo={{ git_repo }} dest={{ project_path }} accept_hostkey=yes when: setup_git_repo tags: git

When you run vagrant up or vagrant provision, you might get this error:

Permission denied (publickey).
 fatal: The remote end hung up unexpectedly

However, if you run vagrant ssh and manually git the repo, everything works. The reason for this is, in my case, Ansible was becoming root before pulling the code from the repo and root does not have the private key. Luckily, you can tell Ansible git which file to use, by using the key_file keyword. Like this:

- name: Setup the Git repo
  git: repo={{ git_repo }} dest={{ project_path }} accept_hostkey=yes key_file=/home/vagrant/.ssh/id_rsa_bitbucket
  when: setup_git_repo
  tags: git

Django, PyCharm, Vagrant and Ansible

To provide maximum isolation between customers, I prefer to set each one up on its own VPS. One down-side to this approach is it is a pain to setup a new server. In the past, I used Fabric. But recently I read High Performance Django. In that book, they go out of their way to advise against using Fabric. They like Salt. After a little googling and a few coin tosses, I decided to give Ansible a try.

At first the going was a little rough, then I discovered this gem of a repo on Github: ansible-django-stack. It even uses Vagrant, another package I have wanted to try.

OMG

This repo is insanely helpful. It even comes with a fully functional Django project. This was incredibly helpful for figuring out how to get Pycharm working with the virtual machine created by Vagrant. Just follow the docs in repo and in a few minutes you will have a fully functioning Django site, running the components any serious Django project needs. This will change your life.

Installing the Exact Same Configuration on Digital Ocean

Getting it running on a local virtual machine is pretty cool. Its even more amazing how easy it is to get it running in a Digital Ocean droplet. In a previous post, I tried and failed to setup a droplet using Ansible. So I skipped that step and use the Ansible web interface to do that. Here are the steps for creating the droplet and installing the complete stack:

  1. Setup a Droplet using Ubuntu 12.04.5×64 because that is what the Vagrantfile specifies. If you want to setup a different OS, change your Vagrantfile.
  2. Get the IP address for your new droplet
  3. cd into the root dir of ansible-django-stack and type:

ansible-playbook -i ip_address, -v development.yml --ask-sudo-pass

Make sure to include the comma after the IP address. This tells Ansible to not look for an inventory file and to just run the playbook on that server. That’s it! Go to http://192.168.33.15/ and you will see a fully functioning Django site!

Bring the Charm

One powerful feature of Vagrant is it’s “Synced Folders” function. Actually this is a misnomer. A synced folder is a folder that is accessible on your host machine and the virtual machine. Thus there is no synching involved. They are the same physical location.

You can use this feature to edit project files “on” the virtual machine from the PyCharm installation on the host machine. To activate folder synching, do the following:

  1. git clone https://github.com/jcalazan/glucose-tracker.git   /home/me/glucose-tracker
  2. Add this line to the Vagrantfile in ansible-django-stack:
config.vm.synced_folder "/home/me/glucose-tracker", "/webapps/glucosetracker/glucose-tracker"

Now open this repo with PyCharm just like you would with any other project. If you change some of the code and restart the server on the virtual machine, you will see the changes when you reload the page.

Yeah But Can I Use the PyCharm Debugger?

The best feature of PyCharm is the debugger. But will it work with Vagrant? Of course it will. Those folks at Jet Brains have got you covered.

PyCharm (v4) fully supports Vagrant and can run the python interpreter on the virtual machine. To get started, just go to settings>tools>vagrant and do what comes naturally. Then go to Tools on the menu bar and select vagrant up.

Next, go to settings>Project>Project Interpreter. Click the gear icon and select Add Remote, then select Vagrant and set the instance folder to the folder that contains Vagrantfile. Next set the python interpreter to the virtualenv for this project (note how awesome having a working project is):

/webapps/glucosetracker/bin/python

Next go to Run>Edit Configurations to setup the PyCharm server. Here is what it looks like:

run_config

You will need to setup these environment vars:

env_vars

Finally, you need to setup the Path Mappings like this:

path_mappings

And ta da! You can now run the project in PyCharm complete with debugging.

Now you can add the power of Ansible and Vagrant without sacrificing any of the power of PyCharm!