espenak / awsfabrictasks

Other
84 stars 26 forks source link

Run tasks on multiple hosts #2

Closed rnhurt closed 12 years ago

rnhurt commented 12 years ago

I am trying to run a task on multiple hosts with the same tag [Name: Magento] and am getting the following error:

awsfabrictasks.ec2.api.MultipleInstancesWithSameNameError: More than one ec2 reservations with tag:Name=Magento

Basically, what I want to do is manage all of my Magento servers with a single command. Update the OS, pull the latest code from Git, etc... I'm trying to do this by using AWS tags but Fabric is not playing nice with me.

I mainline Ruby and although my Python is really weak I think Fabric is the right tool for this job. Am I missing something? Is is possible to tell AWSFab to run the same command on all my hosts? Is there a better way to do this?

espenak commented 12 years ago

awsfabrictasks expects names to be unique. How do you tell your machines apart if they are all named Magento? If you want to make this work with awsfabrictasks, you will have to use another tag to describe your instances. You can use the ec2_*_tag tasks to change the tags (or just use the webinterface).

Our API have good support for your use-case. Lets say you use the role=Magento tag on all your Magento instances. You should then be able to use awsfabrictasks.ec2.api.Ec2InstanceWrapper to create tasks that manage these instances. A simple example (may have some errors since this I write this from memory on my iphone):

from awsfabrictasks.ec2.api import Ec2InstanceWrapper, print_ec2_instance
from fabric.api import task, run, settings

@task
def print_uname():
    run("uname -a")

@task
def list_magento_instances():
    for instancewrapper in Ec2InstanceWrapper.get_by_tagvalue(tags={"role": "Magento"}): # in DEFAULT_REGION
        # Some debugging print
        print
        print instancewrapper
        print_ec2_instance(instancewrapper.instance)

        # A more realistic usage example
        ssh_uri = instancewrapper.get_ssh_uri()
        key_filename = instancewrapper.get_ssh_key_filename()
        with settings(key_filename=key_filename, host_string=ssh_uri):
            # Run tasks here just as if you invoked ``awsfab -E myname <task>``
            print_uname()
rnhurt commented 12 years ago

Perfect! Thanks!

One suggestion I have would be to put this in the docs somewhere (howto, tutorial, etc.)

espenak commented 12 years ago

Will add it later today or tomorrow. Think I will try to simplify it with a fabric.api.settings-wrapper that makes it possible to do:

with instancewrapper.instance_settings(): # Supports any fabric.api.settings arguments, but key_filename and host_string is ignored/overridden
    print_uname()

Instead of:

ssh_uri = instancewrapper.get_ssh_uri()
key_filename = instancewrapper.get_ssh_key_filename()
with settings(key_filename=key_filename, host_string=ssh_uri):
    # Run tasks here just as if you invoked ``awsfab -E myname <task>``
    print_uname()
espenak commented 12 years ago

Also note that any improvements to the docs are welcome as pull requests, and feel free to add anything you think others may find useful to the wiki.