def make_aws_credentials(config, role_arn=None, role_name=None): if role_arn: try: sts_connection = STSConnection() assumedRoleObject = sts_connection.assume_role( role_arn=role_arn, role_session_name=role_name ) except: out("Oops! something went wrong trying to assume the specified role") else: # create credentials for switching roles aws = AwsCredentials( assumedRoleObject.credentials.access_key, assumedRoleObject.credentials.secret_key, assumedRoleObject.credentials.session_token, get(config, 'aws.region', os.environ.get('AWS_DEFAULT_REGION')), get(config, 'aws.bucket', os.environ.get('AWS_BEANSTALK_BUCKET_NAME')), get(config, 'aws.bucket_path', os.environ.get('AWS_BEANSTALK_BUCKET_NAME_PATH'))) out("Using Role: "+role_name) else: # create credentials aws = AwsCredentials( get(config, 'aws.access_key', os.environ.get('AWS_ACCESS_KEY_ID')), get(config, 'aws.secret_key', os.environ.get('AWS_SECRET_ACCESS_KEY')), get(config, 'aws.secret_token', os.environ.get('AWS_SECRET_TOKEN')), get(config, 'aws.region', os.environ.get('AWS_DEFAULT_REGION')), get(config, 'aws.bucket', os.environ.get('AWS_BEANSTALK_BUCKET_NAME')), get(config, 'aws.bucket_path', os.environ.get('AWS_BEANSTALK_BUCKET_NAME_PATH'))) return aws
def run_ebs_deploy(command, args, parser=None): """ the main """ init_logging(args.use_logging) # make sure we have an archive or a directory if not args.config_file or not os.path.exists(args.config_file): out("Config file not found: " + args.config_file) parser and parser.print_help() return -1 # make sure that if we have a role to assume, that we also have a role name to display if (args.role_arn and not args.role_name) or (args.role_name and not args.role_arn): out("You must use and --role-arn and --role-name together") parser and parser.print_help() return -1 # enable logging if args.verbose: from boto import set_stream_logger set_stream_logger('boto') config = load_config(args.config_file) aws = make_aws_credentials(config, args.role_arn, args.role_name) helper = EbsHelper(aws, app_name=get(config, 'app.app_name'), wait_time_secs=args.wait_time) # execute the command return command.execute(helper, config, args)
def run_ebs_deploy(command, args, parser=None): """ the main """ init_logging(args.use_logging) # make sure we have an archive or a directory if not args.config_file or not os.path.exists(args.config_file): out("Config file not found: "+args.config_file) parser and parser.print_help() return -1 # make sure that if we have a role to assume, that we also have a role name to display if (args.role_arn and not args.role_name) or (args.role_name and not args.role_arn): out("You must use and --role-arn and --role-name together") parser and parser.print_help() return -1 # enable logging if args.verbose: from boto import set_stream_logger set_stream_logger('boto') config = load_config(args.config_file) aws = make_aws_credentials(config, args.role_arn, args.role_name) helper = EbsHelper(aws, app_name=get(config, 'app.app_name'), wait_time_secs=args.wait_time) # execute the command return command.execute(helper, config, args)
def execute(helper, config, args): """ dump command dumps things """ settings = parse_option_settings(get(parse_env_config(config, args.environment), 'option_settings', [])) for setting in settings: out(str(setting))
def execute(helper, config, args): """ Lists solution stacks """ out("Available solution stacks") for stack in helper.list_available_solution_stacks(): out(" "+str(stack)) return 0
def execute(helper, config, args): """ Lists solution stacks """ out("Available solution stacks") for stack in helper.list_available_solution_stacks(): out(" " + str(stack)) return 0
def execute(helper, config, args): """ Lists environments """ versions = helper.get_versions() out("Deployed versions:") for version in versions: out(version)
def execute(helper, config, args): """ dump command dumps things """ env = parse_env_config(config, args.environment) option_settings = env.get('option_settings', {}) settings = parse_option_settings(option_settings) for setting in settings: out(str(setting))
def execute(helper, config, args): """ The init command """ # check to see if the application exists if not helper.application_exists(): helper.create_application(get(config, 'app.description')) else: out("Application "+get(config, 'app.app_name')+" exists") # create environments environment_names = [] environments_to_wait_for_green = [] for env_name, env_config in get(config, 'app.environments').items(): environment_names.append(env_name) env_config = parse_env_config(config, env_name) actual_env_name = helper.environment_name_for_cname(env_config.get('cname_prefix', None)) if not actual_env_name: option_settings = parse_option_settings(env_config.get('option_settings', {})) helper.create_environment(env_name, solution_stack_name=env_config.get('solution_stack_name'), cname_prefix=env_config.get('cname_prefix', None), description=env_config.get('description', None), option_settings=option_settings, tier_name=env_config.get('tier_name'), tier_type=env_config.get('tier_type'), tier_version=env_config.get('tier_version')) environments_to_wait_for_green.append(env_name) else: out("Environment "+env_name+" exists as "+actual_env_name) # get the environments environments_to_wait_for_term = [] if args.delete: environments = helper.get_environments() for env in environments: if env['EnvironmentName'] not in environment_names: if env['Status'] != 'Ready': out("Unable to delete "+env['EnvironmentName']+" because it's not in status Ready ("+env['Status']+")") else: out("Deleting environment: "+env['EnvironmentName']) helper.delete_environment(env['EnvironmentName']) environments_to_wait_for_term.append(env['EnvironmentName']) # wait if not args.dont_wait and len(environments_to_wait_for_green)>0: helper.wait_for_environments(environments_to_wait_for_green, status='Ready', include_deleted=False) if not args.dont_wait and len(environments_to_wait_for_term)>0: helper.wait_for_environments(environments_to_wait_for_term, status='Terminated', include_deleted=False) out("Application initialized") return 0
def execute(helper, config, args): """ Swaps old and new URLs. If old_environment was active, new_environment will become the active environment """ old_env_name = args.old_environment new_env_name = args.new_environment # swap C-Names out("Assuming that {} is the currently active environment...".format(old_env_name)) out("Swapping environment cnames: {} will become active, {} will become inactive.".format(new_env_name, old_env_name)) helper.swap_environment_cnames(old_env_name, new_env_name) helper.wait_for_environments([old_env_name, new_env_name], status='Ready', include_deleted=False)
def execute(helper, config, args): """ Swaps old and new URLs. If old_environment was active, new_environment will become the active environment """ old_env_name = args.old_environment new_env_name = args.new_environment # swap C-Names out("Assuming that {} is the currently active environment...".format( old_env_name)) out("Swapping environment cnames: {} will become active, {} will become inactive." .format(new_env_name, old_env_name)) helper.swap_environment_cnames(old_env_name, new_env_name) helper.wait_for_environments([old_env_name, new_env_name], status='Ready', include_deleted=False)
def execute(helper, config, args): """ Lists environments """ envs = config.get('app', {}).get('environments', []) out("Parsed environments:") for name, conf in list(envs.items()): out('\t'+name) envs = helper.get_environments() out("Deployed environments:") for env in envs: if env['Status'] != 'Terminated': out('\t'+str(env['EnvironmentName'])+' ('+str(env['Status'])+', '+str(env['CNAME'])+')')
def execute(helper, config, args): """ Deletes an environment """ env_config = parse_env_config(config, args.environment) environments_to_wait_for_term = [] environments = helper.get_environments() for env in environments: if env['EnvironmentName'] == args.environment: if env['Status'] != 'Ready': out("Unable to delete " + env['EnvironmentName'] + " because it's not in status Ready (" + env['Status'] + ")") else: out("Deleting environment: "+env['EnvironmentName']) helper.delete_environment(env['EnvironmentName']) environments_to_wait_for_term.append(env['EnvironmentName']) if not args.dont_wait: helper.wait_for_environments(environments_to_wait_for_term, status='Terminated', include_deleted=True) out("Environment deleted") return 0
def execute(helper, config, args): """ Deletes an environment """ env_config = parse_env_config(config, args.environment) environments_to_wait_for_term = [] environments = helper.get_environments() for env in environments: if env['EnvironmentName'] == args.environment: if env['Status'] != 'Ready': out("Unable to delete " + env['EnvironmentName'] + " because it's not in status Ready (" + env['Status'] + ")") else: out("Deleting environment: " + env['EnvironmentName']) helper.delete_environment(env['EnvironmentName']) environments_to_wait_for_term.append(env['EnvironmentName']) if not args.dont_wait: helper.wait_for_environments(environments_to_wait_for_term, status='Terminated', include_deleted=True) out("Environment deleted") return 0
def execute(helper, config, args): """ Lists environments """ envs = config.get('app', {}).get('environments', []) out("Parsed environments:") for name, conf in envs.items(): out('\t' + name) envs = helper.get_environments() out("Deployed environments:") for env in envs: if env['Status'] != 'Terminated': out('\t' + str(env['EnvironmentName']) + ' (' + str(env['Status']) + ', ' + str(env['CNAME']) + ')')
def make_aws_credentials(config, role_arn=None, role_name=None): if role_arn: try: sts_connection = STSConnection() assumedRoleObject = sts_connection.assume_role( role_arn=role_arn, role_session_name=role_name) except: out("Oops! something went wrong trying to assume the specified role" ) else: # create credentials for switching roles aws = AwsCredentials( assumedRoleObject.credentials.access_key, assumedRoleObject.credentials.secret_key, assumedRoleObject.credentials.session_token, get(config, 'aws.region', os.environ.get('AWS_DEFAULT_REGION')), get(config, 'aws.bucket', os.environ.get('AWS_BEANSTALK_BUCKET_NAME')), get(config, 'aws.bucket_path', os.environ.get('AWS_BEANSTALK_BUCKET_NAME_PATH'))) out("Using Role: " + role_name) else: # create credentials aws = AwsCredentials( get(config, 'aws.access_key', os.environ.get('AWS_ACCESS_KEY_ID')), get(config, 'aws.secret_key', os.environ.get('AWS_SECRET_ACCESS_KEY')), get(config, 'aws.secret_token', os.environ.get('AWS_SECRET_TOKEN')), get(config, 'aws.region', os.environ.get('AWS_DEFAULT_REGION')), get(config, 'aws.bucket', os.environ.get('AWS_BEANSTALK_BUCKET_NAME')), get(config, 'aws.bucket_path', os.environ.get('AWS_BEANSTALK_BUCKET_NAME_PATH'))) return aws
def execute(helper, config, args): """ Deploys to an environment """ version_label = args.version_label archive = args.archive # get the environment configuration env_config = parse_env_config(config, args.environment) option_settings = parse_option_settings(env_config.get('option_settings', {})) cname_prefix = env_config.get('cname_prefix', None) # no zdt for anything but web server tier_name = env_config.get('tier_name', 'WebServer') if tier_name != 'WebServer': raise Exception( "Only able to do zero downtime deployments for " "WebServer tiers, can't do them for %s" % (tier_name, )) # find an available environment name out("Determining new environment name...") new_env_name = None if not helper.environment_exists(args.environment, include_deleted=True): new_env_name = args.environment else: for i in xrange(10): temp_env_name = args.environment + '-' + str(i) if not helper.environment_exists(temp_env_name, include_deleted=True): new_env_name = temp_env_name break if new_env_name is None: raise Exception("Unable to determine new environment name") else: out("New environment name will be " + new_env_name) # find an available cname name new_env_cname = cname_prefix + "-" + uuid4().hex[:8] out("New environment cname will be " + new_env_cname) # find existing environment name old_env_name = helper.get_previous_environment_for_subdomain(cname_prefix) min_size = None max_size = None desired_capacity = None if old_env_name: min_size, max_size, desired_capacity = helper.get_env_sizing_metrics(old_env_name) out("Retrieved old cluster sizes from {}: MinSize - {}, MaxSize - {}, DesiredCapacity - {}".format( old_env_name, min_size, max_size, desired_capacity)) should_copy_scaling_sizes = args.copy_previous_size and desired_capacity and max_size and min_size if should_copy_scaling_sizes: # We want the new cluster to start up with `desired_capacity` instances, # so set its min_size to that value. Later, we will adjust. option_settings = override_scaling(option_settings, desired_capacity, max_size) out("Overriding new cluster sizes: MinSize - {}, MaxSize - {}".format( desired_capacity, max_size)) # upload or build an archive version_label = upload_application_archive( helper, env_config, archive=args.archive, directory=args.directory, version_label=version_label) # create the new environment helper.create_environment(new_env_name, solution_stack_name=env_config.get('solution_stack_name'), cname_prefix=new_env_cname, description=env_config.get('description', None), option_settings=option_settings, version_label=version_label, tier_name=tier_name, tier_type=env_config.get('tier_type'), tier_version=env_config.get('tier_version')) helper.wait_for_environments(new_env_name, status='Ready', health='Green', include_deleted=False) if old_env_name is None: raise Exception("Unable to find current environment with cname: " + cname_prefix) out("Current environment name is " + old_env_name) env_data = helper.environment_data(new_env_name) if args.check_command: if callable(args.check_command): out("Running check-command function") args.check_command(env_data) out("check-command passed") elif isinstance(args.check_command, basestring): command = shlex.split(args.check_command) + [new_env_cname] out("Running check-command {}".format(command)) rc = sh.Command(command[0])(command[1:], _iter=True) for line in rc: out(line.rstrip()) out("Exit Code: {}".format(rc.exit_code)) # we need to readjust the min_size of the new cluster, because it's currently set to the old cluster's # desired_capacity if should_copy_scaling_sizes and desired_capacity != min_size: helper.set_env_sizing_metrics(new_env_name, min_size, max_size) out("Resizing new cluster MinSize to {}".format(min_size)) helper.wait_for_environments(new_env_name, status='Ready', health='Green', include_deleted=False) # swap C-Names out("Swapping environment cnames") helper.swap_environment_cnames(old_env_name, new_env_name) helper.wait_for_environments([old_env_name, new_env_name], status='Ready', include_deleted=False) # delete the old environment if args.termination_delay: out("Termination delay specified, sleeping for {} seconds...".format(args.termination_delay)) time.sleep(args.termination_delay) out("Deleting old environment {}".format(old_env_name)) helper.delete_environment(old_env_name) # delete unused helper.delete_unused_versions(versions_to_keep=int(get(config, 'app.versions_to_keep', 10)))
def usage(): commands = get_command_names() out("usage: ebs-deploy command [options | help]") out("Where command is one of:") for cmd in commands: out(" " + cmd)
def execute(helper, config, args): """ Deploys to an environment """ version_label = args.version_label archive = args.archive # get the environment configuration env_config = parse_env_config(config, args.environment) option_settings = parse_option_settings(env_config.get('option_settings', {})) cname_prefix = env_config.get('cname_prefix', None) # no zdt for anything but web server tier_name = env_config.get('tier_name', 'WebServer') if tier_name != 'WebServer': raise Exception( "Only able to do zero downtime deployments for " "WebServer tiers, can't do them for %s" % (tier_name, )) # find existing environment name old_env_name = helper.environment_name_for_cname(cname_prefix) if old_env_name is None: raise Exception("Unable to find current environment with cname: " + cname_prefix) out("Current environment name is " + old_env_name) # find an available environment name out("Determining new environment name...") new_env_name = None if not helper.environment_exists(args.environment): new_env_name = args.environment else: for i in xrange(10): temp_env_name = args.environment + '-' + str(i) if not helper.environment_exists(temp_env_name): new_env_name = temp_env_name break if new_env_name is None: raise Exception("Unable to determine new environment name") out("New environment name will be " + new_env_name) # find an available cname name out("Determining new environment cname...") new_env_cname = None for i in xrange(10): temp_cname = cname_prefix + '-' + str(i) if not helper.environment_name_for_cname(temp_cname): new_env_cname = temp_cname break if new_env_cname is None: raise Exception("Unable to determine new environment cname") out("New environment cname will be " + new_env_cname) # upload or build an archive version_label = upload_application_archive( helper, env_config, archive=args.archive, directory=args.directory, version_label=version_label) # create the new environment helper.create_environment(new_env_name, solution_stack_name=env_config.get('solution_stack_name'), cname_prefix=new_env_cname, description=env_config.get('description', None), option_settings=option_settings, version_label=version_label, tier_name=tier_name, tier_type=env_config.get('tier_type'), tier_version=env_config.get('tier_version')) helper.wait_for_environments(new_env_name, status='Ready', health='Green', include_deleted=False) # swap C-Names out("Swapping environment cnames") helper.swap_environment_cnames(old_env_name, new_env_name) helper.wait_for_environments([old_env_name, new_env_name], status='Ready', include_deleted=False) # delete the old environment if args.termination_delay: out("Termination delay specified, sleeping for {} seconds...".format(args.termination_delay)) time.sleep(args.termination_delay) helper.delete_environment(old_env_name) # delete unused helper.delete_unused_versions(versions_to_keep=int(get(config, 'app.versions_to_keep', 10)))
def execute(helper, config, args): """ Deploys to an environment """ version_label = args.version_label archive = args.archive # get the environment configuration env_config = parse_env_config(config, args.environment) option_settings = parse_option_settings( env_config.get('option_settings', {})) cname_prefix = env_config.get('cname_prefix', None) # no zdt for anything but web server tier_name = env_config.get('tier_name', 'WebServer') if tier_name != 'WebServer': raise Exception("Only able to do zero downtime deployments for " "WebServer tiers, can't do them for %s" % (tier_name, )) # find existing environment name old_env_name = helper.environment_name_for_cname(cname_prefix) if old_env_name is None: raise Exception("Unable to find current environment with cname: " + cname_prefix) out("Current environment name is " + old_env_name) # find an available environment name out("Determining new environment name...") new_env_name = None if not helper.environment_exists(args.environment): new_env_name = args.environment else: for i in xrange(10): temp_env_name = args.environment + '-' + str(i) if not helper.environment_exists(temp_env_name): new_env_name = temp_env_name break if new_env_name is None: raise Exception("Unable to determine new environment name") out("New environment name will be " + new_env_name) # find an available cname name out("Determining new environment cname...") new_env_cname = None for i in xrange(10): temp_cname = cname_prefix + '-' + str(i) if not helper.environment_name_for_cname(temp_cname): new_env_cname = temp_cname break if new_env_cname is None: raise Exception("Unable to determine new environment cname") out("New environment cname will be " + new_env_cname) # upload or build an archive version_label = upload_application_archive(helper, env_config, archive=args.archive, directory=args.directory, version_label=version_label) # create the new environment helper.create_environment( new_env_name, solution_stack_name=env_config.get('solution_stack_name'), cname_prefix=new_env_cname, description=env_config.get('description', None), option_settings=option_settings, version_label=version_label, tier_name=tier_name, tier_type=env_config.get('tier_type'), tier_version=env_config.get('tier_version')) helper.wait_for_environments(new_env_name, status='Ready', health='Green', include_deleted=False) # swap C-Names out("Swapping environment cnames") helper.swap_environment_cnames(old_env_name, new_env_name) helper.wait_for_environments([old_env_name, new_env_name], status='Ready', include_deleted=False) # delete the old environment if args.termination_delay: out("Termination delay specified, sleeping for {} seconds...".format( args.termination_delay)) time.sleep(args.termination_delay) helper.delete_environment(old_env_name) # delete unused helper.delete_unused_versions( versions_to_keep=int(get(config, 'app.versions_to_keep', 10)))
def execute(helper, config, args): """ The init command """ # check to see if the application exists if not helper.application_exists(): helper.create_application(get(config, "app.description")) else: out("Application " + get(config, "app.app_name") + " exists") # create environments environment_names = [] environments_to_wait_for_green = [] for env_name, env_config in get(config, "app.environments").items(): environment_names.append(env_name) env_config = parse_env_config(config, env_name) if not helper.environment_exists(env_name): option_settings = parse_option_settings(env_config.get("option_settings", {})) helper.create_environment( env_name, solution_stack_name=env_config.get("solution_stack_name"), cname_prefix=env_config.get("cname_prefix", None), description=env_config.get("description", None), option_settings=option_settings, tier_name=env_config.get("tier_name"), tier_type=env_config.get("tier_type"), tier_version=env_config.get("tier_version"), version_label=args.version_label, ) environments_to_wait_for_green.append(env_name) else: out("Environment " + env_name) # get the environments environments_to_wait_for_term = [] if args.delete: environments = helper.get_environments() for env in environments: if env["EnvironmentName"] not in environment_names: if env["Status"] != "Ready": out( "Unable to delete " + env["EnvironmentName"] + " because it's not in status Ready (" + env["Status"] + ")" ) else: out("Deleting environment: " + env["EnvironmentName"]) helper.delete_environment(env["EnvironmentName"]) environments_to_wait_for_term.append(env["EnvironmentName"]) # wait if not args.dont_wait and len(environments_to_wait_for_green) > 0: helper.wait_for_environments(environments_to_wait_for_green, status="Ready", include_deleted=False) if not args.dont_wait and len(environments_to_wait_for_term) > 0: helper.wait_for_environments(environments_to_wait_for_term, status="Terminated", include_deleted=False) out("Application initialized") return 0
def usage(): commands = get_command_names() out("usage: ebs-deploy command [options | help]") out("Where command is one of:") for cmd in commands: out(" "+cmd)
def execute(helper, config, args): """ Deploys to an environment """ version_label = args.version_label archive = args.archive # get the environment configuration env_config = parse_env_config(config, args.environment) option_settings = parse_option_settings(env_config.get('option_settings', {})) cname_prefix = env_config.get('cname_prefix', None) # find existing environment name old_env_name = helper.environment_name_for_cname(cname_prefix) if old_env_name is None: raise Exception("Unable to find current environment with cname: "+cname_prefix) out("Current environment name is "+old_env_name) # find an available environment name out("Determining new environment name...") new_env_name = None if not helper.environment_exists(args.environment): new_env_name = args.environment else: for i in xrange(10): temp_env_name = args.environment+'-'+str(i) if not helper.environment_exists(temp_env_name): new_env_name = temp_env_name break if new_env_name is None: raise Exception("Unable to determine new environment name") out("New environment name will be "+new_env_name) # find an available cname name out("Determining new environment cname...") new_env_cname = None for i in xrange(10): temp_cname = cname_prefix+'-'+str(i) if not helper.environment_name_for_cname(temp_cname): new_env_cname = temp_cname break if new_env_cname is None: raise Exception("Unable to determine new environment cname") out("New environment cname will be "+new_env_cname) # upload or build an archive version_label = upload_application_archive( helper, env_config, archive=args.archive, directory=args.directory, version_label=version_label) # create the new environment helper.create_environment(new_env_name, solution_stack_name=env_config.get('solution_stack_name'), cname_prefix=new_env_cname, description=env_config.get('description', None), option_settings=option_settings, version_label=version_label) helper.wait_for_environments(new_env_name, status='Ready', health='Green', include_deleted=False) # swap C-Names out("Swapping environment cnames") helper.swap_environment_cnames(old_env_name, new_env_name) helper.wait_for_environments([old_env_name, new_env_name], status='Ready', include_deleted=False) # delete the old environmnet helper.delete_environment(old_env_name) # delete unused helper.delete_unused_versions(versions_to_keep=int( get(config, 'app.versions_to_keep', 10) ))