class TestOpsWorksConnection(unittest.TestCase): def setUp(self): self.api = OpsWorksConnection() def test_describe_stacks(self): response = self.api.describe_stacks() self.assertIn('Stacks', response) def test_validation_errors(self): with self.assertRaises(ValidationException): self.api.create_stack('testbotostack', 'us-east-1', 'badarn', 'badarn2')
def deploy_erlang_rest_app(): api = OpsWorksConnection() instance_id = "29c92563-e53c-4b24-85bb-8109784b7275" app_id = "5597648b-dc7f-437b-a0ed-df8b242bf8ef" command = {"Name": "deploy"} stack_id = "55186abb-f9aa-44b3-b0c1-f607747725ab" res = api.create_deployment(stack_id, command, app_id=app_id, instance_ids=[instance_id]) return res
def connect_opsworks(aws_access_key_id=None, aws_secret_access_key=None, **kwargs): from boto.opsworks.layer1 import OpsWorksConnection return OpsWorksConnection(aws_access_key_id=aws_access_key_id, aws_secret_access_key=aws_secret_access_key, **kwargs)
def __init__(self, aws_access_key_id=None, aws_secret_access_key=None, layer_id=None, offline=False): self.connection = OpsWorksConnection( aws_access_key_id=aws_access_key_id, aws_secret_access_key=aws_secret_access_key) self.layer_id = layer_id self.show_offline = offline self.instances = []
def handle(self, *args, **options): opsworks = OpsWorksConnection() stack_resp = opsworks.describe_stacks() stack_id = None stack_name = None for stack in stack_resp['Stacks']: if stack['Name'].startswith('web') and stack['Name'].endswith( options['environment']): stack_id = stack['StackId'] stack_name = stack['Name'] break if not stack_id: raise CommandError('Stack does not exist.' % options['environment']) # get application app_resp = opsworks.describe_apps(stack_id=stack_id) app_id = app_resp['Apps'][0]['AppId'] app_name = app_resp['Apps'][0]['Name'] # get layer for layers in opsworks.describe_layers(stack_id=stack_id)['Layers']: if layers['Name'] == 'bots': # deploy to the instances of particular layer for instance in opsworks.describe_instances( layer_id=layers['LayerId'])['Instances']: custom_json = json.dumps(get_json()) comment = "Deploying %s from %s@%s at %s to %s on %s" % ( app_name, getpass.getuser(), socket.gethostname(), datetime.now().isoformat(' '), instance['Hostname'], stack_name) deployment = opsworks.create_deployment( stack_id, {'Name': 'deploy'}, app_id=app_id, instance_ids=[instance['InstanceId']], custom_json=custom_json, comment=comment) print "https://console.aws.amazon.com/opsworks/home?#/stack/%s/deployments/%s" % ( stack_id, deployment['DeploymentId'])
class OpsWorksInstanceManager: def __init__(self, aws_access_key_id=None, aws_secret_access_key=None, layer_id=None, offline=False): self.connection = OpsWorksConnection( aws_access_key_id=aws_access_key_id, aws_secret_access_key=aws_secret_access_key) self.layer_id = layer_id self.show_offline = offline self.instances = [] def get_instance(self, instance_index): return self.instances[instance_index] def list_instances(self): instances = self.connection.describe_instances( layer_id=self.layer_id)['Instances'] counter = 0 for instance in instances: if self.show_offline or instance['Status'] == 'online': self.instances.append(instance) counter += 1 self.instances = sorted(self.instances, key=itemgetter(u'Hostname')) return self.instances def print_instances(self): instances = self.list_instances() for counter, instance in enumerate(instances): print "%d) %s" % (counter + 1, instance[u'Hostname'])
def run(self, *args, **options): opsworks = OpsWorksConnection() stack_resp = opsworks.describe_stacks() stack_id = None stack_name = None # get web production stack for stack in stack_resp['Stacks']: if stack['Name'].startswith('web') and stack['Name'].endswith(self.environment): stack_id = stack['StackId'] stack_name = stack['Name'] break if not stack_id: raise Exception('Stack does not exist.' % options['environment']) # get application app_resp = opsworks.describe_apps(stack_id=stack_id) app_id = app_resp['Apps'][0]['AppId'] app_name = app_resp['Apps'][0]['Name'] # get layer for layers in opsworks.describe_layers(stack_id=stack_id)['Layers']: if layers['Name'] == 'bots': # deploy to the instances of particular layer for instance in opsworks.describe_instances(layer_id=layers['LayerId'])['Instances']: custom_json = json.dumps(get_json()) comment = "Deploying %s from %s@%s at %s to %s on %s" % ( app_name, getpass.getuser(), socket.gethostname(), datetime.now().isoformat(' '), instance['Hostname'], stack_name) deployment = opsworks.create_deployment(stack_id, {'Name': 'deploy'}, app_id=app_id, instance_ids=[instance['InstanceId']], custom_json=custom_json, comment=comment) print "https://console.aws.amazon.com/opsworks/home?#/stack/%s/deployments/%s" % (stack_id, deployment['DeploymentId'])
from boto.opsworks.layer1 import OpsWorksConnection command = "execute_recipes" opsworks = OpsWorksConnection() stackName = u'CIC-InnovationService01' # set deploymentCommand deploymentCommand = {'Name': '%s' % command} deploymentCommand['Name'] = 'execute_recipes' deploymentCommand['Args'] = {"recipes": ["git::sync_crawler"]} # get stackId desc_stacks = opsworks.describe_stacks() stackId = u'None' for loop in desc_stacks[u'Stacks']: if loop[u'Name'] == stackName: stackId = loop[u'StackId'] if stackId == u'None': print("Error: stackName not found") # execute recipes opsworks.create_deployment(stack_id=stackId, command=deploymentCommand)
def setUp(self): self.api = OpsWorksConnection()
from boto.opsworks.layer1 import OpsWorksConnection command = "execute_recipes" opsworks = OpsWorksConnection() stackName = u'CIC-InnovationService01' # set deploymentCommand deploymentCommand = { 'Name': '%s' % command } deploymentCommand['Name'] = 'execute_recipes' deploymentCommand['Args'] = {"recipes":["git::sync_tech-info"]} # get stackId desc_stacks = opsworks.describe_stacks() stackId = u'None' for loop in desc_stacks[u'Stacks']: if loop[u'Name'] == stackName: stackId = loop[u'StackId'] if stackId == u'None': print ("Error: stackName not found") # execute recipes opsworks.create_deployment(stack_id = stackId, command = deploymentCommand )
def main(args): global ops if len(args) < 2: usage() return ops = OpsWorksConnection() stack_name = args[0] stack_id = select_stack_id(stack_name) app = AttrDict() app_list = [] for arg in args[1:]: if "=" not in arg: if app: app_list.append(app) app = AttrDict(name=arg, params={}) else: k, v = arg.split("=", 1) app.params[k] = v if app.name: app_list.append(app) all_instances = [] must_start_instances = [] must_stop_instances = [] for app in app_list: app.info = select_app(stack_id, app.name) app.layers = [AttrDict(l) for l in find_layers_for_app(stack_id, app.info["Shortname"])] if not app.layers: raise InvalidNumberOfLayers("no layers available for app '%(Name)s' (%(Shortname)s)" % app.info) app.json = { "deploy": { app.info["Shortname"]: { } } } root = app.json["deploy"][app.info["Shortname"]] for k, v in app.params.iteritems(): path = k.split(".") attr = path[-1] path = path[:-1] descend_dict(root, path)[attr] = v if len(app.layers) > 1: app.elb = select_elb_for_layers(stack_id, app.layers) active_layer = [l["LayerId"] for l in app.layers].index(app.elb["LayerId"]) app.old_layer = app.layers[active_layer] app.new_layer = app.layers[1 - active_layer] else: app.new_layer = app.layers[0] for l in app.layers: l.instances = find_layer_instances(l["LayerId"]) all_instances.extend(l.instances) must_start_instances.extend(i for i in l.instances if l == app.new_layer and i["Status"] == "stopped" and "AutoScalingType" not in i) must_stop_instances.extend(i for i in l.instances if l != app.new_layer and i["Status"] != "stopped" and "AutoScalingType" not in i) if not app.new_layer.instances: raise NoInstanceAvailable("no instances available for layer '%(Name)s'" % app.new_layer) # INFO for app in app_list: print "Application '%(Name)s' to be deployed on layers '%(LayerName)s' with instances" % dict(app.info, LayerName=app.new_layer["Name"]) for i in app.new_layer.instances: print "\t%(Hostname)s - %(Architecture)s - %(InstanceType)s - %(Status)s" % i print "with custom JSON: %s" % pformat(app.json) # ^ INFO pending_instance_ids = [i["instanceId"] for i in must_start_instances] for id in pending_instance_ids: ops.start_instance(id) while pending_instance_ids: ins = [i for i in ops.describe_instances(instance_ids=pending_instance_ids)["Instances"] if i["Status"] != "online"] pending_instance_ids = [i["InstanceId"] for i in ins] if pending_instance_ids: print "Waiting 30 sec for instances to start: %s" % ", ".join(i["Hostname"] for i in ins) time.sleep(30) for app in app_list: print "Deploying '%(Name)s' (%(Shortname)s)" % app.info instance_ids = [i["InstanceId"] for i in app.new_layer.instances] prev_dep = find_last_deployment(app.info["AppId"], instance_ids) if prev_dep and "CustomJson" in prev_dep: print "\tprevious deployment (type '%s') done by %s on %s" % ( prev_dep["Command"]["Name"], prev_dep["IamUserArn"].split(":user/")[-1], prev_dep["CreatedAt"]) dep_id = deploy_app(stack_id, app.info["AppId"], instance_ids, app.json) # wait for deployment to be complete while True: dep = ops.describe_deployments(deployment_ids=[dep_id])["Deployments"][0] if dep["Status"] != "running": break print "\twaiting 60 sec for completion of deployment..." time.sleep(30) print "\tcompleted with status: %s" % dep["Status"] if len(app.layers) > 1: print "Attaching ELB '%(DnsName)s' to layer '%(Name)s'" % dict(app.elb, Name=app.new_layer["Name"]) attach_elb_to_layer(app.elb, app.old_layer, app.new_layer) pending_instance_ids = [i["InstanceId"] for i in must_stop_instances] for id in pending_instance_ids: ops.stop_instance(id) while pending_instance_ids: ins = [i for i in ops.describe_instances(instance_ids=pending_instance_ids)["Instances"] if i["Status"] != "stopped"] pending_instance_ids = [i["InstanceId"] for i in ins] if pending_instance_ids: print "Waiting 30 sec for instances to stop: %s" % ", ".join(i["Hostname"] for i in ins) time.sleep(30)
def connect(): return OpsWorksConnection()