Question

I'm learning to use Fabric and Boto so far I have managed to login and create an new instance. How do I now pip install Gunicorn on the newly created server below using Python in same fab file?

i.e. I'm hoping to get the new instance and pip install from this file.

This is my fab.py file and what I have so far:

SERVER_TYPES = {
                'web' : {
                       'image_id' : 'ami-xxxxxx',
                       'instance_type' : 't1.micro',
                       'security_groups' : [MAIN_SG],
                       'key_name' : MAIN_KP,
                        },
}



class EC2Conn:
    def __init__(self):
        print(_green("Started..."))
        self.ec2conn = None
        self.user = 'fabUser'
        self.access_key = 'xxxxxx'
        self.secret_key = 'xxxxxxxxxxxx'

    def connect(self):
        print(_green("Connecting..."))

        region = ec2.get_region('eu-west-1')
        self.ec2conn = ec2.connection.EC2Connection(self.access_key,
                          self.secret_key, region=region)


    def get_instances(self):
        return self.ec2conn.get_all_instances()


    def create_instance(self, instance_type='web', address=None):
                reservation = self.ec2conn.run_instances( **SERVER_TYPES[instance_type])
                print reservation
                instance = reservation.instances[0]
                time.sleep(10)
                while instance.state != 'running':
                        time.sleep(5)
                        instance.update()
                        print "Instance state: %s" % (instance.state)

                print "instance %s done!" % (instance.id)



def create_instance():
    a = EC2Conn()
    a.connect()
    return a.create_instance()

So I'm after something like this:

def install_stuff(using self.ec2conn)
      using ec2 instance
      run('pip install gunicorn')

   etc
Was it helpful?

Solution

I had to do something similar in the past. I've combined what I think are the important parts. Once its setup you can run fabric commands on a host, or group of hosts, by passing a list for the hosts parameter. Hope this helps

from fabric.api import *
import socket
socket.setdefaulttimeout(5)

# Setup fabric details
env.user         = 'fabric-user'
env.key_filename = '/root/.ssh/fabric_rsa'

def execute_remote(command):
    return run(command)

@parallel
def execute_remote_parallel(command):
    return run(command)

def run_fabric(cmd,hosts,in_parallel):
    """ Check the parameters and call the corresponding fabric block"""
    if in_parallel:
        return execute(execute_remote_parallel,command=cmd,hosts=hosts)
    else:
        return execute(execute_remote,command=cmd,hosts=hosts)

class FabricFunctions:    

    def stop_service(self,hosts,in_parallel,servicename):
        cmd = "sudo /sbin/service %s stop" % servicename
        run_fabric(cmd, hosts, in_parallel)

    def start_service(self,hosts,in_parallel,servicename):
        cmd = "sudo /sbin/service %s start" % servicename
        run_fabric(cmd, hosts, in_parallel)


#
#   Example - Untested!
#
f = FabricFunctions()
f.start_service("ec2-instance-ip",False,"httpd")

It should be pretty simple to add new methods to the fabric functions class to run pip commands

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top