Playing with Amazon EC2, libcloud and fabric
So i finally got around to signing up for an Free Tier Amazon EC2 account after reading alot about libcloud.
Combining libcloud with fabric gives huge opportunities when it comes to automating installations and deployment,
and with only a small amount of code.
First i had to install libcloud, which is installed through pip.
As fabric is available as an ubuntu package i used that, maybe there is a newer version available in pip but i haven’t checked yet.
sudo apt-get install python-pip sudo pip install libcloud
sudo apt-get install fabric
What i have done is prepare my own EC2 AMI, where i have created a user and added my usual ssh-pubkey for simple authentication.
To do this you just have to start up an ubuntu AMI, log in to it and make your changes and then choose to make it into an AMI.
The ubuntu AMI i used is their official Maverick i386 AMI on us-east: ami-ccf405a5
You also have to change your default security group in EC2 to permit tcp port 22 or you won’t be able to connect to the machine.
The EC2 webservice require you to use their X509 certificate so you should create one of those and download the key and cert files.
Now let’s get to the code!
from libcloud.types import Provider from libcloud.providers import get_driver from libcloud.base import NodeImage, NodeSize import libcloud.security import os from fabric.api import * from fabric.contrib.console import confirm import time import string libcloud.security.VERIFY_SSL_CERT = True libcloud.security.CA_CERTS_PATH.append("/path/to/cert-BLABLA.pem") EC2_ACCESS_ID = 'ABCDEFGHIJKLMNOPQ' EC2_SECRET_KEY = 'jghgfjhgfkjhgfuyrtgfhusdnsjkdf' keyname = "your keyname" username = "the user you created in the AMI" my_ami = "ami-yourami" i_size = "t1.micro" #This is what you should use if your using the Free Tier account Driver = get_driver(Provider.EC2) conn = Driver(EC2_ACCESS_ID, EC2_SECRET_KEY) nodes = conn.list_nodes() def all_instances(): for node in nodes: if node.public_ip: print node.public_ip env.hosts += [username + "@" + node.public_ip] def new_instance(): name = raw_input("Name of new instance: ") image = NodeImage(id=my_ami, name="", driver="") size = NodeSize(id=i_size, name="", ram=None, disk=None, bandwidth=None, price=None, driver="") node = conn.create_node(name=name, image=image, size=size, ex_keyname=keyname) nodes = conn.list_nodes() print nodes while nodes[-1].state != 0: print nodes[-1] time.sleep(30) nodes = conn.list_nodes() print "ok" nodes = conn.list_nodes() env.hosts = [username + "@" + nodes[-1].public_ip] time.sleep(30) def latest_instance(): env.hosts = [username + "@" + nodes[-1].public_ip]
Now write a small method for running “uname -a” in fabric:
def uname(): run("uname -a")
This method can now be used in combination with any of the instance-methods:
fab all_instances uname fab new_instance uname fab latest_instance uname
The method new_instance will create a new instance from your AMI and when it’s ready connect via SSH and run your commands.
I have used a sleep-timer for 30 seconds to allow the new instance to boot up and start SSHd properly before we try to connect.
This timer have worked for my free account, but maybe you could have a lower value for faster machines as they will probably boot quicker.