***Warning: I took these notes as I tried to create a droplet using Ansible. I did not get it to work. So if all you want is the answer, this is not the place to be.
I have been using AWS free tier for a while. Based on lots of googling and the kindness of other bloggers, I eventually got a fabric script that sets up and manages my sites on AWS. Getting that fabric script working was a real challenge because the AWS API is a moving target and the docs are lacking.
I just found out my free period on AWS is about to end. While I think AWS is probably a pretty good way to go if you have a lot of traffic and VC’s paying your bills, many of my sites are very low volume (50 users, less than one page view per second). Thus AWS is expensive over-kill.
As I have been googling various subjects, I noticed that lots of answers are on Digital Ocean. So I started looking into Digital Ocean as an alternative to AWS. Everything seemed great, so I signed up and started playing around.
I should also mention that several months ago, I read “High Performance Django“. In that book, they have a special, highlighted warning to not use fabric for deployment. Silly me. Just because fabric works well and is easy to understand is no reason to use it. After more googling, I decided to try Ansible.
My first impression is that if you stick to the well beaten path on Digital Ocean, things work pretty good. I did their one click installer for Django and had a site running in less than a minute. If you are a noob to Django and deployment, this is the way to go. But I wanted more control of my stack and there seems to be lots of Ansible examples for creating a Django stack on DO. Down the rabbit hole I went.
Turns out DO and Ansible are moving targets with lacking documentation. AWS all over again.
This Github repo seemed to hold the answer: https://github.com/hostmaster/ansible-digitalocean-bootstrap. But right off the bat, I got:
failed=True msg='dopy >= 0.2.3 required for this module'
I had dopy 0.3 installed. But Ansible was not using my virtualenv. I add the virtualenv by adding this line to vars.yml:
ansible_python_interpreter: "/home/me/.virtualenvs/roi_digital_ocean/bin/python"
With that fixed, I am stymied by this error:
failed: [localhost] => {"failed": true}
msg: Access Denied
I posted it to Stackoverflow. No answer in over 48 hours. I am not complaining. In fact I am grateful for the free help I have gotten in the past. However, in contrast, the last Django question I asked was answered in 10 minutes. I suspect this question is obscure enough that I will never get an answer.
I know Ansible uses dopy. So I tried creating a droplet with dopy. Following the examples, I was able to create a droplet. However, I was not able to create a droplet using the ssh_key_ids keyword in the new_droplet method. I tried every conceivable value. Every time I got:
dopy.manager.DoError: You specified invalid ssh key ids for Droplet creation.
Which is the error message the Digital Ocean API sends back. Here is a solution to a similar problem. They are using the python Requests module. dopy uses Requests. The difference between that solution and dopy is dopy does not explicitly JSON encode the parameters. I think Requests does that for you if you give it a dict. Therefore, in theory, there is no difference between the two. Also, I was able to create a new droplet, with an SSH key using python-digitalocean v1.1.
For now, maybe I can just use the DO web interface to create the droplets and use Ansible to configure them once they are created. Here are the gory details for Ubuntu 12.04. I already have an SSH key on my machine:
- Go to the .ssh dir on your machine. Mine is at ~/.ssh
- Open id_dsa.pub and copy its entire contents
- Goto: https://cloud.digitalocean.com/ssh_keys
- Click on Add SSH Key
- Paste the contents of id_dsa.pub into the Public SSH Key box
- At the end of the SSH key you will see a name. I used that as the name on the DO web form. I am not sure if this is necessary
- Use the DO web interface to create a new droplet. In the Add SSH Key section, make sure to highlight the SSH key you just made.
- I use ssh from the Ubuntu command line all the time. So it made sense to test my new droplet there with:
ssh root@104.236.77.94
Once More with Ansible
In the “getting started” section of Ansible, it shows you how to use Ansible to ping a server. Lets do that.
- create an inventory file. I called mine test_inventory. It’s contents was just the IP address of my droplet.
- In the same dir as the inventory file, at the command line, type:
ansible -i test_inventory -m ping all -u root
If you forget the -u root params, you will get a message like:
SSH encountered an unknown error during the connection. We recommend you re-run the command using -vvvv ...
If you run it again with the -vvvv option, you get an very confusing and long set of debug messages. This is the problem with Ansible. Simple mistakes that noobs are likely to make, lead to confusing error messages. I am sure the “Access Denied” error above is a similar noob mistake.